microsoft c v4

This commit is contained in:
davidly 2024-07-01 10:35:17 -07:00
parent d10efaa850
commit c2ce01a4e3
174 changed files with 10842 additions and 0 deletions

6
Microsoft C v4/ADAPT.BAT Normal file
View File

@ -0,0 +1,6 @@
CLS
TYPE S3.@@@
RESPOND MBC
IF ERRORLEVEL 77 MENU M %2 %3 %4
IF ERRORLEVEL 67 MENU C %2 %3 %4
IF ERRORLEVEL 66 MENU B %2 %3 %4

BIN
Microsoft C v4/BINMODE.OBJ Normal file

Binary file not shown.

20
Microsoft C v4/BRKCTL.INC Normal file
View File

@ -0,0 +1,20 @@
; brkctl command values
BR_ARGSEG= 1 ; specified segment
BR_NEWSEG= 2 ; new segment
BR_IMPSEG= 3 ; last or new segment
MAXSEG= 20 ; maximum brkctl segments
segrec struc ; defines brkctl segment offsets
sz dw ?
sg dw ?
segrec ends
heaprec struc ; defines heap descriptor offsets
bottom dw ?
roveroff dw ?
last dw ?
top dw ?
nextseg dw ?
heaprec ends

View File

@ -0,0 +1,8 @@
;-----------------------------------------------------------------------
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;--------------------------------------------------------------------------
?PLM= 0
?WIN= 0
memC equ 1 ; compact model

BIN
Microsoft C v4/C1.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/C2.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/C3.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/C3L.EXE Normal file

Binary file not shown.

91
Microsoft C v4/CHKSTK.ASM Normal file
View File

@ -0,0 +1,91 @@
title chkstk - C stack checking routine
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;
;--------------------------------------------------------------------------
include version.inc
.xlist
include cmacros.inc
include msdos.inc
.list
sBegin data
assumes ds,data
extrn _end:word ; stack bottom
if sizeC
globalCP _aaltstkovr,-1 ; alternate stack overflow
endif
public STKHQQ ; used by parasitic heap
STKHQQ dw dataoffset _end+STACKSLOP ; initial value
sEnd data
sBegin code
assumes ds,data
assumes cs,code
externNP _amsg_exit ; write error and die
;------------------------------------------------------------------------
;
; chkstk - check stack upon procedure entry
;
; Entry:
; ax = size of local frame
labelP <PUBLIC,_chkstk>
if sizeC
pop cx ; get return offset
pop dx ; get return segment
else
pop cx ; get return offset
endif
mov bx,sp
sub bx,ax ; new position
jc OMerr ; error - out of memory
cmp bx,[STKHQQ] ; SP - AX : STKHQQ (for heap/stack)
jb OMerr ; error - out of memory
mov sp,bx ; set new stack pointer
if sizeC
push dx ; push segment
push cx ; push offset
chkproc proc far
ret ; far return to dx:cx
chkproc endp
else
jmp cx ; return to cx
endif
OMerr:
if sizeC
mov ax,word ptr [_aaltstkovr]
inc ax
jnz altstkovr
endif
xor ax,ax
jmp _amsg_exit ; give stack overflow and die
if sizeC
altstkovr:
push dx ; user segment
push cx ; user offset
jmp [_aaltstkovr] ; Pascal/FORTRAN stack overflow
endif
sEnd code
end

114
Microsoft C v4/CHKSUM.ASM Normal file
View File

@ -0,0 +1,114 @@
title chksum -- _nullcheck routine for C
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;
;--------------------------------------------------------------------------
;
; Purpose
;
; This routine is used to check for assignment through a null pointer.
; Memory at DGROUP:0 is checked for destructive assignments. This
; routine is not particularly effective in compact and large models.
; A stub may be provoded for this routine without affecting the
; behavior of a correctly written C program.
;----------------------------------------------------------------------------
?DF= 1 ; this is special for c startup
include version.inc
.xlist
include cmacros.inc
.list
createSeg _TEXT, code, byte, public, CODE, <>
createSeg NULL, null, para, public, BEGDATA,DGROUP
createSeg _DATA, data, word, public, DATA, DGROUP
createSeg HDR, nhdr, byte, public, MSG, DGROUP
createSeg MSG, nmsg, byte, public, MSG, DGROUP
createSeg PAD, npad, byte, common, MSG, DGROUP
createSeg EPAD, nepad, byte, common, MSG, DGROUP
defGrp DGROUP ; define DGROUP
codeOFFSET equ offset _TEXT:
dataOFFSET equ offset DGROUP:
sBegin null
assumes ds,data
CHKSUM= 1Fh ; has to be correct or error
BIAS= 55h
chkpt db 8 dup(0) ; for null pointer assignment
db 'C Library - (C)Copyright Microsoft Corp 1986'
chkb db CHKSUM ; checksum byte
db 0 ; leaves al = 0
chkln= $ - chkpt ; length to checksum
sEnd null
sBegin nmsg
assumes ds,data
dw 1
db 13,10,'error 2001: Null pointer assignment',13,10,0
sEnd
externP _NMSG_WRITE ; pascal calling
sBegin code
assumes cs,code
assumes ds,data
; _nullcheck
;
; _chksum cumulatively xor's all the bytes from ds:0 through 1 past end
; of copyright string, finally xor'ing an arbitrary non-zero constant.
; This is used to check if a null pointer has been written to.
;
; This version can be called as many times as the user wants.
; The function returns zero if the checksum is OK.
cProc _nullcheck,<PUBLIC>,<>
cBegin nogen ; no arguments - so no frame
push si
xor si,si ; start at DS:0
mov cx,chkln
xor ah,ah
cld
chkloop: ; loop to 1 past end of copyrt. string
lodsb
xor ah,al ; accumulate xor total in AH
loop chkloop
xor ah,BIAS ; XOR out the initial BIAS
jz setzero
mov ax,1 ; Null pointer assignment
push ax
call _NMSG_WRITE ; write message out
; ax = 0 if the checksum is OK
setzero:
pop si
ret
cEnd nogen
sEnd code
end

248
Microsoft C v4/CIRCLE.C Normal file
View File

@ -0,0 +1,248 @@
#include <dos.h>
#include <conio.h>
#include <math.h>
#define SQUARE(root) ((root) * (root))
#define ABS(num) (((num) < 0) ? (-num) : (num))
#define PI 3.14159265
/* Function prototypes */
int init (int);
void dot ( int, int, int );
int isqrt ( int );
void circle ( int, int, int, int );
void palette ( int );
void background ( int );
/* Arrays for storing address information for all pixels */
unsigned yaddr[200];
unsigned xaddr[640];
char shift[640];
char point[640];
char far *scrn = (char far *)0xB8000000; /* Screen buffer */
int max_x, max_y, max_clr, shifter, back = 3, pal = 1;
/*
* Use variables rather than constants for the following
* values so we can change them in the debugger
*/
int aspect = 270, x_wid = 85, y_wid = 78;
main()
{
int i, x, y, mode = 4, tmode, p = 1, b = 8;
tmode = getmode();
init(mode);
background(b);
palette(p);
for (i = 0; i <= 90; ++i) { /* Draw circles */
x = x_wid * atan(sin(i / PI));
y = y_wid * atan(cos(i / PI));
circle((max_x / 2) + x,100 + y,i % 40,(i % max_clr) + 1);
}
for (i = 0; i <= 90; ++i) { /* Erase them */
x = x_wid * atan(sin(i / PI));
y = y_wid * atan(cos(i / PI));
circle((max_x / 2)+x,100+y,i % 40,0);
}
init(tmode); /* Restore original mode */
return(0);
}
int getmode()
{
union REGS inregs, outregs;
inregs.h.ah = 0x0F; /* Use BIOS call to get mode */
inregs.h.al = 0;
int86(0x10,&inregs,&outregs);
if (outregs.h.al == 7) {
puts("Can't run with monochrome adapter.\a");
exit(7);
}
else
return(outregs.h.al);
}
int init (num)
int num;
{
int indx = 0, indx2 = 0;
unsigned clr_wid, mask;
union REGS inregs, outregs;
if (num > 6) { /* Can't assign EGA modes */
/* (they could be added easily) */
puts("Invalid mode.\x07");
exit(0);
}
switch (num) {
case 4 : /* Set variables for each mode */
max_clr = 3;
max_x = 320;
max_y = 200;
shifter = 4;
clr_wid = 2;
break;
case 5 :
max_clr = 1;
max_x = 320;
max_y = 200;
shifter = 4;
clr_wid = 2;
break;
case 6 :
max_clr = 1;
max_x = 640;
max_y = 200;
shifter = 8;
clr_wid = 1;
break;
}
if (num > 3) { /* For graphics modes only, */
while (indx < max_y) { /* calculate all y offsets */
yaddr[indx] = 80 * indx2;
++indx;
yaddr[indx] = (80 * indx2) + 0x2000;
++indx;
++indx2;
}
/* Calculate all x offsets */
for (indx = 0; indx < max_x; ++indx) {
mask = 0x80 >> (clr_wid * (indx % shifter));
if (num != 6) { /* Medium resolution offsets */
mask |= (mask >> 1);
shift[indx] = 6 - (clr_wid * (indx % shifter));
}
else /* High resolution offsets */
shift[indx] = 7 - (indx % shifter);
point[indx] = ~mask;
xaddr[indx] = indx / shifter;
}
}
inregs.h.ah = 0; /* Use BIOS call to set mode */
inregs.h.al = num;
int86(0x10,&inregs,&outregs);
return(num);
}
/* Draw a dot */
void dot ( x, y, clr )
int x, y, clr;
{
unsigned total;
char tcolor;
clr = ABS(clr) & max_clr; /* Check color boundary */
total = xaddr[x] + yaddr[y]; /* Put in screen buffer */
scrn[total] = (clr << shift[x]) | (scrn[total] & point[x]);
}
int isqrt ( arg ) /* Calculate integer square root */
int arg; /* (real square root is too slow) */
{
int odd_int, old_arg, first_sqrt;
odd_int = 1; /* Initialize with 1 */
old_arg = arg; /* Save argument */
while (arg >= 0) { /* Find double approximate root */
arg = arg - odd_int;
odd_int = odd_int + 2;
}
first_sqrt = odd_int >> 1; /* Divide by two */
/* Return adjusted root */
if (SQUARE(first_sqrt) - first_sqrt + 1 > old_arg)
return(first_sqrt - 1);
else
return(first_sqrt);
}
void circle ( cx, cy, radius, clr )
int cx, cy, radius, clr;
{
int a, af, b, bf, target, r2, temp;
clr = ABS(clr) & max_clr; /* Check color boundary */
target = 0;
a = radius;
b = 0;
r2 = SQUARE(radius);
while (a >= b) { /* Calculate new point */
b = isqrt(r2 - SQUARE(a));
temp = target;
target = b;
b = temp;
while (b < target) { /* Plot point in each */
/* quadrant */
af = max_x * a / aspect;
bf = max_x * b / aspect;
dot(cx + af,cy + b,clr);
dot(cx + bf,cy + a,clr);
dot(cx - af,cy + b,clr);
dot(cx - bf,cy + a,clr);
dot(cx - af,cy - b,clr);
dot(cx - bf,cy - a,clr);
dot(cx + af,cy - b,clr);
dot(cx + bf,cy - a,clr);
b = b + 1;
}
a = a - 1;
}
}
void palette ( color )
int color;
{
union REGS inregs, outregs;
color &= 0x01;
inregs.h.ah = 0x0B; /* Call BIOS to set palette */
inregs.h.bh = 1;
inregs.h.bl = color;
int86(0x10,&inregs,&outregs);
}
void background ( color )
int color;
{
union REGS inregs, outregs;
color &= 0x0F;
inregs.h.ah = 0x0B; /* Call BIOS to set background */
inregs.h.bh = 0;
inregs.h.bl = color;
int86(0x10,&inregs,&outregs);
}

BIN
Microsoft C v4/CIRCLE.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/CIRCLE.R Normal file

Binary file not shown.

BIN
Microsoft C v4/CIRCLEB.BAT Normal file

Binary file not shown.

BIN
Microsoft C v4/CL.EXE Normal file

Binary file not shown.

895
Microsoft C v4/CMACROS.INC Normal file
View File

@ -0,0 +1,895 @@
comment $
cmacros - assembly macros for interfacing to HHLs
(C)Copyright Microsoft Corp. 1984,1985,1986
$
if1
outif MACRO name,defval,onmsg,offmsg
ifndef name
ifb <defval>
name=0
else
name=defval
endif
endif
if name
name=1
ifnb <onmsg>
%out ! onmsg
endif
else
ifnb <offmsg>
%out ! offmsg
endif
endif
endm
error MACRO msg
bug
%out E r r o r ----- msg
ENDM
%out cMacros Version 1.06
outif memS,0,<Small Model>
outif memM,0,<Medium Model>
outif memL,0,<Large Model>
outif memC,0,<Compact Model>
outif memH,0,<Huge Model>
memMOD= memS + memM + memL + memC + memH
if memMOD ne 1
if memMOD eq 0
memS= 1
outif memS,0,<Small Model>
else
error <Must have only 1 memory model selected>
endif
endif
sizeC= memM + memL + memH
sizeD= memL + memC + (memH*2)
outif ?DF,0,<No segments or groups will be defined>
outif ?WIN,1,<Windows Support>
outif ?PLM,1,<PLM calling convention>
endif
.XCREF
.XCREF ?N,?AX,?AH,?AL,?BX,?BH
.XCREF ?BL,?CX,?CH,?CL,?DX,?DH
.XCREF ?DL,?SI,?DI,?ES,?DS,?BP
.XCREF ?SP,?SS,?CS
.XCREF ?RSL,?CPD,?argl,?argc,?BA
.XCREF ?ACB,???,?PO
.XCREF ?PAS,?PC
.XCREF Uconcat,mPush,mPop
.XCREF ?RI,?pp,?pp1,?al1
.XCREF ?aD,?AP,?Atal,?pd,?dd,?dd1,?ex1
.XCREF ?pg,?pg1,?aloc,?cs1,?cs2
.XCREF ?lb1,?lblpu
.XCREF ?DF,?PLM,?WIN,?IA,?PU,?ADJ
.CREF
?RSL = 0
?CPD = 0
?ArgL = 0
?ArgC = 0
?BA = 0
?ACB = 0
??? = 0
?PO = 0
?PAS = 0
?PC = 0
?IA = 0
?PU = 0
?ADJ = 0
?lblpu = 0
?N = 0000000000000000B
?AX = 0000000000000011B
?AH = 0000000000000001B
?AL = 0000000000000010B
?BX = 0000000000001100B
?BH = 0000000000000100B
?BL = 0000000000001000B
?CX = 0000000000110000B
?CH = 0000000000010000B
?CL = 0000000000100000B
?DX = 0000000011000000B
?DH = 0000000001000000B
?DL = 0000000010000000B
?SI = 0000000100000000B
?DI = 0000001000000000B
?ES = 0000010000000000B
?DS = 0000100000000000B
?BP = 0001000000000000B
?SP = 0010000000000000B
?SS = 0100000000000000B
?CS = 1000000000000000B
uconcat macro n1,n2,o1,o2,p1,p2
n1&n2 o1&o2 p1&p2
endm
mpush macro rV
irp x,<ax,bx,cx,dx,si,di,es,ds,bp,sp,ss,cs>
if rV AND ?&&x
push x
endif
endm
endm
mpop macro rV
irp x,<cs,ss,sp,bp,ds,es,di,si,dx,cx,bx,ax>
if rV AND ?&&x
pop x
endif
endm
endm
SAVE macro rL
?RSL = 0
?RI ?RSL,<rL>
endm
smashes macro n,rL
.xcref
.xcref ?SM&n
.cref
?SM&n = 0
?RI ?SM&n,<rL>
endm
?RI macro n,rL
irp x,<rL>
ifdef ?&&x
n = n or ?&&x
endif
endm
endm
parmB macro nl
?pp <&nL>,<byte>,2,1
endm
parmW macro nl
?pp <&nL>,<word>,2,2
endm
parmD macro nl
ife ?PLM
irp x,<nL>
?pp <&&x>,<DWORD>,0,4
?pp <Off_&&x>,<WORD>,2,2
?pp <Seg_&&x>,<WORD>,2,2
endm
else
irp x,<nL>
?pp <Seg_&&x>,<WORD>,2,2
?pp <Off_&&x>,<WORD>,2,2
?pp <&&x>,<DWORD>,0,4
endm
endif
endm
parmQ macro nl
?pp <&nL>,<QWORD>,8,8
endm
parmT macro nl
?pp <&nL>,<TBYTE>,10,10
endm
if sizeC
parmCP macro nl
parmD <nl>
endm
else
parmCP macro nl
parmW <nl>
endm
endif
if sizeD
parmDP macro nl
parmD <nl>
endm
else
parmDP macro nl
parmW <nl>
endm
endif
?pp macro nL,t,l,s
if ?CPD
.xcref
ife ?PLM
irp x,<nL>
?pp1 x,<t>,%?PO,%?adj,%(?PO+?adj)
?PO = ?PO + l
.xcref ?T&&x
?T&&x = s
endm
else
irp x,<nL>
?PO = ?PO + l
?pp1 x,<t>,%?PO,%?adj,%(?PO+?adj)
.xcref ?T&&x
?T&&x = s
endm
endif
.cref
else
%out Parm(s) "&nl" declared outside proc def.
endif
endm
?pp1 macro n,t,o,a,b
ife ?PLM
n equ t ptr [bp+b]
else
n equ t ptr [bp+a+?PO-o]
endif
endm
localB macro nL
?aLoc <&nL>,<BYTE ptr>,1,1,0
endm
localW macro nL
?aLoc <&nL>,<WORD PTR>,2,2,1
endm
localD macro nL
irp x,<nL>
?aLoc <Seg_&&x>,<WORD PTR>,2,2,1
?aLoc <Off_&&x>,<WORD PTR>,2,2,1
?aLoc <&&x>,<DWORD PTR>,0,4,1
endm
endm
localQ macro nL
?aLoc <&nL>,<QWORD PTR>,8,8,1
endm
localT macro nL
?aLoc <&nL>,<TBYTE PTR>,10,10,1
endm
if sizeC
localCP macro nL
localD <nL>
endm
else
localCP macro nL
localW <nL>
endm
endif
if sizeD
localDP macro nL
localD <nL>
endm
else
localDP macro nL
localW <nL>
endm
endif
localV macro n,a
?aLoc <&n>,<BYTE PTR>,%(&a),0,1
endm
?aLoc macro nL,t,l,s,a
if ?CPD
.xcref
??? = ??? + l
if a
??? = ((??? + 1) AND 0FFFEH)
endif
irp x,<nL>
?aL1 x,<t>,%???
.xcref ?T&&x
?T&&x = s
endm
.cref
else
%out Locals "&nl" declared outside procedure def.
endif
endm
?aL1 macro n,t,o
if ?IA
n equ t [bp-?IA-o]
else
n equ t [bp-o]
endif
endm
globalB macro n,i,s
?aD <n>,1
?dd n,1,<BYTE>,<DB>,<i>,<s>
endm
globalW macro n,i,s
?aD <n>,2
?dd n,1,<WORD>,<DW>,<i>,<s>
endm
globalD macro n,i,s
?aD <n>,4
?dd n,1,<DWORD>,<DD>,<i>,<s>
endm
globalQ macro n,i,s
?aD <n>,8
?dd n,1,<QWORD>,<DQ>,<i>,<s>
endm
globalT macro n,i,s
?aD <n>,10
?dd n,1,<TBYTE>,<DT>,<i>,<s>
endm
if sizeC
globalCP macro n,i,s
globalD n,<i>,<s>
endm
else
globalCP macro n,i,s
globalW n,<i>,<s>
endm
endif
if sizeD
globalDP macro n,i,s
globalD n,<i>,<s>
endm
else
globalDP macro n,i,s
globalW n,<i>,<s>
endm
endif
staticB macro n,i,s
?aD <n>,1
?dd n,0,<BYTE>,<DB>,<i>,<s>
endm
staticW macro n,i,s
?aD <n>,2
?dd n,0,<WORD>,<DW>,<i>,<s>
endm
staticD macro n,i,s
?aD <n>,4
?dd n,0,<DWORD>,<DD>,<i>,<s>
endm
staticQ macro n,i,s
?aD <n>,8
?dd n,0,<QWORD>,<DQ>,<i>,<s>
endm
staticT macro n,i,s
?aD <n>,10
?dd n,0,<TBYTE>,<DT>,<i>,<s>
endm
if sizeC
staticCP macro n,i,s
staticD n,<i>,<s>
endm
else
staticCP macro n,i,s
staticW n,<i>,<s>
endm
endif
if sizeD
staticDP macro n,i,s
staticD n,<i>,<s>
endm
else
staticDP macro n,i,s
staticW n,<i>,<s>
endm
endif
?dd macro n,p,t,d,i,s
ife ?PLM
n label t
?dd1 _&n,p,<d>,<i>,<s>
else
?dd1 n,p,<d>,<i>,<s>
endif
endm
?dd1 macro n,p,d,i,s
if p
PUBLIC n
endif
ifb <s>
n d i
else
ifb <i>
n d s DUP (?)
else
n d s DUP (i)
endif
endif
endm
externB macro nL
?ex1 <&nL>,1,<BYTE>
endm
externW macro nL
?ex1 <&nL>,2,<WORD>
endm
externD macro nL
?ex1 <&nL>,4,<DWORD>
endm
externQ macro nL
?ex1 <&nL>,8,<QWORD>
endm
externT macro nL
?ex1 <&nL>,10,<TBYTE>
endm
externNP macro nL
?ex1 <&nL>,2,<NEAR>
endm
externFP macro nL
?ex1 <&nL>,4,<FAR>
endm
if sizeC
externP macro nL
?ex1 <&nL>,4,<FAR>
endm
else
externP macro nL
?ex1 <&nL>,2,<NEAR>
endm
endif
if sizeC
externCP macro nL
?ex1 <&nL>,4,<DWORD>
endm
else
externCP macro nL
?ex1 <&nL>,2,<WORD>
endm
endif
if sizeD
externDP macro nL
?ex1 <&nL>,4,<DWORD>
endm
else
externDP macro nL
?ex1 <&nL>,2,<WORD>
endm
endif
?ex1 macro nL,s,d
irp x,<nL>
.xcref
.xcref ?T&&x
.cref
?T&&x = s
ife ?PLM
extrn _&&x:&d
x equ _&&x
else
extrn x:&d
endif
endm
endm
labelB macro nL
?lb1 <&nL>,1,<BYTE>
endm
labelW macro nL
?lb1 <&nL>,2,<WORD>
endm
labelD macro nL
?lb1 <&nL>,4,<DWORD>
endm
labelQ macro nL
?lb1 <&nL>,8,<QWORD>
endm
labelT macro nL
?lb1 <&nL>,10,<TBYTE>
endm
labelNP macro nL
?lb1 <&nL>,2,<NEAR>
endm
labelFP macro nL
?lb1 <&nL>,4,<FAR>
endm
if sizeC
labelP macro nL
?lb1 <&nL>,4,<FAR>
endm
else
labelP macro nL
?lb1 <&nL>,2,<NEAR>
endm
endif
if sizeC
labelCP macro nL
?lb1 <&nL>,4,<DWORD>
endm
else
labelCP macro nL
?lb1 <&nL>,2,<WORD>
endm
endif
if sizeD
labelDP macro nL
?lb1 <&nL>,4,<DWORD>
endm
else
labelDP macro nL
?lb1 <&nL>,2,<WORD>
endm
endif
?lb1 macro nL,s,d
?lblpu = 0
irp x,<nL>
ifidn <x>,<PUBLIC>
?lblpu = 1
else
.xcref
.xcref ?T&&x
.cref
?T&&x = s
ife ?PLM
if ?lblpu
public _&&x
endif
_&&x label &d
x equ _&&x
else
if ?lblpu
public x
endif
x label &d
endif
endif
endm
endm
defB macro nL
?aD <&nL>,1
endm
defW macro nL
?aD <&nL>,2
endm
defD macro nL
?aD <&nL>,4
endm
defQ macro nL
?aD <&nL>,8
endm
defT macro nL
?aD <&nL>,10
endm
if sizeC
defCP macro nL
defD <nL>
endm
else
defCP macro nL
defW <nL>
endm
endif
if sizeD
defDP macro nL
defD <nL>
endm
else
defDP macro nL
defW <nL>
endm
endif
?aD macro nL,s
irp x,<nL>
.xcref
.xcref ?T&&x
.cref
?T&&x = s
endm
endm
regPtr macro n,S,O
.xcref
.xcref ?T&n,?SR&n,?OR&n
.cref
?T&n = 0FFFFH
?SR&n = 0
?RI ?SR&n,<&S>
?OR&n = 0
?RI ?OR&n,<&O>
endm
arg macro aL
irp x,<aL>
?argc = ?argc + 1
?Atal <x>,%?argc
endm
endm
?Atal macro n,i
.xcref
.xcref ?ALI&i
.cref
?ALI&i &macro
?AP n
&endm
endm
?AP macro n
?argl = ?argl + 2
ifdef ?T&n
ife ?T&n-1
push word ptr (n)
exitm
endif
ife ?T&n-2
push n
exitm
endif
ife ?T&n-4
push word ptr (n)+2
push word ptr (n)
?argl = ?argl + 2
exitm
endif
ife ?T&n-8
push word ptr (n)+6
push word ptr (n)+4
push word ptr (n)+2
push word ptr (n)
?argl = ?argl + 6
exitm
endif
ife ?T&n-0FFFFH
mpush %(?SR&n),1
mpush %(?OR&n),1
?argl = ?argl + 2
exitm
endif
ife ?T&n
push word ptr (n)
exitm
endif
endif
push n
endm
ife ?PLM
ccall macro n,a,sleaze
ifnb <a>
Arg <a>
endif
ifdef ?SM&n
?RSL = ?RSL AND ?SM&n
endif
mpush %?RSL
?argl = 0
?ACB = ?argc
rept ?argc
uconcat <?ALI>,%?ACB
uconcat <purge>,,<?ALI>,%?ACB
?ACB = ?ACB - 1
endm
ife ?PLM
ifb <sleaze>
call _&n
else
call n
endif
else
call n
endif
if ?argl
add sp,?argl
endif
mpop %?RSL
?RSL = 0
?argc = 0
?argl = 0
endm
else
ccall macro n,a
ifnb <a>
Arg <a>
endif
ifdef ?SM&n
?RSL = ?RSL AND ?SM&n
endif
mpush %?RSL
?argl = 0
?ACB = 1
rept ?argc
uconcat <?ALI>,%?ACB
uconcat <purge>,,<?ALI>,%?ACB
?ACB = ?ACB + 1
endm
ife ?PLM
call _&n
else
call n
endif
mpop %?RSL
?RSL = 0
?argc = 0
?argl = 0
endm
endif
cProc macro n,cl,s
?pd n,<cl>,<s>,4
endm
?pd macro n,c,a,i
if ?CPD
?UTPE
endif
?CPD = 1
??? = 0
?argc = 0
?BA = 0
?PO = 0
?PU = 0
?IA = 0
?adj = i
?PAS = 0
ifnb <a>
?RI ?PAS,<a>
endif
?PC = sizeC
irp x,<c>
ifidn <x>,<FAR>
?PC = 1
endif
ifidn <x>,<NEAR>
?PC = 0
endif
ifidn <x>,<PUBLIC>
?PU = 1
endif
endm
if ?PC
if ?WIN
?IA = 2
endif
?adj = ?adj + 2
endif
ife ?PLM
ife ?PC
n label near
else
n label far
endif
?pg <_&n>,%?PU,%?PC,%?PAS
else
?pg <n>,%?PU,%?PC,%?PAS
endif
endm
?pg macro n,p,c,a
.xcref
cBegin &macro g
.xcref
?pg1 <n>,c,a,%?PO
?CPD = 0
?argc = 0
?BA = 1
??? = (???+1) AND 0FFFEH
if p
PUBLIC n
endif
ife c
n proc NEAR
else
n proc FAR
endif
ifidn <g>,<nogen>
if ???+?PO+a
%out <cBegin - possible invalid use of nogen>
endif
else
if ?IA
mov ax,ds
nop
inc bp
push bp
mov bp,sp
push ds
mov ds,ax
else
push bp
mov bp,sp
endif
if ???
sub sp,???
endif
mPush a,1
endif
.cref
purge cBegin
&endm
?UTPE &macro
%out Unterminated Procedure Definition: "&n"
&endm
endm
?pg1 macro n,c,a,o
.xcref
cEnd &macro g
.xcref
?BA = 0
ifidn <g>,<nogen>
if o+a
%out <cEnd - possible invalid use of nogen>
endif
else
mPop a,1
if ?IA
sub bp,2
mov sp,bp
pop ds
pop bp
dec bp
else
mov sp,bp
pop bp
endif
ife ?PLM
ret
else
ret o
endif
endif
n endp
.cref
purge cEnd
&endm
.cref
endm
assumes macro s,g
local assumed
assumed = 0
ifidn <code>,<g>
assume s&:_TEXT
assumed = 1
endif
ifidn <CODE>,<g>
assume s&:_TEXT
assumed = 1
endif
ifidn <data>,<g>
assume s&:dgroup
assumed = 1
endif
ifidn <DATA>,<g>
assume s&:dgroup
assumed = 1
endif
ife assumed
assume s&:&g
endif
endm
createSeg macro n,ln,a,co,cl,grp
ifnb <grp>
addSeg grp,n
endif
ifnb <cl>
n segment a co '&cl'
else
n segment a co
endif
n ends
?cs1 <n>,<ln>
endm
if1
ASMpass=1
else
ASMpass=2
endif
addSeg macro grp,seg
ifndef def_&grp
def_&grp= 0
endif
if def_&grp ne ASMpass
add_&grp &macro s
in_&grp <seg>,s
&endm
in_&grp &macro sl,s
ifb <s>
grp group sl
else
add_&grp &macro ns
in_&grp <sl,s>,ns
&endm
endif
&endm
def_&grp=ASMpass
else
add_&grp seg
endif
endm
defGrp macro nam
addSeg nam
endm
?cs1 macro n,ln
begin&ln &macro
?cs2 <n>
n segment
&endm
endm
?cs2 macro n
sEnd &macro
n ends
&endm
endm
sBegin macro ln
begin&ln
endm
ife ?DF
createSeg _TEXT,code,byte,public,CODE
createSeg _DATA,data,word,public,DATA,DGROUP
defGrp DGROUP
codeOFFSET equ OFFSET _TEXT:
dataOFFSET equ OFFSET DGROUP:
endif
errnz macro x
if2
if x
errnz1 <x>,%(x)
endif
endif
endm
errnz1 macro x1,x2
= *ERRNZ* x1 = x2
endm
errn$ macro l,x
errnz <OFFSET $ - OFFSET l x>
ENDM

BIN
Microsoft C v4/CODEVIEW.DOC Normal file

Binary file not shown.

130
Microsoft C v4/COUNT.C Normal file
View File

@ -0,0 +1,130 @@
#include <stdio.h>
#include <io.h>
#include <ctype.h>
#include <string.h>
#define BUFFSIZE 512 /* Small buffer for debugging */
#define TRUE 1
#define FALSE 0
#define FACTOR 1.1 /* Vowels per syllable in typical file */
/* Conditional operator prevents divide by zero */
#define WPS (float)words / (sentences ? sentences : 1)
#define LPW (float)letters / (words ? words : 1)
#define SPW (vowels * FACTOR) / (words ? words : 1)
int bytes = 0, characters = 0, words = 0, lines = 0;
int letters = 0, vowels = 0, sentences = 0;
char buffer[BUFFSIZE];
main(argc,argv)
int argc;
char *argv[];
{
FILE *stream;
int namebuf[15];
char *name;
int numread;
char inword = FALSE;
/* Get a file if one was not specified as an argument */
if (argc > 1)
name = argv[1];
else {
printf("Enter file name: ");
name = gets(namebuf);
}
/* Open file in binary mode */
if ((stream = fopen(name,"rb")) == NULL)
return (1);
/* Read file buffers, passing bytes read and inword status */
while ((numread = fread(buffer,1,BUFFSIZE,stream)) != 0)
inword = countwords(inword,numread);
/* Calculate and print the results */
printf("\n\n\t\tFile statistics\n\n");
printf("\t\tBytes: %d \n",bytes);
printf("\t\tCharacters: %d \n",characters);
printf("\t\tLetters: %d \n",letters);
printf("\t\tVowels: %d \n",vowels);
printf("\t\tConsonants %d \n",letters - vowels);
printf("\t\tWords: %d \n",words);
printf("\t\tLines: %d \n",lines ? lines : 1);
printf("\t\tSentences: %d \n",sentences);
printf("\t\tWords per sentence: %-.1f \n",WPS);
printf("\t\tLetters per word: %-.1f \n",LPW);
printf("\t\tEstimated syllables per word: %-.1f \n",SPW);
return (0);
}
/*
* Analyze the chars in one buffer.
*
* Increment bytes. For each char, increment characters,
* lines, and/or words if appropriate. For each character,
* call analyze function. (A character is defined as a
* printable ASCII code.)
*/
countwords(inword,numread)
char inword;
int numread;
{
int count;
char code;
bytes += numread;
for (count = 0; count <= numread; ++count) {
code = buffer[count];
if (code == '\n')
++lines;
if (!inword) {
if (code > ' ') {
analyze(code,inword);
inword = TRUE;
++words;
++characters;
}
}
else {
if (code <= ' ')
inword = FALSE;
else {
++characters;
analyze(code,inword);
}
}
}
return(inword);
}
/*
* Analyze a character.
*
* Increment letters, vowels, and/or sentences
* if appropriate.
*/
analyze(code,inword)
char code;
char inword;
{
if (isalpha(code)) {
++letters;
if ((strchr("AEIOUaeiou",code)) || (strchr("Yy",code) && inword))
++vowels;
}
else {
if (strchr(".!?",code))
++sentences;
}
}

BIN
Microsoft C v4/COUNT.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/COUNT.R Normal file

Binary file not shown.

14
Microsoft C v4/COUNT.TXT Normal file
View File

@ -0,0 +1,14 @@
COUNT is a simple program for analyzing text files. It makes
certain reasonable assumptions that will be valid for most text files.
For example, it assumes that terminating punctuation (period, question
mark, or exclamation point) marks the end of a sentence. COUNT will
produce incorrect results on files that contain abbreviations, dot
codes, or other uses of terminating punctuation. The program uses a
constant for the number of vowels per syllable. This number is based
on analysis of several typical files. Finally, Y is assumed to be a
consonant at the start of a word, but a vowel within a word.
During the session you'll need to know that this file contains 796
bytes, 630 characters, 588 letters, 226 vowels, 127 words, 13 lines,
and 8 sentences.


BIN
Microsoft C v4/COUNTB.BAT Normal file

Binary file not shown.

269
Microsoft C v4/CRT0.ASM Normal file
View File

@ -0,0 +1,269 @@
title c - C start up routine
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;
;--------------------------------------------------------------------------
;
; How startup works in a few words -
;
; The startup and termination is performed by a few modules
;
; crt0.asm DOS 2.x/3.x specific init/term
; crt0msg.asm DOS 2.x/3.x error messages
; (winstart.asm) Windows specific init/term (not included)
;
; crt0dat.asm remainder of shared DOS 3.x init/term
;
; ************* IMPORTANT *****************************************
;
; If the user reassembles this module, he will need to link using the
; /DOSSEG switch or run the the DOSSEG.EXE program on crt0.obj, i.e.
;
; dosseg crt0.obj
;
; See the C documentation for more information about the /DOSSEG switch.
;
; All assembler modules must be assembled with the /mx switch, i.e.
;
; masm crt0/mx;
;
;--------------------------------------------------------------------------
?DF= 1 ; this is special for c startup
include version.inc
.xlist
include cmacros.inc
include msdos.inc
include brkctl.inc
.list
page
;===========================================================================
;
; Segment definitions
;
; The segment order is essentially the same as in XENIX.
; This module is edited after assembly to contain a dosseg comment
; record for the linker.
;
;===========================================================================
createSeg _TEXT, code, byte, public, CODE, <>
createSeg C_ETEXT,etext, byte, public, ENDCODE,<>
createSeg _DATA, data, word, public, DATA, DGROUP
createSeg STACK, stack, para, stack, STACK, DGROUP
defGrp DGROUP ; define DGROUP
codeOFFSET equ offset _TEXT:
dataOFFSET equ offset DGROUP:
page
public __acrtused ; trick to force in startup
__acrtused = 9876h ; funny value not easily matched in SYMDEB
extrn __acrtmsg:abs ; trick to pull in startup messages
sBegin stack
assumes ds,data
db 2048 dup (?) ; default stack size
sEnd
page
sBegin data
extrn _edata:byte ; end of data (start of bss)
extrn _end:byte ; end of bss (start of stack)
externW _psp ; psp:0 (paragraph #)
externW __argc
externDP __argv
externDP environ
; these are used by DOS C memory management (not used in Windows)
globalW _asizds,0 ; DS size (in bytes)
globalW _atopsp,0 ; top of stack (heap bottom)
labelW <PUBLIC,_abrktb> ; segment table for brkctl
dw ?
dw DGROUP
db (MAXSEG-1) * (size segrec) dup (?)
labelW <PUBLIC,_abrktbe>
globalW _abrkp,<dataoffset _abrktb>
sEnd
page
externP _cinit ; run-time initializers
externP _NMSG_TEXT ; pascal - find error message text
externP _NMSG_WRITE ; pascal - write error message to stdout
externP _setargv ; process command line arguments
externP _setenvp ; process environment
externP _nullcheck ; check for null assignment
externP main ; C main program
externP exit ; exit ( code )
if sizeC
extrn __exit:far ; _exit ( code) (cmacros name conflict)
else
extrn __exit:near
endif
sBegin code
assumes cs,code
assumes ds,nothing
labelNP <PUBLIC,_astart> ; start address of all "C" programs
; check MS-DOS version for 2.0 or later
callos VERSION
cmp al,2 ; check for version 2 or later
jae setup ; yes - continue with setup
mov ax,4
push ax
call _NMSG_TEXT ; find 'DOS 2.0 or later required'
xchg dx,ax
callos message
int 20h ; DOS 1.0 exit program
setup:
mov di,DGROUP
mov si,ds:[DOS_MAXPARA] ; get max. paragraph
sub si,di ; si = # para in data area
cmp si,1000h ; if more than 64K
jb setSP
mov si,1000H ; use full 64K (-16)
setSP:
cli ; turn off interrupts
mov ss,di ; SS = DGROUP
add sp,dataoffset _end-2 ; 2 for _asizds limit
sti ; turn interrupts back on
jnc SPok
xor ax,ax
push ax
call _NMSG_WRITE
mov ax,DOS_terminate shl 8 + 255
callos ; terminate process with 255
SPok:
assumes ss,data
and sp,not 1 ; make even (if not)
mov [_abrktb].sz,sp ; top DS free location
mov [_atopsp],sp ; save top of stack
mov ax,si ; si = # paragraphs
mov cl,4
shl ax,cl
dec ax
mov [_asizds],ax ; save DS size - 1 (in bytes)
; release extra space to DOS
add si,di ; si = DGROUP + # para in DGROUP
mov ds:[DOS_MAXPARA],si ; fix psp:2
mov bx,es ; bx = PSP base
sub bx,si ; bx = - # para used
neg bx
callos setmem ; set memory block size
mov [_psp],ds ; save psp:0
; zero data areas (_BSS and c_common)
push ss
pop es
assumes es,data
cld ; set direction flag (up)
mov di,dataOFFSET _edata ; beginning of bss area
mov cx,dataOFFSET _end ; end of bss area
sub cx,di
xor ax,ax
rep stosb ; zero bss
; C segmentation conventions set up here (DS=SS and CLD)
push ss ; set up initial DS=ES=SS, CLD
pop ds
assumes ds,data
; do necessary initialization BEFORE command line processing!
call _cinit ; shared by DOS and Windows
push ss
pop ds ; ds = DGROUP
assumes ds,data
; process command line and environment
call _setargv ; crack command line
call _setenvp ; crack environment
; call main and exit
xor bp,bp ; mark top stack frame for SYMDEB
if sizeD
push ds ; the environment is in DS
endif
push word ptr [environ]
if sizeD
push ds ; the arguments are in DS
endif
push word ptr [__argv]
push [__argc] ; move parameters onto stack
call main ; main ( argc , argv , envp )
; use whatever is in ax after returning here from the main program
push ax
call exit ; exit (AX)
; _exit will call terminators
page
;------------------------------------------------------------------------
;
; Fast exit fatal errors - die quick and return (255)
labelNP <PUBLIC,_cintDIV>
; _NMSG_WRITE will reestablish ds = DGROUP
mov ax,3 ; Integer divide by zero interrupt
labelNP <PUBLIC,_amsg_exit>
push ax
call _NMSG_WRITE ; write error message to stdout
mov ax,255
push ax
call __exit ; _exit(255)
sEnd
end _astart ; start address

468
Microsoft C v4/CRT0DAT.ASM Normal file
View File

@ -0,0 +1,468 @@
title crt0dat - DOS and Windows shared startup and termination
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;
;--------------------------------------------------------------------------
?DF = 1 ;; tell cmacros.inc we want to define our own segments
include version.inc
.xlist
include cmacros.inc
include msdos.inc
.list
createSeg _TEXT, code, byte, public, CODE, <>
createSeg CDATA, cdata, word, common, DATA, DGROUP
createSeg _DATA, data, word, public, DATA, DGROUP
createSeg XIB, xibseg, word, public, DATA, DGROUP
createSeg XI, xiseg, word, public, DATA, DGROUP ; init's
createSeg XIE, xieseg, word, public, DATA, DGROUP
createSeg XOB, xobseg, word, public, BSS, DGROUP
createSeg XO, xoseg, word, public, BSS, DGROUP ; onexit table
createSeg XOE, xoeseg, word, public, BSS, DGROUP
createSeg XPB, xpbseg, word, public, DATA, DGROUP
createSeg XP, xpseg, word, public, DATA, DGROUP ; preterm's
createSeg XPE, xpeseg, word, public, DATA, DGROUP
createSeg XCB, xcbseg, word, public, DATA, DGROUP
createSeg XC, xcseg, word, public, DATA, DGROUP ; term's
createSeg XCE, xceseg, word, public, DATA, DGROUP
defGrp DGROUP ;; define DGROUP
codeOFFSET equ offset _TEXT:
dataOFFSET equ offset DGROUP:
page
sBegin xibseg
xibegin label byte
sEnd xibseg
sBegin xieseg
xiend label byte
sEnd xieseg
sBegin xobseg
xontab label byte ; start of onexit table
sEnd xobseg
sBegin xoeseg
xonend label byte
sEnd xoeseg
sBegin xpbseg
xpbegin label byte ; end of onexit table
sEnd xpbseg
sBegin xpeseg
xpend label byte
sEnd xpeseg
sBegin xcbseg
xcbegin label byte
sEnd xcbseg
sBegin xceseg
xcend label byte
sEnd xceseg
sBegin cdata ; floating point setup segment
assumes ds,data
dw 0 ; force segment to be at least 0's
labelD <PUBLIC,_fpinit> ; public for signal
fpmath dd 1 dup (?) ; linking trick for fp
fpdata dd 1 dup (?)
fpsignal dd 1 dup (?) ; fp signal message
sEnd
sBegin data
assumes ds,data
; special C environment string
cfile db ';C_FILE_INFO'
cfileln = $-cfile
globalD _aintdiv,0 ; divide error interrupt vector save
globalQ _fac,0 ; floating accumulator
globalW errno,0 ; initial error code
globalW _umaskval,0 ; initial umask value
; ************* following must be in this order
globalW _pspadr,0 ; psp:0 (far * to PSP segment)
globalW _psp,0 ; psp:0 (paragraph #)
labelB <PUBLIC,_dosvermajor>
globalB _osmajor,0
labelB <PUBLIC,_dosverminor>
globalB _osminor,0
; ************* above must be in this order
labelW <PUBLIC,_oserr>
globalW _doserrno,0 ; initial DOS error code
labelB <PUBLIC,_osfile>
db 3 dup (FOPEN+FTEXT) ; stdin, stdout, stderr
db 2 dup (FOPEN) ; stdaux, stdprn
db _NFILE-5 dup (0) ; the other 15 handles
globalW __argc,0
globalDP __argv,0
globalDP environ,0 ; environment pointer
; signal related common data
globalW _child,0 ; flag used to handle signals from child process
; note - if any changes are made to this structure, corresponding changes
; are needed in both doexec.asm and signal.asm
entry struc
dftoff dw 0 ; default return address: offset
dftseg dw 0 ; default return address: segment
shfoff dw 0 ; signal-handling function: offset
shfseg dw 0 ; signal-handling function: segment
entry ends
public __csigtab
__csigtab entry <> ; table of just one entry for now
sEnd data
page
sBegin code
assumes cs,code
if sizeC
global proc far
endif
;-----------------------------------------------------------------------------
;
; _cinit () - C initialization
;
; This routine performs the shared DOS and Windows initialization.
; The following order of initialization must be preserved -
;
; 1. Save DOS version
; 2. Check for devices for file handles 0 - 4
; 3. Integer divide interrupt vector setup
; 4. Floating point initialization
; 5. Copy ;C_FILE_INFO into _osfile
; 6. General C initializor routines
externP _cintDIV
externP _nullcheck
cProc _cinit,<PUBLIC>,<>
cBegin nogen ; no local frame to set up
assumes ds,data
assumes ss,data
; 1. Save DOS version
callos VERSION
mov word ptr [_osmajor],ax ; set _osmajor and _osminor
; 2. Check for devices for file handles 0 - 4
mov bx,4
devloop:
mov ax,DOS_ioctl shl 8 + 0 ; issue ioctl(0) to get dev info
callos
jc notdev
test dl,80h ; is it a device ?
jz notdev ; no
or _osfile[bx],FDEV ; yes - set FDEV bit
notdev:
dec bx
jns devloop
; 3. Integer divide interrupt vector setup
mov ax,DOS_getvector shl 8 + 0
callos ; save divide error interrupt
mov word ptr [_aintdiv],bx
mov word ptr [_aintdiv+2],es
push cs
pop ds
assumes ds,nothing
mov ax,DOS_setvector shl 8 + 0
mov dx,codeOFFSET _cintDIV
callos ; set divide error interrupt
push ss
pop ds
assumes ds,data
; 4. Floating point initialization
mov cx,word ptr [fpmath+2]
jcxz nofloat_i
mov es,[_psp] ; psp segment
mov si,es:[DOS_ENVP] ; environment segment
lds ax,[fpdata] ; get task data area
assumes ds,nothing
mov dx,ds ; into dx:ax
xor bx,bx ; (si) = environment segment
call [fpmath] ; fpmath(0) - init (never fails)
lds ax,[fpsignal] ; get signal address
assumes ds,nothing
mov dx,ds
mov bx,3
call [fpmath] ; fpmath(3) - set signal address
push ss
pop ds
assumes ds,data
nofloat_i:
; 5. Copy ;C_FILE_INFO into _osfile
; fix up files inherited from child using ;C_FILE_INFO
mov es,[_psp] ; es = PSP
mov cx,word ptr es:[DOS_envp] ; es = user's environment
jcxz nocfi ; no environment !!!
mov es,cx
xor di,di ; start at 0
cfilp:
cmp byte ptr es:[di],0 ; check for end of environment
je nocfi ; yes - not found
mov cx,cfileln
mov si,dataOFFSET cfile
repe cmpsb ; compare for ';C_FILE_INFO'
je gotcfi ; yes - now do something with it
mov cx,07FFFh ; environment max = 32K
xor ax,ax
repne scasb ; search for end of current string
jne nocfi ; no 00 !!! - assume end of env.
jmp cfilp ; keep searching
; found ;C_FILE_INFO and transfer info into _osfile
gotcfi:
push es
push ds
pop es ; es = DGROUP
pop ds ; ds = env. segment
assumes ds,nothing
assumes es,data
mov si,di ; si = startup of _osfile info
mov di,dataOFFSET _osfile ; di = _osfile block
lodsb ; must be less than 20
cbw
xchg cx,ax ; cx = number of entries
osflp:
lodsb ; get next byte
inc al
jz saveit ; was FF - save as 00
dec ax ; restore al
saveit:
stosb
loop osflp ; transfer next character
nocfi:
; 6. General C initializor routines
push ss
pop ds ; ds = DGROUP
mov si,dataOFFSET xibegin
mov di,dataOFFSET xiend
call initterm ; call the initializors
ret
cEnd nogen
page
;-----------------------------------------------------------------------------
;
; C termination
;
; The termination sequence is more complicated due to the multiple
; entry points - exit(code) and _exit(code). The _exit() routine
; is a quick exit routine that does not do certain C exit functions
; like stdio buffer flushing and onexit processing.
;
; exit (status):
;
; 1. call runtime preterminators
;
; _exit (status):
;
; 2. perform C terminators
; 3. perform _nullcheck() for null pointer assignment
; 4. close all open files
; 5. terminate floating point
; 6. reset divide by zero interrupt vector
; 7. terminate with return code to DOS
public _exit
_exit:
cProc dummy1,<>,<>
parmw status
cBegin
assumes ds,data
assumes ss,data
; 1. call runtime preterminators
; - onexit processing
; - flushall
; - rmtmp
mov si,dataOFFSET xontab ; beginning of onexit table
mov di,dataOFFSET xonend ; end of onexit table
call initterm
mov si,dataOFFSET xpbegin ; beginning of pre-terminators
mov di,dataOFFSET xpend ; end of pre-terminators
call initterm
jmp short exiting ; jump into _exit
cend nogen
public __exit
__exit:
cProc dummy2,<>,<>
parmw status
cBegin
assumes ds,data
assumes ss,data
exiting:
; 2. perform C terminators
mov si,dataOFFSET xcbegin
mov di,dataOFFSET xcend
call initterm
; 3. perform _nullcheck() for null pointer assignment
call _nullcheck ; perform null check (ignore return)
; 4. close all files
mov cx,_NFILE
xor bx,bx
closeloop:
test _osfile[bx],FOPEN
jz notopen
callos close
notopen:
inc bx
loop closeloop
; 5. terminate floating point
; 6. reset divide by zero interrupt vector
call _ctermsub ; fast cleanup
; 7. return to the DOS
mov ax,status ; get return value
callos terminate ; exit with al = return code
cEnd nogen
if sizeC
global endp
endif
labelNP <PUBLIC,_ctermsub>
; 5. terminate floating point
mov cx,word ptr [fpmath+2] ; test for floating point
jcxz nofloat_t ; no
mov bx,2 ; yes - cleanup
call [fpmath]
nofloat_t:
; 6. reset divide by zero interrupt vector
push ds
lds dx,[_aintdiv] ; ds:dx = restore vector
mov ax,DOS_setvector shl 8 + 0
callos ; set divide error interrupt
pop ds
ret
page
;-----------------------------------------------------------------------------
;
; initterm - do all the initializors and terminators
;
; The initializors and terminators may be written in C
; so we are assuming C conventions (DS=SS, CLD, SI and DI preserved)
; We go through them in reverse order for onexit.
;
; si = start of procedure list
; di = end of procedure list
initterm:
cmp si,di ; are we done?
jae itdone ; yes - no more
if sizeC
sub di,4
mov ax,[di]
or ax,[di+2]
jz initterm ; skip null procedures
call dword ptr [di]
else
dec di
dec di
mov cx,[di]
jcxz initterm ; skip null procedures
call cx
endif
jmp initterm ; keep looping
itdone:
ret
sEnd
end

49
Microsoft C v4/CRT0FP.ASM Normal file
View File

@ -0,0 +1,49 @@
title crt0fp - floating point not loaded trap
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1986
;
;--------------------------------------------------------------------------
?DF= 1 ; this is special for c startup
include version.inc
.xlist
include cmacros.inc
.list
createSeg _TEXT, code, byte, public, CODE, <>
createSeg HDR, nhdr, byte, public, MSG, DGROUP
createSeg MSG, nmsg, byte, public, MSG, DGROUP
createSeg PAD, npad, byte, common, MSG, DGROUP
createSeg EPAD, nepad, byte, common, MSG, DGROUP
defGrp DGROUP ; define DGROUP
; Messages used by _fptrap
sBegin nmsg
assumes ds,data
dw 2
db 13,10,'error 2002: Floating point not loaded',13,10,0
sEnd
sBegin code
assumes cs,code
externNP _amsg_exit
labelNP <PUBLIC,_fptrap>
mov ax,2 ; issue floating point not loaded
jmp _amsg_exit ; and die
sEnd
end

View File

@ -0,0 +1,48 @@
title crt0msg - startup messages
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1986
;
;--------------------------------------------------------------------------
?DF= 1 ; this is special for c startup
include version.inc
.xlist
include cmacros.inc
.list
createSeg HDR, nhdr, byte, public, MSG, DGROUP
createSeg MSG, nmsg, byte, public, MSG, DGROUP
createSeg PAD, npad, byte, common, MSG, DGROUP
createSeg EPAD, nepad, byte, common, MSG, DGROUP
defGrp DGROUP ; define DGROUP
public __acrtmsg
__acrtmsg= 9876h
; Messages used by crt0.asm
sBegin nmsg
assumes ds,data
dw 0
db 13,10,'error 2000: Stack overflow',13,10,0
dw 3
db 13,10,'error 2003: Integer divide by 0',13,10,0
dw 4
db 13,10,'error 2004: DOS 2.0 or later required',13,10,'$',0
dw 9
db 13,10,'error 2009: Not enough space for environment',13,10,0
sEnd
end

BIN
Microsoft C v4/CSETARGV.OBJ Normal file

Binary file not shown.

BIN
Microsoft C v4/CV.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/CV.HLP Normal file

Binary file not shown.

BIN
Microsoft C v4/CVARSTCK.OBJ Normal file

Binary file not shown.

BIN
Microsoft C v4/CVR.EXE Normal file

Binary file not shown.

1
Microsoft C v4/DEMO.BAT Normal file
View File

@ -0,0 +1 @@
sample

24
Microsoft C v4/DEMO.C Normal file
View File

@ -0,0 +1,24 @@
main(argc, argv, envp)
int argc;
char **argv;
char **envp;
{
register char **p;
/* print out the argument list for this program */
for (p = argv; argc > 0; argc--,p++) {
printf("%s\n", *p);
}
/* print out the current environment settings. Note that
* the environment table is terminated by a NULL entry
*/
for (p = envp; *p; p++) {
printf("%s\n", *p);
}
exit(0);
}

BIN
Microsoft C v4/DOSSEG.EXE Normal file

Binary file not shown.

35
Microsoft C v4/E.C Normal file
View File

@ -0,0 +1,35 @@
#include <stdio.h>
#ifndef MWC
#include <string.h>
#include <stdlib.h>
#endif
#define DIGITS_TO_FIND 200 /*9009*/
int cdecl 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;
}

396
Microsoft C v4/EMOEM.ASM Normal file
View File

@ -0,0 +1,396 @@
title emoem.asm - OEM dependent code for 8087
;--------------------------------------------------------------------
;
; OEM customization routines for 8087/80287 coprocessor
;
; Copyright (C) 1985 by Microsoft Corporation
;
; This module is designed to work with the following
; Microsoft language releases:
;
; Microsoft C 3.00 and later
; Microsoft FORTRAN 77 3.30 and later
; Microsoft Pascal 3.30 and later
;
; This module supercedes the OEMR7.ASM module used in earlier
; versions of Microsoft FORTRAN 77 and Pascal. The documentation
; provided with the FORTRAN and Pascal releases refers to the old
; OEMR7.ASM module and is only slightly relevant to this module.
;
; The following routines need to be written to properly handle the
; 8087/808287 installation, termination, and interrupt handler
;
; __FPINSTALL87 install 8087 interrupt handler
; __FPTERMINATE87 deinstall 8087 interrupt handler
; __fpintreset reset OEM hardware if an 8087 interrupt
;
; This module should be assembled with the Microsoft Macro Assembler
; as follows:
;
; masm emoem/r;
;
; Most hardware handles the 8087/80287 in one of the following
; three ways -
;
; 1. NMI - IBM PC and clones all handle the interrupt this way
; 2. single 8259
; 3. master/slave 8259
;
; Manufacturer specific initialization is supported for these 3
; machine configurations either by modifying this file and replacing
; the existing EMOEM module in the math libraries or by patching
; the .LIB and .EXE files directly.
;
; Microsoft FORTRAN and Pascal Release 3.30
;
; LIB MATH-+EMOEM;
; LIB 8087-+EMOEM;
;
; Microsoft C Release 3.00
;
; LIB 87-+EMOEM;
; LIB EM-+EMOEM;
;
;--------------------------------------------------------------------
ifndef PCDOS ; if PCDOS is nonzero, then the 8087
PCDOS= 0 ; handler may only work on IBM PCs
endif ; and clones
;---------------------------------------------------------------------
; Assembly constants.
;---------------------------------------------------------------------
; MS-DOS OS calls
OPSYS EQU 21H
SETVECOP EQU 25H
GETVECOP EQU 35H
DOSVERSION EQU 30h
CTLCVEC EQU 23h
EMULATOR_DATA segment public 'FAR_DATA'
assume ds:EMULATOR_DATA
; User may place data here if DS is setup properly.
; Recommend keeping the data items in the code segment.
EMULATOR_DATA ends
EMULATOR_TEXT segment public 'CODE'
assume cs:EMULATOR_TEXT
public __FPINSTALL87 ; DO NOT CHANGE THE CASE ON
public __FPTERMINATE87 ; THESE PUBLIC DEFINITIONS
extrn __FPEXCEPTION87:near ; DO NOT CHANGE CASE
;***********************************************************************
;
; Hardware dependent parameters in the 8087 exception handler.
;
; For machines using 2 8259's to handle the 8087 exception, be sure that
; the slave 8259 is the 1st below and the master is the 2nd.
;
; The last 4 fields allow you to enable extra interrupt lines into the
; 8259s. It should only be necessary to use these fields if the 8087
; interrupt is being masked out by the 8259 PIC.
;
; The ocw2's (EOI commands) can be either non-specific (20H) or
; specific (6xH where x=0 to 7). If you do not know which interrupt
; request line on the 8259 the 8087 exception uses, then you should issue
; the non-specific EOI (20H). Interrupts are off at this point in the
; interrupt handler so a higher priority interrupt will not be seen.
oeminfo struc
oemnum db 0 ; MS-DOS OEM number (IBM is 00h)
intnum db 2 ; IBM PC clone interrupt number
share db 0 ; nonzero if original vector should be taken
a8259 dw 0 ; 1st 8259 (A0=0) port #
aocw2 db 0 ; 1st 8259 (A0=0) EOI command
b8259 dw 0 ; 2nd 8259 (A0=0) port #
bocw2 db 0 ; 2nd 8259 (A0=0) EOI command
a8259m dw 0 ; 1st 8259 (A0=1) port #
aocw1m db 0 ; 1st 8259 (A0=1) value to mask against IMR
b8259m dw 0 ; 2nd 8259 (A0=1) port #
bocw1m db 0 ; 2nd 8259 (A0=1) value to mask against IMR
oeminfo ends
if PCDOS eq 0
;-----------------------------------------------------------------------
; OEM specific 8087 information
;
; If the OEM number returned from the DOS version call matches,
; this information is automatically moved into the oem struc below.
oemtab label byte ; Table of OEM specific values for 8087
; OEM#, int, shr, a59, acw2,b59, bcw2,a59m,acw1,b59m,bcw1
;TI Professional Computer
TI_prof oeminfo <028h,047h,000h,018h,020h,0000,0000,0000,0000,0000,0000>
db 0 ; end of table
endif ;PCDOS eq 0
; Unique pattern that can be searched for with the debugger so that
; .LIB or .EXE files can be patched with the correct values.
; If new values are patched into .LIB or .EXE files, care must be
; taken in insure the values are correct. In particular, words and
; bytes are intermixed in oeminfo structure. Remember words are
; stored low byte - high byte in memory on the 8086 family.
db '<<8087>>' ; older versions used '<8087>'
; Some manufacturer's machines can not be differentiated by the
; OEM number returned by the MS-DOS version check system call.
; For these machines it is necessary to replace the line below
oem oeminfo <> ; default values for IBM PC & clones
; with one of the following. If your machine has an 8087 capability
; and it is not in the list below, you should contact your hardware
; manufacturer for the necessary information.
;ACT Apricot
;oem oeminfo <000h,055h,000h,000h,020h,000h,000h,000h,000h,000h,000h>
;NEC APC3 and PC-9801 (OEM number returned by NEC MS-DOS's is different)
;oem oeminfo <000h,016h,000h,008h,066h,000h,067h,00Ah,0BFh,002h,07Fh>
;---------------------------------------------------------------------
statwd dw 0 ; Temporary for status word
oldvec dd 0 ; Old value in 8087 exception interrupt vector
ctlc dd 0 ; Old value of Control-C vector (INT 23h)
aoldIMR db 0 ; 1st 8259 original IMR value
boldIMR db 0 ; 2nd 8259 original IMR value
page
;---------------------------------------------------------------------
;
; Perform OEM specific initialization of the 8087.
;
__FPINSTALL87:
push ds ; DS = EMULATOR_DATA
push cs ; Move current CS to DS for opsys calls.
pop ds
assume ds:EMULATOR_TEXT
if PCDOS eq 0
push ds
pop es ; CS = DS = ES
mov ah,DOSVERSION
int OPSYS ; bh = OEM#
cld
mov si,offset oemtab ; start of OEM 8087 info table
mov di,offset oem+1
mov cx,(size oem)-1
OEMloop:
lodsb ; get OEM#
or al,al
jz OEMdone ; OEM# = 0 - did not find OEM
cmp al,bh ; correct OEM#
je OEMfound
add si,cx ; skip over OEM information
jmp OEMloop
OEMfound:
rep movsb ; move the information
OEMdone: ; done with automatic customization
endif
; Save old interrupt vector.
; Ask operating system for vector.
mov al,[oem].intnum ; Interrupt vector number.
mov ah,GETVECOP ; Operating system call interrupt.
int OPSYS ; Call operating system.
mov word ptr [oldvec],bx ; Squirrel away old vector.
mov word ptr [oldvec+2],es
; Have operating system install interrupt vectors.
mov dx,offset __fpinterrupt87 ; Load DX with 8087 interrupt handler.
mov ah,SETVECOP ; Set interrupt vector code in AH.
mov al,[oem].intnum ; Set vector number.
int OPSYS ; Install vector.
; Intercept Control-C vector to guarentee cleanup
mov ax,GETVECOP shl 8 + CTLCVEC
int OPSYS
mov word ptr [ctlc],bx
mov word ptr [ctlc+2],es
mov dx,offset ctlcexit
mov ax,SETVECOP shl 8 + CTLCVEC
int OPSYS
; set up 8259's so that 8087 interrupts are enabled
mov ah,[oem].aocw1m ; get mask for 1st 8259 IMR
or ah,ah ; if 0, don't need to do this
jz installdone ; and only 1 8259
mov dx,[oem].a8259m ; get port number for 1st 8259 (A0=1)
in al,dx ; read old IMR value
mov [aoldIMR],al ; save it to restore at termination
and al,ah ; mask to enable interrupt
jmp short $+2 ; for 286's
out dx,al ; write out new mask value
mov ah,[oem].bocw1m ; get mask for 2nd 8259 IMR
or ah,ah ; if 0, don't need to do this
jz installdone ;
mov dx,[oem].b8259m ; get port number for 2nd 8259 (A0=1)
in al,dx ; read old IMR value
mov [boldIMR],al ; save it to restore at termination
and al,ah ; mask to enable interrupt
jmp short $+2 ; for 286's
out dx,al ; write out new mask value
installdone:
assume ds:EMULATOR_DATA
pop ds
ret
page
; __FPTERMINATE87
;
; This routine should do the OEM 8087 cleanup. This routine is called
; before the program exits.
;
; DS = EMULATOR_DATA
__FPTERMINATE87:
push ds
push ax
push dx
mov ah,SETVECOP
mov al,[oem].intnum
lds dx,[oldvec]
int OPSYS
; reset 8259 IMR's to original state
push cs
pop ds ; DS = CS
assume ds:EMULATOR_TEXT
cmp [oem].aocw1m,0 ; did we have to change 1st 8259 IMR
je term2nd8259 ; no - check 2nd 8259
mov al,[aoldIMR] ; get old IMR
mov dx,[oem].a8259m ; get 1st 8259 (A0=1) port #
out dx,al ; restore IMR
term2nd8259:
cmp [oem].bocw1m,0 ; did we have to change 2nd 8259 IMR
je terminatedone ; no
mov al,[boldIMR] ; get old IMR
mov dx,[oem].b8259m ; get 2nd 8259 (A0=1) port #
out dx,al ; restore IMR
terminatedone:
pop dx
pop ax
pop ds
assume ds:EMULATOR_DATA
ret
; Forced cleanup of 8087 exception handling on Control-C
ctlcexit:
push ax
push dx
push ds
call __FPTERMINATE87 ; forced cleanup of exception handler
lds dx,[ctlc] ; load old control C vector
mov ax,SETVECOP shl 8 + CTLCVEC
int OPSYS
pop ds
pop dx
pop ax
jmp [ctlc] ; go through old vector
page
; __fpinterrupt87
;
; This is the 8087 exception interrupt routine.
;
; All OEM specific interrupt and harware handling should be done in
; __fpintreset because __FPEXCEPTION87 (the OEM independent 8087
; exception handler) may not return. __FPEXCEPTION87 also turns
; interrupts back on.
;
PENDINGBIT= 80h ; Bit in status word for interrupt pending
__fpinterrupt87:
assume ds:nothing
nop
fnstsw [statwd] ; Store out exceptions
push ax ; waste time
pop ax
jmp short $+2
test byte ptr [statwd],PENDINGBIT ; Test for 8087 interrupt
jz not87int ; Not an 8087 interrupt.
call __fpintreset ; OEM interrupt reset routine
call __FPEXCEPTION87 ; 8087 error handling - may not return
; this routine turns interrupts back on
cmp [oem].share,0 ; Should we execute the old interrupt routine?
jz done8087 ; if not then return
; If you fall through here to do further hardware resetting, things
; may not always work because __FPEXCEPTION87 does not always return
; This only happens when the 8087 handler gets an exception that is
; a fatal error in the language runtimes. I.e., divide by zero
; is a fatal error in all the languages, unless the control word has
; set to mask out divide by zero errors.
not87int:
jmp [oldvec] ; We should never return from here.
done8087:
iret
__fpintreset:
push ax
push dx
mov al,[oem].aocw2 ; Load up EOI instruction.
or al,al ; Is there at least one 8259 to be reset?
jz Reset8259ret ; no
mov dx,[oem].a8259
out dx,al ; Reset (master) 8259 interrupt controller.
mov al,[oem].bocw2 ; Load up EOI instruction.
or al,al ; Is there a slave 8259 to be reset?
jz Reset8259ret
mov dx,[oem].b8259
out dx,al ; Reset slave 8259 interrupt controller.
Reset8259ret:
pop dx
pop ax
ret
EMULATOR_TEXT ends
end

View File

@ -0,0 +1,48 @@
title execmsg - exec messages
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1986
;
;--------------------------------------------------------------------------
?DF= 1 ; this is special to define segments
include version.inc
.xlist
include cmacros.inc
.list
createSeg HDR, nhdr, byte, public, MSG, DGROUP
createSeg MSG, nmsg, byte, public, MSG, DGROUP
createSeg PAD, npad, byte, common, MSG, DGROUP
createSeg EPAD, nepad, byte, common, MSG, DGROUP
defGrp DGROUP ; define DGROUP
public __execmsg
__execmsg= 9876h
; Messages used by doexec.asm
sBegin nmsg
assumes ds,data
; WARNING - doexec.asm expects these three messages to be together
; these messages must always have $ on the end
dw 5
db 13,10,'error 2005: Not enough memory on exec',13,10,'$',0
dw 6
db 13,10,'error 2006: Bad format on exec',13,10,'$',0
dw 7
db 13,10,'error 2007: Bad environment on exec',13,10,'$',0
sEnd
end

BIN
Microsoft C v4/EXEMOD.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/EXEPACK.EXE Normal file

Binary file not shown.

View File

@ -0,0 +1,8 @@
;-----------------------------------------------------------------------
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;--------------------------------------------------------------------------
?PLM= 0
?WIN= 0
memL equ 1 ; large model

BIN
Microsoft C v4/LIB.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/LINK.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/LSETARGV.OBJ Normal file

Binary file not shown.

BIN
Microsoft C v4/LVARSTCK.OBJ Normal file

Binary file not shown.

View File

@ -0,0 +1,8 @@
;-----------------------------------------------------------------------
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;--------------------------------------------------------------------------
?PLM= 0
?WIN= 0
memM equ 1 ; medium model

BIN
Microsoft C v4/MAKE.EXE Normal file

Binary file not shown.

92
Microsoft C v4/MAKEFILE Normal file
View File

@ -0,0 +1,92 @@
#############################################################
#
# (C)Copyright Microsoft Corporation, 1986
#
# makefile for building c runtime startup objects
# and linking null c program
#
# This makefile is invoked by startup.bat. See
# startup.bat for usage information.
#############################################################
MODEL=S
SRC=..
INC=..
CINC=..
CFLAGS=-A$(MODEL) -I$(INC) -Os -Gs -c
CL=cl $(CFLAGS)
ASMFLAGS= -Mx
ASM=masm $(ASMFLAGS)
CMACROS=$(INC)\$(MODEL)\version.inc $(INC)\cmacros.inc
# startup modules
crt0.obj: $(SRC)\crt0.asm $(CMACROS) $(INC)\msdos.inc $(INC)\brkctl.inc
$(ASM) $(SRC)\crt0.asm;
copy ..\dosseg.exe
dosseg crt0.obj
del dosseg.exe
crt0dat.obj: $(SRC)\crt0dat.asm $(CMACROS) $(INC)\msdos.inc
$(ASM) $(SRC)\crt0dat.asm;
crt0msg.obj: $(SRC)\crt0msg.asm $(CMACROS)
$(ASM) $(SRC)\crt0msg.asm;
nmsghdr.obj: $(SRC)\nmsghdr.asm $(CMACROS) $(INC)\msdos.inc
$(ASM) $(SRC)\nmsghdr.asm;
chksum.obj: $(SRC)\chksum.asm $(CMACROS) $(INC)\msdos.inc
$(ASM) $(SRC)\chksum.asm;
setargv.obj: $(SRC)\setargv.asm $(CMACROS) $(INC)\msdos.inc
$(ASM) $(SRC)\setargv.asm;
stdalloc.obj: $(SRC)\stdalloc.asm $(CMACROS) \
$(INC)\brkctl.inc $(INC)\msdos.inc
$(ASM) $(SRC)\stdalloc.asm;
stdenvp.obj: $(SRC)\stdenvp.asm $(CMACROS) $(INC)\msdos.inc $(INC)\brkctl.inc
$(ASM) $(SRC)\stdenvp.asm;
chkstk.obj: $(SRC)\chkstk.asm $(CMACROS) $(INC)\msdos.inc
$(ASM) $(SRC)\chkstk.asm;
# wild card expansion support modules
$(MODEL)setargv.obj: $(SRC)\stdargv.asm $(CMACROS) $(INC)\msdos.inc \
$(INC)\brkctl.inc
$(ASM) -Dwildcard $(SRC)\stdargv.asm,$(MODEL)setargv.obj;
_wild.obj: $(SRC)\_wild.asm $(CMACROS) $(INC)/msdos.inc
$(ASM) $(SRC)\_wild.asm;
wild.obj: $(SRC)\wild.c $(CINC)/stdio.h $(INC)/register.h $(CINC)/ctype.h
$(CL) -I$(CINC) -Ze -Zl $(SRC)\wild.c
# error message modules
crt0fp.obj: $(SRC)\crt0fp.asm $(CMACROS)
$(ASM) $(SRC)\crt0fp.asm;
execmsg.obj: $(SRC)\execmsg.asm $(CMACROS)
$(ASM) $(SRC)\execmsg.asm;
# small program
nulbody.obj: $(SRC)\nulbody.c
$(CL) $(SRC)\nulbody.c
# this step is always done because the target does not exist
startup:
link @$(SRC)\nulbody.lnk
IF NOT ERRORLEVEL 0 echo *** link failed ***

116
Microsoft C v4/MATH.C Normal file
View File

@ -0,0 +1,116 @@
#define FALSE 0
#define TRUE 1
extern char p[];
extern char t[];
extern int q;
arctan(s)
register int s;
{
register int n;
t[0] = 1;
div(s); /* t[] = 1/s */
add();
n = 1;
do {
mul(n);
div(s * s);
div(n += 2);
if (((n-1) / 2) % 2 == 0)
add();
else
sub();
} while (!tiszero());
}
add()
{
register int j;
for (j = q; j >= 0; j--)
if (t[j] + p[j] > 9) {
p[j] += t[j] - 10;
p[j-1] += 1;
} else
p[j] += t[j];
}
sub()
{
register int j;
for (j = q; j >= 0; j--)
if (p[j] < t[j]) {
p[j] -= t[j] - 10;
p[j-1] -= 1;
} else
p[j] -= t[j];
}
mul(multiplier)
register int multiplier;
{
int b;
register int i;
int carry, digit = 0;
for (i = q; i >= 0; i--) {
b = (t[i] * multiplier + carry);
digit = b % 10;
carry = b / 10;
t[i] = digit;
}
}
/* t[] /= l */
div(divisor)
int divisor;
{
register int i, b;
int quotient, remainder = 0;
for (i = 0; i <= q; i++) {
b = (10 * remainder + t[i]);
quotient = b / divisor;
remainder = b % divisor;
t[i] = quotient;
}
}
div4()
{
register int i, c, d = 0;
for (; i <= q; i++) {
c = (10 * d + p[i]) / 4;
d = (10 * d + p[i]) % 4;
p[i] = c;
}
}
mul4()
{
register int i, c, d;
d = c = 0;
for (i = q; i >= 0; i--) {
d = (p[i] * 4 + c) % 10;
c = (p[i] * 4 + c) / 10;
p[i] = d;
}
}
tiszero()
{
register int k;
for (k = 0; k <= q; k++)
if (t[k] != 0)
return(FALSE);
return(TRUE);
}

BIN
Microsoft C v4/MENU.BAT Normal file

Binary file not shown.

BIN
Microsoft C v4/MOUSE.COM Normal file

Binary file not shown.

BIN
Microsoft C v4/MOUSE.SYS Normal file

Binary file not shown.

BIN
Microsoft C v4/MSC.EXE Normal file

Binary file not shown.

157
Microsoft C v4/MSDOS.INC Normal file
View File

@ -0,0 +1,157 @@
;-----------------------------------------------------------------------
;
; MS-DOS definitions for C runtime
_NFILE equ 20 ; maximum # files per process
STACKSLOP equ 256 ; stack slop for interrupt overhead
; __osfile flag values for DOS file handles
FOPEN equ 01H ; file handle open
FEOFLAG equ 02H ; end of file has been encountered
FDEV equ 40H ; file handle refers to device
FTEXT equ 80H ; file handle is in text mode
FAPPEND equ 20H ; file handle opened O_APPEND
FRDONLY equ 10H ; file handle associated with read only file
callos MACRO func
ifnb <func>
mov ah,DOS_&func
endif
int DOS
ENDM
DOS equ 21H ; MS-DOS interrupt
DOS_exit equ 00000H ; exit offset (PSP:0000)
DOS_maxpara equ 00002H ; maximum paragraph (PSP:0002)
DOS_envp equ 0002cH ; environment address (PSP:002c)
DOS_cmdline equ 00080H ; command line offset (PSP:0080)
DOS_kill equ 00H ; terminate
DOS_echoread equ 01H ; read keyboard and echo
DOS_display equ 02H ; display character
DOS_auxinput equ 03H ; auxiliary input
DOS_auxoutput equ 04H ; auxiliary output
DOS_print equ 05H ; print character
DOS_conio equ 06H ; direct console i/o
DOS_coninput equ 07H ; direct console input
DOS_readkbd equ 08H ; read keyboard
DOS_message equ 09H ; display string
DOS_bufkbdin equ 0aH ; buffered keyboard input
DOS_kbdstatus equ 0bH ; check keyboard status
DOS_flshread equ 0cH ; flush buffer and read keyboard
DOS_diskreset equ 0dH ; disk reset
DOS_selectdisk equ 0eH ; select default disk
DOS_fcbopen equ 0fH ; open file with fcb
DOS_fcbclose equ 10H ; close file with fcb
DOS_fcbfirst equ 11H ; search for first entry with fcb
DOS_fcbnext equ 12H ; search for next entry with fcb
DOS_fcbdelete equ 13H ; delete file with fcb
DOS_fcbsread equ 14H ; sequential read with fcb
DOS_fcbswrite equ 15H ; sequential write with fcb
DOS_fcbcreate equ 16H ; create file with fcb
DOS_fcbrename equ 17H ; rename file with fcb
DOS_currentd equ 19H ; current default disk
DOS_setDMA equ 1aH ; set DMA
DOS_fcbrread equ 21H ; random read with fcb
DOS_fcbrwrite equ 22H ; random write with fcb
DOS_fcbsize equ 23H ; file size with fcb
DOS_fcbsetrec equ 24H ; set relative record with fcb
DOS_setvector equ 25H ; set interrupt vector
DOS_fcbbread equ 27H ; random block read with fcb
DOS_fcbbwrite equ 28H ; random block write with fcb
DOS_fcbparse equ 29H ; parse file name with fcb
DOS_getdate equ 2aH ; get date
DOS_setdate equ 2bH ; set date
DOS_gettime equ 2cH ; get time
DOS_settime equ 2dH ; set time
DOS_verify equ 2eH ; set/reset verify flag
DOS_getDMA equ 2fH ; get DMA
DOS_version equ 30H ; get version number
DOS_keep equ 31H ; keep process
DOS_cntlc equ 33H ; Cntl-C check
DOS_getvector equ 35H ; get interrupt vector
DOS_getdskspc equ 36H ; get disk free space
DOS_country equ 38H ; get country dependent info
DOS_mkdir equ 39H ; make subdirectory
DOS_rmdir equ 3aH ; remove subdirectory
DOS_chdir equ 3bH ; change subdirectory
DOS_create equ 3cH ; create pathname
DOS_open equ 3dH ; open pathname
DOS_close equ 3eH ; close file handle
DOS_read equ 3fH ; read from file handle
DOS_write equ 40H ; write from file handle
DOS_delete equ 41H ; delete pathname
DOS_lseek equ 42H ; move file pointer
DOS_filemode equ 43H ; get/set attributes of pathname
DOS_ioctl equ 44H ; ioctl for devices
DOS_dup equ 45H ; duplicate file handle
DOS_forcedup equ 46H ; force duplicate file handle
DOS_curdir equ 47H ; get current directory
DOS_allocmem equ 48H ; allocate memory block
DOS_freemem equ 49H ; free memory block
DOS_setmem equ 4aH ; set size of memory block
DOS_exec equ 4bH ; load and execute program
DOS_terminate equ 4cH ; terminate process with errorcode
DOS_wait equ 4dH ; get child process return code
DOS_findfirst equ 4eH ; find first file match
DOS_findnext equ 4fH ; find next file match
DOS_getverify equ 54H ; return current verify flag
DOS_rename equ 56H ; rename pathname
DOS_filedate equ 57H ; get/set file handle date/time
DOS_locking equ 5CH ; file record locking/unlocking
DOS_sleep equ 89H ; delay process execution
; DOS error codes
doserr MACRO num,name,text
name equ num
ENDM
doserr 1, E_ifunc, <invalid function code>
doserr 2, E_nofile, <file not found>
doserr 3, E_nopath, <path not found>
doserr 4, E_toomany, <too many open files>
doserr 5, E_access, <access denied>
doserr 6, E_ihandle, <invalid handle>
doserr 7, E_arena, <arena trashed>
doserr 8, E_nomem, <not enough memory>
doserr 9, E_iblock, <invalid block>
doserr 10, E_badenv, <bad environment>
doserr 11, E_badfmt, <bad format>
doserr 12, E_iaccess, <invalid access code>
doserr 13, E_idata, <invalid data>
doserr 14, E_unknown, <??? unknown error ???>
doserr 15, E_idrive, <invalid drive>
doserr 16, E_curdir, <current directory>
doserr 17, E_difdev, <not same device>
doserr 18, E_nomore, <no more files>
doserr 19, E_maxerr2, <unknown error - Version 2.0>
; the following errors can occur only in DOS 3.0
doserr 32, E_sharerr, <sharing violation>
doserr 33, E_lockerr, <locking violation>
doserr 34, E_maxerr3, <unknown error - Version 3.0>
; DOS file attributes
A_ro equ 01H ; read-only file
A_h equ 02H ; hidden
A_s equ 04H ; system
A_v equ 08H ; volume ID
A_d equ 10H ; directory
A_a equ 20H ; archive
A_mod equ A_ro+A_h+A_s+A_a ; modifiable attributes
; end of msdos.inc
;-----------------------------------------------------------------------

BIN
Microsoft C v4/MSETARGV.OBJ Normal file

Binary file not shown.

BIN
Microsoft C v4/MVARSTCK.OBJ Normal file

Binary file not shown.

133
Microsoft C v4/NMSGHDR.ASM Normal file
View File

@ -0,0 +1,133 @@
title nmsghdr - near message header and finder
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1986
;
;--------------------------------------------------------------------------
?DF= 1 ; this is special for c startup
include version.inc
?PLM= 1 ; pascal calling conventions
.xlist
include cmacros.inc
include msdos.inc
.list
createSeg _TEXT, code, byte, public, CODE, <>
createSeg _DATA, data, word, public, DATA, DGROUP
createSeg HDR, nhdr, byte, public, MSG, DGROUP
createSeg MSG, nmsg, byte, public, MSG, DGROUP
createSeg PAD, npad, byte, common, MSG, DGROUP
createSeg EPAD, nepad, byte, common, MSG, DGROUP
defGrp DGROUP ; define DGROUP
codeOFFSET equ offset _TEXT:
dataOFFSET equ offset DGROUP:
sBegin nhdr
assumes ds,data
db '<<NMSG>>'
stnmsg label byte
sEnd
sBegin npad
assumes ds,data
dw -1 ; message padding marker
sEnd
sBegin nepad
assumes ds,data
db -1
sEnd
sBegin code
assumes cs,code
assumes ds,data
;------------------------------------------------------------------------
;
; char * pascal __NMSG_TEXT ( messagenumber)
;
; This routine returns a near pointer to the message associated with
; messagenumber. If the message does not exist, then a 0 is returned.
;
; This routine reestablishes DS = ES = DGROUP
cProc __NMSG_TEXT,<PUBLIC>,<si,di> ; pascal calling
parmW msgt
cBegin
mov ax,DGROUP
mov ds,ax ; ds = DGROUP (force it always)
push ds
pop es
mov dx,msgt ; dx = message number
mov si,dataOFFSET stnmsg ; start of near messages
tloop:
lodsw ; ax = current message number
cmp ax,dx
je found ; found it - return address
inc ax
xchg ax,si
jz found ; at end and not found - return 0
xchg di,ax
xor ax,ax
mov cx,-1
repne scasb ; skip until 00
mov si,di
jmp tloop ; try next entry
found:
xchg ax,si
cEnd
;------------------------------------------------------------------------
;
; void pascal __NMSG_WRITE ( messagenumber)
;
; This routine writes the message associated with messagenumber
; to stderr.
cProc __NMSG_WRITE,<PUBLIC>,<di> ; pascal calling
parmW msgw
cBegin
push msgw
call __NMSG_TEXT ; find near text pointer
or ax,ax
jz nowrite ; don't write anything if not there
xchg dx,ax ; ds:dx = string address
mov di,dx
xor ax,ax
mov cx,-1
repne scasb ; es = ds from __NMSG_TEXT
not cx
dec cx ; cx = string length
mov bx,2
callos write
nowrite:
cEnd
sEnd
end

2
Microsoft C v4/NULBODY.C Normal file
View File

@ -0,0 +1,2 @@
main() {
}

View File

@ -0,0 +1,2 @@
nulbody crt0 crt0dat crt0msg nmsghdr chksum +
setargv stdalloc stdenvp /NOD /DOSSEG /m;

View File

@ -0,0 +1,28 @@
There is a bug in IBM PC-DOS 3.20 which may cause improper operation of a
program if a floating point exception is generated. This patch to IBM
PC-DOS 3.20 is provided to insure proper operation of programs which may
generate floating point exceptions. In particular, the C runtime routine
signal with the SIGFPE parameter does not work with the unpatched version
of IBM PC-DOS 3.20. IBM has also made a patch for this problem available.
Procedure for patching IBM PC-DOS 3.20:
1. Use the DOS sys command to transfer IBMDOS.COM and IBMBIO.COM
to a writable diskette.
2. Copy command.com, sys.com and debug.com from your IBM DOS 3.20
diskette to the new diskette.
3. Copy stkpat.bat, stkpat.scr, rmrhs.exe and setrhs.exe from the
\patch directory to the new diskette.
4. Reboot the system from the new diskette.
5. Run stkpat.bat. This patches the IBMBIO.COM on the new diskette.
6. Use the DOS sys command to transfer the patch to any other
IBM PC-DOS 3.20 diskette.
If you are running any version of DOS 3.20 other than IBM PC-DOS 3.20, contact
your hardware manufacturer (OEM) to find out if the problem exists in your
DOS 3.20 version.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,6 @@
echo This script will work only on drive a:
rmrhs
debug ibmbio.com <stkpat.scr
setrhs

View File

@ -0,0 +1,5 @@
a c48
jmp short c64
w
q

41
Microsoft C v4/PI.C Normal file
View File

@ -0,0 +1,41 @@
#define MAXPRC 4000
char p[MAXPRC];
char t[MAXPRC];
int q;
main(argc,argv)
int argc;
char *argv[];
{
long startime, endtime;
register int i;
if (argc == 2) {
sscanf(argv[1],"%d",&q);
} else {
printf("Usage: pi [precision]\n");
exit(55);
}
if (q > MAXPRC) {
printf("Precision too large\n");
exit(66);
}
/* compute pi */
time(&startime);
arctan(2);
arctan(3);
mul4();
time(&endtime);
/* print pi */
printf("pi = %d.",p[0]);
for (i = 1; i <= q; i++)
printf("%d",p[i]);
printf("\n");
printf("%ld seconds to compute %d digits of pi\n",endtime-startime,q);
}

BIN
Microsoft C v4/PI.EXE Normal file

Binary file not shown.

BIN
Microsoft C v4/PIB.BAT Normal file

Binary file not shown.

69
Microsoft C v4/README.DOC Normal file
View File

@ -0,0 +1,69 @@
The directory \startup and its subdirectories contain the files
necessary for building the startup portion of the C runtime library.
The \startup directory contains the startup source files, the memory
model independent include files, the batch file and the make file used
to build the startup object files. The subdirectories of \startup
contain the memory model dependent include file (version.inc) for the
startup and are the repositories for the object files that get created
by the startup batch file.
The startup object files can be built by invoking startup.bat. This
batch file assumes that the \startup directory and its subdirectories
S, M, C, and L exist and that make.exe, the C compiler and the assembler
are in the execution path. MASM 4.0 or later is required to build the
startup sources with the makefile invoked by startup.bat. The batch
file also assumes that the startup sources are in the same directory as
startup.bat.
The include files stdio.h and ctype.h are required for building the
startup source file wild.c but are not included on the \startup directory
because they exist on the directory containing the standard include files.
A make variable called CINC controls where the makefile looks for these
include files. CINC is currently set to look for these include files in
the \startup directory by the line "CINC=.." in the makefile. The value
of CINC can be changed appropriately if the includes are placed elsewhere.
The message "<cEnd - possible invalid use of nogen>" is generated
when some of the assembly language source files are assembled. This
message is expected and is totally benign.
The startup batch file requires arguments as described in the header of
startup.bat. Invoking startup.bat with no arguments will also give usage
information.
The following files are contained in the \startup directory:
Startup source files:
chkstk.asm
chksum.asm
crt0.asm
crt0dat.asm
crt0fp.asm
crt0msg.asm
execmsg.asm
nmsghdr.asm
setargv.asm
stdalloc.asm
stdenvp.asm
stdargv.asm
_wild.asm
wild.c
Startup include files:
brkctl.inc
cmacros.inc
msdos.inc
register.h
Tools:
dosseg.exe
Make and batch files:
startup.bat: invokes make file to build objs and link to null program
makefile: contains rules for building startup sources
nulbody.c: null c program
nulbody.lnk: link script for linking null program
Documentation:
readme.doc: information about \startup directory structure
and contents

BIN
Microsoft C v4/RESPOND.COM Normal file

Binary file not shown.

View File

@ -0,0 +1,8 @@
;-----------------------------------------------------------------------
; (C)Copyright Microsoft Corporation, 1984, 1985, 1986
;--------------------------------------------------------------------------
?PLM= 0
?WIN= 0
memS equ 1 ; small model

11
Microsoft C v4/S1.@@@ Normal file
View File

@ -0,0 +1,11 @@
Machine Menu
Which type of computer are you using?
I IBM (TM) Personal Computer
C IBM-compatible computer
N MS-DOS computer that is not IBM compatible
Press the letter of your selection: 

17
Microsoft C v4/S10.@@@ Normal file
View File

@ -0,0 +1,17 @@
A common debugging technique is to establish a situation in
which you know the results your program should produce, then
see if the program actually produces those results. This
method is used in the sample session.
During the session, the debugger examines a simple program
called COUNT. This program counts the letters, words, sentences,
and other elements in a text file. The program contains a bug
that will be found and analyzed during the session.
To test the program, a text file called COUNT.TXT is provided.
The words, sentences, letters, bytes, and other elements in
COUNT.TXT have been counted by hand, and noted in the file itself.
During debugging, the numbers in the text file will be compared
to the numbers counted by the program. Any differences will
be a clue to help locate the bug.

9
Microsoft C v4/S11.@@@ Normal file
View File

@ -0,0 +1,9 @@
The rest of the session may be more helpful if you have a
printed listing of the source file, COUNT.C, and the file
to be analyzed, COUNT.TXT. If you have a printer that can
be accessed through the PRN device, you can now print these
files. Make sure your printer is properly attached to the
computer, that the power is on, and that the paper is adjusted.
Do you want to print COUNT.C and COUNT.TXT? (Y/N) 

23
Microsoft C v4/S12.@@@ Normal file
View File

@ -0,0 +1,23 @@
The debugger will be started with the following command line:
CVR /W /S /M "/C<COUNT.R" COUNT COUNT.TXT
The elements of the command line are explained below:
- CVR is the program name of the restricted debugger.
- /W is an option that specifies window mode.
- /S is an option that specifies screen swapping as the
screen-exchange mode.
- /M is an option that turns off the mouse if you have one.
- "/C<COUNT.R" is an option that specifies that, on start-up,
commands will be redirected from COUNT.R to the debugger.
- COUNT is the executable file (the .EXE extension is assumed).
- COUNT.TXT is the file to be processed by COUNT.EXE.
Your command line may also include the /B, /I, or /D options,
depending on selections made at previous menus. See the
CODEVIEW.DOC file for more information on command lines.
The debugger will now be started. Loading and initial processing
may take a moment . . .

16
Microsoft C v4/S13.@@@ Normal file
View File

@ -0,0 +1,16 @@
The program `PI' calculates the value of pi to whatever
precision you specify on the command line. Unlike other
sample programs on the demonstration disk, `PI.EXE' was
compiled from two source modules: `PI.C' and `MATH.C'.
The session opens the debugger with `PI' as the program to
be debugged. The number 60 is passed as a parameter so that
`PI' will calculate pi to 60 decimal places.
To quit, enter `Q' or select Quit from the File menu. For
on-line help, press F1 or select Help from the View menu.
Other than that, you're on your own. Good luck!
The debugger will now be started. Loading and initial
processing may take a moment . . .

12
Microsoft C v4/S14.@@@ Normal file
View File

@ -0,0 +1,12 @@
If your computer is not IBM compatible, you will not be able
to run the sample session. You can still use the CodeView (TM)
debugger in sequential mode, as described in the CODEVIEW.DOC
file, which summarizes the CodeView commands and options.
If you have a printer that can be accessed through the PRN
device, you can print CODEVIEW.DOC now. Make sure your printer
is properly attached to the computer, that the power is on,
and that the paper is adjusted.
Do you want to print CODEVIEW.DOC? (Y/N) 

21
Microsoft C v4/S2.@@@ Normal file
View File

@ -0,0 +1,21 @@
A few IBM-compatible computers require the /D CodeView
option. The following are known to require this option:
Tandy 1000 AT&T 6300 Plus
Computers that work without /D include the following:
Compaq Eagle
HP Vectra TI Business Professional
AT&T 6300 Zenith (except model 100)
Tandy 1200 or 3000 NCR PC
If your computer is not mentioned, try the session first
without /D. If you have trouble, try again with /D. If you
still have trouble, your computer isn't compatible.
If you use the /D option, the CONTROL-C and CONTROL-BREAK
keys cannot be used to break out of the sample session.
Do you want to try the /D option? (Y/N) 

11
Microsoft C v4/S3.@@@ Normal file
View File

@ -0,0 +1,11 @@
Equipment Menu
Which type of display adapter and monitor are you using?
M Monochrome monitor and monochrome adapter
B Black-and-white monitor and graphics adapter
C Color monitor and graphics adapter
Press the letter of your selection: 

21
Microsoft C v4/S4.@@@ Normal file
View File

@ -0,0 +1,21 @@
Welcome to the CodeView (TM) debugger.
Now the world-class Microsoft (R) C Compiler comes with a
world-class debugger. During this session, you'll see it
in action. You can learn how to use it and try it on your
own. By that time, we think you'll be ready to buy it.
The CodeView demonstration disk is freely copyable. You may
give the disk to friends, upload it to electronic bulletin
boards, or distribute it through computer clubs. Read the
CODEVIEW.DOC file for more information about distribution
and use of the demonstration disk.
The debugger on this disk (CVR.EXE) is a restricted version
that can only be used with the three sample programs. The
unrestricted version (CV.EXE) comes with Version 4.0 of the
Microsoft C Compiler.
Copyright (C) Microsoft Corporation 1986
All rights reserved

20
Microsoft C v4/S5.@@@ Normal file
View File

@ -0,0 +1,20 @@
Demonstration Menu
Which demonstration do you want to see?
D Demonstrates CodeView features. This selection uses
a graphics program and requires a graphics adapter.
P Prints the documentation file, CODEVIEW.DOC.
T Teaches you about CodeView debugging. During this
session, a sample program is automatically examined
and debugged. The session demonstrates and explains
most CodeView commands.
E Enables you to experiment by examining a program that
calculates the value of pi.
Q Quits the sample session.
Press the letter of your selection: 

8
Microsoft C v4/S6.@@@ Normal file
View File

@ -0,0 +1,8 @@
The documentation file, CODEVIEW.DOC, summarizes the
CodeView commands and options. If you have a printer
that can be accessed through the PRN device, you can
print this file. Make sure your printer is properly
attached to the computer, that the power is on, and
that the paper is adjusted.
Do you want to print CODEVIEW.DOC now? (Y/N) 

8
Microsoft C v4/S7.@@@ Normal file
View File

@ -0,0 +1,8 @@
If you have a mouse, you can probably use it with the
CodeView debugger. However, the debugger is not guaranteed
to work correctly if your computer is not completely IBM
compatible or if your mouse is not a Microsoft Mouse. A
few non-IBM machines will not run the debugger at all with
a mouse.
Do you want to try using the mouse? (Y/N) 

13
Microsoft C v4/S8.@@@ Normal file
View File

@ -0,0 +1,13 @@
Powerful, flexible, easy to use--the Microsoft CodeView
debugger does what you want a debugger to do. And it lets
you work the way you want to work.
You can debug at the source or assembly level. Commands
can be entered with menus, function keys, a mouse, or
command lines. Multiple windows display all the information
you need when you need it. Debugging graphics programs is
a snap with the CodeView debugger.
But don't take our word for it. See for yourself.

17
Microsoft C v4/S9.@@@ Normal file
View File

@ -0,0 +1,17 @@
The CodeView debugger is a powerful tool for serious debugging.
This session uses a practical example to introduce you to
CodeView commands. Each step in the debugging process is
explained as it is performed. The session is quite detailed
and takes 20 to 30 minutes.
You control the pace. The session periodically pauses and asks
you to press the SPACEBAR. Although keystrokes and commands
are discussed on the screen, you should NOT try to type them.
The session does this automatically. Just press the SPACEBAR.
You can quit the session after the debugger is started by first
pressing CONTROL-C or CONTROL-BREAK, then pressing the SPACEBAR.
The word `break' will appear, followed by the CodeView prompt
(the greater-than symbol). At the prompt, enter `Q' for Quit.
The debugger will terminate.

BIN
Microsoft C v4/SAMPLE.BAT Normal file

Binary file not shown.

279
Microsoft C v4/SETARGV.ASM Normal file
View File

@ -0,0 +1,279 @@
title stdargv - standard _setargv routine
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984,1985,1986
;
;--------------------------------------------------------------------------
include version.inc
.xlist
include cmacros.inc
include msdos.inc
.list
TAB = 9 ; tab character
sBegin data
assumes ds,data
externW _psp ; psp segment #
externDP __argv ; argv address
externW __argc ; argc
externB _osmajor ; os major version #
staticCP retadr,0 ; return address
sEnd data
sBegin code
assumes ds,data
assumes cs,code
labelP <PUBLIC,_setargv>
pop word ptr [retadr] ; get return address
if sizeC
pop word ptr [retadr+2] ; seg part of return address
endif
mov ds,[_psp] ; get psp segment
push ss ; ss = ds assumption
pop es
assumes ds,nothing
assumes es,data
; move command line at (psp:80) to stack
mov si,DOS_CMDLINE ; point to command line
lodsb ; get length
cbw ; and convert to word
;xor dx,dx ; argv[0] valid? initially no
cmp __osmajor,3
jb tooold ; if < dos 3.0
push ax ; save length
mov es,ds:[DOS_ENVP] ; envp seg addr
assumes es,nothing
xor ax,ax ; 0
mov cx,ax
not cx ; -1
mov di,ax ; 0
again:
repne scasb ; find null
cmp es:[di],al ; env null?
jne again ; no
add di,3 ; to get to argv[0]
mov cx,ax
not cx ; -1
push di ; start of argv[0]
repne scasb ; search for argv[0] null & get length
pop si ; start of argv[0]
add cx,2 ; cx=-len(argv[0])
neg cx ; cx=+len(argv[0])
;inc dx ; valid argv[0]
pop bx ; len(argv[1]+...+argv[n])
mov ax,bx
add ax,cx ; +len(argv[0])
add ax,3 ; space, null, rounding
and ax,not 1 ; rounded even
sub sp,ax ; allocate space on stack
mov di,sp ; di=destination
push ds ; save psp
push es
pop ds ; ds=env seg
push ss
pop es ; es=stack seg
assumes es,data
rep movsb ; move argv[0]
mov al,' ' ; space following argv[0]
stosb
mov cx,bx ; len(argv[1]+...+argv[n])
pop ds ; psp seg
mov si,DOS_CMDLINE+1 ; restore si for command line move
jmp short moveit
tooold:
mov cx,ax ; save length
add al,4 ; pad for 'C ', term and rounding
and al,not 1 ; round even
sub sp,ax ; allocate space on stack
mov di,sp ; di = destination
mov ax,'C' + ' ' shl 8
stosw ; stuff 'C '
moveit:
rep movsb ; move command line
mov ax,cx ; ax=0
stosb ; stuff terminating 00
mov si,sp ; save command line ptr
push ss
pop ds
assumes ds,data
; crack command line arguments onto stack
push ax ; terminating NULL
if sizeD
push ax ; seg part for long model
endif
mov bx,sp ; remember top of argv (reversed)
nextarg:
mov di,si ; resync argument
lodsb ; get next char
or al,al ; check for end of line
je endline ; yes
call iswhite ; is it white space
jz nextarg ; yes - keep skipping
dec si ; point to 1st character
if sizeD
push ds
endif
push si ; argv entry is ds:si
inc [__argc] ; bump arg count
notspace:
lodsb ; get next char
call isquote
stosb
or al,al ; check for end of line
je endline ; yes
call iswhite ; is it white space
jnz notspace ; no - keep skipping
mov byte ptr [di-1],0 ; zero terminate arg
jmp short nextarg
endstoreb:
stosb ; save null terminator
endline:
mov si,sp ; si = last arg (reversed)
revloop:
if sizeD
sub bx,4
else
dec bx
dec bx
endif
cmp si,bx ; half way up or more
jae revdone ; yes - return
lodsw
xchg [bx],ax
mov [si-2],ax ; swap offsets
if sizeD
lodsw
xchg [bx+2],ax
mov [si-2],ax ; swap segments
endif
jmp short revloop ; keep looping
revdone:
mov bx,sp
;or dx,dx ; argv[0] valid?
;jnz keepit ; yes
; no, skip it
;inc word ptr [bx] ; argv[0] = null - skip past 'C'
keepit:
if sizeD
mov word ptr [__argv+2],ss
endif
mov word ptr [__argv],sp ; save argv pointer
jmp [retadr] ; return
iswhite:
cmp al,TAB ; is it a TAB
je iswret ; yes - exit
cmp al,' ' ; is it a space
iswret:
ret ; return
isquote:
cmp al, '\' ; is this a backslash
jne normquote
cmp byte ptr ds:[si],'"' ; check for \" must do this this way to avoid
jne normquote ; a first char quote with the byte before it
lodsb ; just happening to be a backslash.
jmp short isqret
normquote:
cmp al, '"' ; is it a quote
jne isqret
ifdef NOEATQUOTE
stosb
endif
notquote:
lodsb ; get next char
cmp al,13 ; check for eol
je isqret ; yes - early termination
cmp al,'"' ; ending quote
jne storeb ; no - keep scanning
cmp byte ptr ds:[si-2],'\' ; check for \"
jne endquote ; not \"
ifndef NOEATQUOTE
dec di
endif
storeb:
stosb ; stuff char
jmp short notquote
endquote:
ifdef NOEATQUOTE
stosb
endif
lodsb
jmp short isquote ; done with quotes
isqret:
ret ; return
sEnd code
end

BIN
Microsoft C v4/SETENV.EXE Normal file

Binary file not shown.

35
Microsoft C v4/SIEVE.C Normal file
View File

@ -0,0 +1,35 @@
/* sieve.c */
/* Eratosthenes Sieve Prime Number Program in C from Byte Jan 1983
to compare the speed. */
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define SIZE 8190
typedef int bool;
char flags[SIZE+1];
int cdecl 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
Microsoft C v4/SSETARGV.OBJ Normal file

Binary file not shown.

View File

@ -0,0 +1,72 @@
echo off
REM
REM (C)Copyright Microsoft Corporation, 1986
REM
REM batch file used to invoke make file to build startup
REM Usage: startup (models)
REM (models) is a blank separated list of memory
REM model designators as follows:
REM S: small model
REM M: medium model
REM C: compact model
REM L: large model
REM Examples:
REM startup S M
REM builds small and medium model objects
REM and links with null c program
REM
REM startup S C M L
REM builds objects for all memory models
REM and links with null c program
if NOT "%1" == "" goto nextdir
echo Usage: startup (models)
echo (models) is a blank separated list of memory
echo model designators as follows:
echo S: small model
echo M: medium model
echo C: compact model
echo L: large model
echo Example:
echo startup S M
echo builds small and medium model objects and
echo links with null c program
goto end
:nextdir
if "%1" == "" goto finished
if "%1" == "S" goto argok
if "%1" == "M" goto argok
if "%1" == "C" goto argok
if "%1" == "L" goto argok
echo off
echo Error: invalid argument to startup.bat
echo The valid arguments to startup.bat are S M C and L.
echo The model designators must be upper case.
goto end
:argok
echo on
cd %1
copy ..\*.h
copy ..\*.inc
make MODEL=%1 ..\makefile
del *.h
del msdos.inc
del brkctl.inc
del cmacros.inc
IF NOT ERRORLEVEL 0 goto failure
cd ..
shift
goto nextdir
:failure
ECHO *** startup link failed ***
:finished
echo **** Finished
:end

View File

@ -0,0 +1,95 @@
title stdalloc - memory allocation routine for stdargv, stdenvp
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984, 1986
;
;--------------------------------------------------------------------------
include version.inc
.xlist
include cmacros.inc
include msdos.inc
include brkctl.inc
.list
sBegin data
assumes ds,data
externW _psp ; PSP segment #
externW _abrktb ; break table for allocation
externW _asizds ; break table for allocation end
sEnd data
sBegin code
assumes ds,data
assumes cs,code
externNP _amsg_exit ; write error and die routine
;*** myalloc - used to allocate heap space, without the overhead of
; malloc for both wildcard arguments and environment strings, ptrs.
;
; ARGUMENTS
; bp contains number of bytes in table ( argv/ or envp )
; ax contains total number of bytes to allocate table and strings
; di contains error message number in case of death.
;
; RETURNS
; bp points to table, ax is size of table in bytes.
;
; DESCRIPTION
; tries to find space in heap, failing this calls dos to extend
; heap and tries again, failing this spits out error message and
; dies.
;
cProc _myalloc,<NEAR,PUBLIC>,<>
cBegin nogen
assumes ds,data
mov dx,ax ; save size of environment
add ax,[_abrktb].sz ; ax = DS offset of end of environment
jc _hpovr ; environment won't fit w/in 64k
; give error
cmp [_asizds],ax ; will env fit in allocated mem?
jnc _hpok ; yes, go move it
; need more memory
add ax,15d ; round up to nearest paragraph
push ax ; save this for later
rcr ax,1 ; shift right including carry from add
mov cl,3
shr ax,cl ; convert to # of paragraphs
mov cx,ds
mov bx,[_psp]
sub cx,bx ; DGROUP - _PSP
add ax,cx ; make # of paragraphs _PSP relative
mov es,bx ; seg addr of mem area
mov bx,ax ; set up for OS call
callos setmem ; change size of mem block to bx paras
pop ax ; restore (env size + 15)
jc _hpovr ; not enough memory, give error
and al,0F0h ; round down to nearest paragraph addr
dec ax
mov [_asizds],ax ; store new last byte of DGROUP
_hpok:
xchg ax,bp ; ax = size of env ptr table
mov bp,[_abrktb].sz ; bp points to mem for storing env ptrs
add [_abrktb].sz,dx ; update bottom of heap
ret
_hpovr:
mov ax,di ; error 2009/2008: no space for enviroment/arguments
jmp _amsg_exit ; give error and die
cEnd nogen
sEnd code
end

446
Microsoft C v4/STDARGV.ASM Normal file
View File

@ -0,0 +1,446 @@
title stdargv - standard _setargv routine
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984, 1986
;
;--------------------------------------------------------------------------
?DF = 1 ; tell cmacros.inc we want to define our own segments
include version.inc
.xlist
include cmacros.inc
include msdos.inc
include brkctl.inc
.list
createSeg _TEXT, code, byte, public, CODE, <>
createSeg _DATA, data, word, public, DATA, DGROUP
createSeg HDR, nhdr, byte, public, MSG, DGROUP
createSeg MSG, nmsg, byte, public, MSG, DGROUP
createSeg PAD, npad, byte, common, MSG, DGROUP
createSeg EPAD, nepad, byte, common, MSG, DGROUP
defGrp DGROUP ; define DGROUP
codeOFFSET equ offset _TEXT:
dataOFFSET equ offset DGROUP:
TAB = 9 ; tab character
sBegin data
assumes ds,data
externW _psp ; psp segment #
externB _osmajor ; os major version #
externDP __argv ; argv address
externW __argc ; argc
externW _abrktb ; break table
externW _asizds ; break table end
globalW __argl,0 ; total length of arguments ( expanded )
staticDP argptr,0
sEnd data
ifdef wildcard
externP _cwild ; the wildcard expander
endif
;msg used by stdargv (wild card version of _setargv)
sBegin nmsg
assumes ds,data
dw 8
db 13,10,'error 2008: Not enough space for arguments',13,10,0
sEnd
sBegin code
assumes cs,code
assumes ds,data
externNP _myalloc ; allocation routine for arguments
cProc _setargv,<PUBLIC>,<>
cBegin
mov ax,1
mov [__argc],ax ; start argc at one for this tacky patch
push ax
call near ptr _wsetargv
inc sp
inc sp
mov ax,2
push ax
call near ptr _wsetargv
inc sp
inc sp
cEnd
cProc _wsetargv,<NEAR>,<>
parmw pass
localW endarg
cBegin
push ds ; save ds, it gets trashed
assumes ds,data
assumes ss,data
cmp pass,2
jne apass1
push bp ; save bp for endarg
mov bp,[__argc]
inc bp
if sizeD
shl bp,1
endif
shl bp,1
mov ax,[__argl]
add ax,bp
; Register usage at this point:
; ax = total # bytes needed for argument ptr table and strings
; bp = # bytes required to store arg ptr table
mov di,8 ; no space for arguments message if death.
call _myalloc
; bp points to arg table
; ax is size of arg table in bytes.
mov word ptr [__argv],bp
mov word ptr [argptr],bp
if sizeD
mov word ptr [__argv+2],ds
mov word ptr [argptr+2],ds
endif
add ax,bp
pop bp ; recover bp for endarg
push ax ; Save pointer to string section
apass1:
; move command line at (psp:80) to memory
cmp __osmajor,3
pushf ; save flags for later if too old to get argv[0]
mov ds,[_psp] ; get psp segment
mov si,DOS_CMDLINE ; point to command line
lodsb ; get length
cbw ; and convert to word
mov endarg,ax ; store length of command line in endarg
add endarg,si ; put last character position of si in
; endarg to stop scan.
popf ; recover flags for age test.
push ax ; save length
jae ageok
pop ax
call saveargptr
jmp tooold ; if < dos 3.0
ageok:
mov es,ds:[DOS_ENVP] ; envp seg addr
xor ax,ax ; 0
mov cx,ax
not cx ; -1
mov di,ax ; 0
again:
repne scasb ; find null
cmp es:[di],al ; env null?
jne again ; no
add di,3 ; to get to argv[0]
mov cx,ax
not cx ; -1
push di
repne scasb ; search for argv[0] null & get length
pop si ; start of argv[0]
inc cx ; cx=-len(argv[0])
inc cx ; cx=-len(argv[0])
neg cx ; cx=+len(argv[0])
pop dx ; len(argv[1]+...+argv[n])
call saveargptr
mov ax,dx
add ax,cx ; +len(argv[0])
add ax,3 ; account for null, and rounding
and ax,not 1 ; rounded even
cmp pass,1 ; size up the total length of all the argv's
jne apass2
mov bx,sp ; get old data pointer back
mov ds,ss:[bx]
add [__argl],ax
mov ds,[_psp]
jmp short epass1
apass2:
mov ds,ds:[DOS_ENVP]
rep movsb ; move argv[0]
xor al,al ; space & null following argv[0]
stosb
mov cx,dx ; len(argv[1]+...+argv[n])
call recoverds
mov ds,[_psp]
mov bx,ax
epass1:
mov si,DOS_CMDLINE+1 ; restore si for command line move
jmp short nextarg
tooold:
cmp pass,1
jne bpass2
mov cx,ax ; save length
add al,4 ; pad for 'C ', term and rounding
and al,not 1 ; round even
mov bx,sp ; get old data pointer back
mov ds,ss:[bx]
mov es,ss:[bx]
add [__argl],ax ; increment length of the string section
mov ds,[_psp] ; recover psp segment
jmp short nextarg
bpass2:
mov ax,'C'shl 8 + ' '
stosw
xor ax,ax
stosb
; crack command line arguments onto stack
nextarg:
xor cx,cx
lodsb ; get next char
cmp si,endarg ; check for eoln
jbe cont ; eoln not found
jmp endline ; eoln found
cont:
call iswhite ; is it white space
jz nextarg ; yes - keep skipping
dec si ; point to 1st character
ifdef wildcard
mov dx,si ; save beginning of arg for wildcard
endif
cmp pass,2 ; put entry in argv array
jne gpass1
mov es:[bx],di ; argv entry is es:di
add bx,2
if sizeD
mov es:[bx],es
add bx,2
endif
jmp short notspace
gpass1:
call recoverds
inc [__argc] ; bump arg count
mov ds,[_psp] ; and ds back again
mov bx,ax
notspace:
lodsb ; get next char
ifdef wildcard
call iswild
endif
call isquote
cmp pass,2
jne hpass1
stosb
hpass1:
cmp si,endarg ; check for end of line
ja eoln ; yes
call iswhite ; is it white space
jnz notspace ; no - keep skipping
eoln:
cmp pass,2
jne ipass1
mov byte ptr es:[di-1],0 ; zero terminate arg
ipass1:
ifdef wildcard
cmp cx,100h ; only valid wildcard expansion
jne nowild
call recoverds
mov bx,ax
push ds:[_psp] ; pass [_psp]:si
push dx
push pass ; pass pass number
if sizeD
push ds ; pass char for argv
sub bx,4
else
sub bx,2
endif
mov word ptr [argptr],bx
push bx ; ignored for pass 1
call _cwild ; wildcard expander
if sizeD ; Clean up stack
add sp,10
mov es,dx
else
add sp,8
endif
mov bx,sp ; get old data pointer back
mov es,ss:[bx]
mov bx,ax ; get next available argument vect.
mov di,es:[bx] ; get next available string section
mov ds,[_psp]
nowild:
endif
jmp nextarg
endline:
cmp pass,2
jne zpass1
mov byte ptr es:[di-1],0 ; zero terminate arg
if sizeD ; end argv array with a null
mov word ptr es:[bx+2],0000
endif
mov word ptr es:[bx],0000
zpass1:
pop ds
cEnd
ifdef wildcard
iswild:
cmp al,'*' ; is it a star
je iswldret ; yes - exit
cmp al,'?' ; is it a question mark
jne wldret
iswldret:
mov ch,1
wldret:
ret ; return
endif
iswhite:
cmp al,TAB ; is it a TAB
je iswret ; yes - exit
cmp al,' ' ; is it a space
iswret:
ret ; return
isquote:
cmp al, '\' ; is this a backslash
jne normquote
cmp byte ptr ds:[si],'"' ; check for \" must do this this way to avoid
jne normquote ; a first char quote with the byte before it
ifdef wildcard
mov cl,1 ; disable wildcard
endif
lodsb ; just happening to be a backslash.
jmp short isqret
normquote:
cmp al, '"' ; is it a quote
jne isqret
ifdef wildcard
mov cl,1 ; disable wildcard
endif
notquote:
lodsb ; get next char
cmp al,13 ; check for eol
je isqret ; yes - early termination
cmp al,'"' ; ending quote
jne storeb ; no - keep scanning
cmp byte ptr ds:[si-2],'\' ; check for \"
jne endquote ; yes
dec di
storeb:
cmp pass,2
jne kpass1
stosb ; stuff char
kpass1:
jmp short notquote
endquote:
lodsb
jmp short isquote ; done with quotes
isqret:
ret ; return
saveargptr:
cmp pass,2
jne vpass1
mov bx,sp ; get old data pointer back
add bx,4
mov ds,ss:[bx]
pop es ; save return address
pop di
push es ; recover return address
mov es,ss:[bx]
mov bx,word ptr [argptr]
mov [bx],di
add bx,2
if sizeD
mov [bx],ds
add bx,2
endif
mov ds,[_psp] ; restore ds to _psp
vpass1:
ret
recoverds:
mov ax,bx
mov bx,sp ; get old data pointer back
mov ds,ss:[bx+2]
ret
sEnd code
end

158
Microsoft C v4/STDENVP.ASM Normal file
View File

@ -0,0 +1,158 @@
title stdenvp - standard _setenvp routine
;--------------------------------------------------------------------------
;
; Microsoft C Compiler Runtime for MS-DOS
;
; (C)Copyright Microsoft Corporation, 1984, 1986
;
;--------------------------------------------------------------------------
include version.inc
.xlist
include cmacros.inc
include msdos.inc
.list
sBegin data
assumes ds,data
externW _psp ; PSP segment #
externDP environ ; environment pointer
sEnd data
sBegin code
assumes ds,data
assumes cs,code
externNP _myalloc ; allocation routine for arguments
cProc _setenvp,<PUBLIC>,<>
cBegin
push bp
mov ds,[_psp] ; get psp segment
assumes ds,nothing
; setup envp vector and move environment to heap
; DS = PSP, SS = DGROUP
xor cx,cx ; cx = 0
mov ax,cx ; ax = 0 (search byte)
mov bp,cx ; bp = 0 (envp count)
mov di,cx ; di = 0 (initial offset)
dec cx ; cx = ffff (inifinite count)
mov si,word ptr DS:[DOS_ENVP]
or si,si ; test for null envp
jz noenv ; none
mov es,si ; es:di = environment table
scanenv:
repnz scasb
inc bp ; bp = envp count
scasb
jnz scanenv
noenv:
inc bp ; bp = envp count + 1
xchg ax,di ; ax = envlen
inc ax
and al,not 1 ; round up to even
mov di,bp ; di = argument count
shl bp,1 ; argument count*2
if sizeD
shl bp,1 ; argument count*2
endif
add ax,bp ; ax = space to allocate
push ss
pop ds ; restore DS
assumes ds,data
; Make sure there is enough memory for the environment.
; If there is not enough, try to get some from the OS if possible.
; Register usage at this point:
; ax = total # bytes needed for environment ptr table and strings
; di = # of entries in env ptr table = # of env args + 1
; bp = # bytes required to store env ptr table
; ss = ds = DGROUP
; es = PSP segment
push di ; save # of env args + 1
mov di,9 ; error message in case of death.
call _myalloc ; takes bp = # bytes for ptr table ax = total #
; bytes
pop di ; recover # of env args + 1
; Now there is enough memory for the environment, so copy it in.
; Register usage at this point:
; dx = size of environment in bytes
; di = # of entries in env ptr table = # of env args + 1
; bp points to env table
; ax is size of env table in bytes.
; ss = ds = DGROUP
; es = PSP segment
mov cx,di ; cx = envcnt
mov di,bp
add di,ax ; di points past env ptr table
; store strings there
mov word ptr [environ],bp ; save envp[]
if sizeD
mov word ptr [environ+2],ds ; segment address for large model
endif
push ds
pop es ; es:di = env dest
mov ds,si ; ds:0 = env table
xor si,si
; SS = ES = DGROUP
; DS = PSP segment
assumes es,data
assumes ds,nothing
dec cx ; adjust for the last entry of 0000
jcxz envdone ; done - no environment
envloop:
cmp word ptr [si],';'+'C'*100h ; test if starts with ';C'
je envstr ; don't save pointer if ';C'
mov [bp],di ; save pointer to start of string
if sizeD
mov [bp+2],es ; segment address for large model
add bp,4
else
inc bp
inc bp
endif
envstr:
lodsb
stosb
or al,al
jnz envstr ; keep copying string
loop envloop ; more strings to copy
envdone:
mov [bp],cx ; zero terminate envp table
if sizeD
mov [bp+2],cx ; extra zero for large model
endif
push ss ; DS = DGROUP
pop ds
pop bp
cEnd
sEnd code
end

BIN
Microsoft C v4/SVARSTCK.OBJ Normal file

Binary file not shown.

165
Microsoft C v4/TM.C Normal file
View File

@ -0,0 +1,165 @@
#include <stdio.h>
#ifdef AZTEC86
#include <stdlib.h>
#endif
#ifdef HISOFTC
#include <stdlib.h>
#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;
}

527
Microsoft C v4/TTT.C Normal file
View File

@ -0,0 +1,527 @@
/*
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
int cdecl 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*/

207
Microsoft C v4/WILD.C Normal file
View File

@ -0,0 +1,207 @@
/*
** wild.c
** wildcard expander
**
** handles '*' (none or more of any char), '?' (exactly one char), and
** '[string]' (chars which match string chars or between n1 and n2 if 'n1-n2'
** in string inclusive)
**
*/
#include <stdio.h>
#include <register.h>
#include <ctype.h>
/*
** these are the data structures
**
** [_psp]:81
** Raw command line.
**
** __argv
** ------- ------
** | |---->| |---->"arg0"
** ------- ------
** | |---->"arg1"
** ------
** ....
** ------
** | |---->"argn"
** ------
** |NULL|
** ------
*/
#define SLASHCHAR '\\'
#define FWDSLASHCHAR '/'
#define SLASH "\\"
#define FWDSLASH "/"
char *_hfind();
extern int __argc;
extern int __argl;
extern char **__argv;
static int _add(int, char ***, char far *, char far *, int );
static int _match(char far *, char ***, char far *, int );
static _sort (char **);
static _hmmcpy( a, b, n )
char *a, far *b;
int n;
{ REG1 int i;
for ( i = 0; i < n; i++ )
*( a + i ) = *( b + i );
}
char **
_cwild ( argv, pass, arg )
char **argv;
int pass;
char far *arg;
{
char savechar;
char far *wchar;
char far *arghead = arg;
int ptr, sptr, arglen;
_setdta();
while ( *arg && ( *arg != ' ' ) && ( *arg != '\t' )
&& ( *arg != '\15' ))
arg++;
savechar = *arg; /* save this character, since it is in psp */
*arg = '\0';
for ( wchar = arghead; wchar && ( *wchar != '*' ) && ( *wchar != '?' );
wchar++ );
_match( wchar, &argv, arghead, pass );
*arg = savechar; /* restore this character */
return( argv );
}
static int
_match ( ptr, argv, arg, pass)
char far *ptr;
char ***argv;
char far *arg;
int pass;
{
char *new;
int length;
char **oldargv = *argv;
int gotone = 0;
if ( pass == 1 )
--__argc;
while (ptr != arg && *ptr != SLASHCHAR && *ptr != FWDSLASHCHAR
&& *ptr != ':')
/* find first slash or ':' before wildcard */
ptr--;
if (*ptr == ':' && ptr != arg+1) /* weird name, just add it as is */
return( _add( 0, argv, arg, (char far *)NULL, pass ) );
if (*ptr == SLASHCHAR || *ptr == FWDSLASHCHAR
|| *ptr == ':') /* pathname */
length = ptr - arg + 1; /* length of dir prefix */
if (new = _hfind(arg)) { /* get the first file name */
do { /* got a file name */
if (strcmp(new, ".")
&& strcmp(new, "..")) {
if (*ptr != SLASHCHAR && *ptr != ':'
&& *ptr != FWDSLASHCHAR ) {
/* current directory; don't need path */
if ( _add( 0, argv, (char far *)new,
(char far *)NULL, pass ) )
return(-1);
}
else /* add full pathname */
if ( _add( length, argv,
(char far *)new, arg, pass) )
return(-1);
gotone++;
}
} while (new = _hfind(NULL)); /* get following files */
if (gotone) {
if ( pass == 2 )
{
new = **argv;
**argv = NULL;
_sort(oldargv);
**argv = new;
}
return(0);
}
}
return( _add( 0, argv, arg, (char far *)NULL, pass) ); /* no match */
}
static int
_add(length, argv, arg, prfxstr, pass )
int length;
char ***argv;
char far *arg;
char far *prfxstr;
{
int argln = 1, prfln = 0;
char far *argcnt = arg, far *prfcnt = prfxstr;
while ( *argcnt )
{
argln++;
argcnt++;
}
while ( *prfcnt )
{
prfln++;
prfcnt++;
}
if ( pass == 1 )
{
__argc++;
__argl += argln + length;
}
else /* pass 2 actually build the arg */
{
if ( length )
_hmmcpy( (char *)**argv, (char far *)prfxstr, prfln );
_hmmcpy( (char *)**argv + length, arg, argln );
(*argv)++;
**argv = (char *)(*(*argv - 1) + argln + length);
}
return(0);
}
static
_sort (first)
char **first;
{
char *temp, **last;
if (!*first)
return;
while (*first) {
last = first;
while (*++last) {
if (strcmp(*last, *first) < 0) {
temp = *first;
*first = *last;
*last = temp;
}
}
++first;
}
}

122
Microsoft C v4/_WILD.ASM Normal file
View File

@ -0,0 +1,122 @@
; _wild.asm
;
; helper routines for wildcard expansion
; contains __find, __setdta
;
title _wild
include version.inc
.xlist
include cmacros.inc
include msdos.inc
.list
sBegin data
assumes ds,data
res db 21 dup (0)
attr db 0
time dw 0
date dw 0
sizel dw 0
sizeh dw 0
_name db 13 dup (0)
sEnd
sBegin code
assumes cs,code
assumes ds,data
;*************
; __find (dir)
; char *dir;
;
; get an entry from the directory. if dir is NULL, we've already been called
; before, so get the next entry from the directory. return NULL if there aren't
; any more
cProc _hfind,<PUBLIC>,<ds>
parmD dirfar
cBegin
mov ds,SEG_dirfar;
mov dx,OFF_dirfar;
jmp short entrypoint
cEnd nogen
cProc _find,<PUBLIC>,<ds>
parmdp dir
cBegin
if sizeD
lds dx,dir
mov cx,ds
or cx,cx
jnz first
else
mov dx,dir
endif
entrypoint:
or dx,dx
jz notfirst
first:
mov cx,11h ; get directories and read-only files too
mov ah,DOS_findfirst
jmp short doint
notfirst:
mov ah,DOS_findnext
doint:
callos
jnc retname
xor ax,ax
if sizeD
mov dx,ax
endif
jmp short toend
retname:
mov ax,dataOFFSET _name
if sizeD
mov dx,ss
endif
toend:
cEnd <>,<>,<ds>
;************
; __setdta ()
;
; set the disk transfer address to our template
cProc _setdta,<PUBLIC>,<>
cBegin
push ds
mov ax,ss
mov ds,ax
mov dx,dataOFFSET res
callos setdma
pop ds
pop bp
ret
cEnd nogen
sEnd
end

View File

@ -0,0 +1,23 @@
/*
* assert.h
*
* defines the assert macro.
*
* Copyright (C) Microsoft Corporation, 1984, 1985, 1986
*
*/
#ifndef NDEBUG
#define assert(exp) { \
if (!(exp)) { \
fprintf(stderr,"Assertion failed: file %s, line %d\n", __FILE__, __LINE__); \
exit(1); \
} \
}
#else
#define assert(exp)
#endif /* NDEBUG */

View File

@ -0,0 +1,63 @@
/*
* conio.h
*
* This include file contains the function declarations for the MS C V2.03
* compatable console and port IO routines
*
* Copyright (C) Microsoft Corporation, 1984, 1985, 1986
*
*/
/* function declarations for those who want strong type checking
* on arguments to library function calls
*/
#ifdef LINT_ARGS /* argument checking enabled */
#ifndef NO_EXT_KEYS /* extended keywords are enabled */
char * cdecl cgets(char *);
int cdecl cprintf(char *, ...);
void cdecl cputs(char *);
int cdecl cscanf(char *, ...);
int cdecl getch(void);
int cdecl getche(void);
int cdecl inp(unsigned int);
int cdecl kbhit(void);
int cdecl outp(unsigned int, int);
void cdecl putch(int);
int cdecl ungetch(int);
#else /* extended keywords not enabled */
char *cgets(char *);
int cprintf(char *, ...);
void cputs(char *);
int cscanf(char *, ...);
int getch(void);
int getche(void);
int inp(unsigned int);
int kbhit(void);
int outp(unsigned int, int);
void putch(int);
int ungetch(int);
#endif /* NO_EXT_KEYS */
#else
#ifndef NO_EXT_KEYS /* extended keywords are enabled */
char * cdecl cgets();
int cdecl cprintf();
void cdecl cputs();
int cdecl cscanf();
int cdecl getch();
int cdecl getche();
int cdecl inp();
int cdecl kbhit();
int cdecl outp();
void cdecl putch();
int cdecl ungetch();
#else /* extended keywords not enabled */
char *cgets();
void cputs();
void putch();
#endif /* NO_EXT_KEYS */
#endif /* LINT_ARGS */

View File

@ -0,0 +1,57 @@
/*
* ctype.h
*
* defines the ctype macros as well as the character conversion macros
* (toupper, etc).
*
* Copyright (C) Microsoft Corporation, 1984, 1985, 1986
*
*/
/*
* This declaration allows the user access to the ctype lookup array _ctype
* defined in ctype.o by simply including ctype.h
*/
#ifndef NO_EXT_KEYS /* extended keywords are enabled */
extern unsigned char cdecl _ctype_[];
extern unsigned char cdecl _ctype[];
#else /* extended keywords not enabled */
extern unsigned char _ctype_[];
extern unsigned char _ctype[];
#endif /* NO_EXT_KEYS */
/* set bit masks for the possible character types */
#define _UPPER 0x1 /* upper case letter */
#define _LOWER 0x2 /* lower case letter */
#define _DIGIT 0x4 /* digit[0-9] */
#define _SPACE 0x8 /* tab, carriage return, new line,
* vertical tab or form feed
*/
#define _PUNCT 0x10 /* punctuation character */
#define _CONTROL 0x20 /* control character */
#define _BLANK 0x40 /* space char */
#define _HEX 0x80 /* hexadecimal digit */
/* the macro definitions of the functions */
#define isalpha(c) ( (_ctype+1)[c] & (_UPPER|_LOWER) )
#define isupper(c) ( (_ctype+1)[c] & _UPPER )
#define islower(c) ( (_ctype+1)[c] & _LOWER )
#define isdigit(c) ( (_ctype+1)[c] & _DIGIT )
#define isxdigit(c) ( (_ctype+1)[c] & _HEX )
#define isspace(c) ( (_ctype+1)[c] & _SPACE )
#define ispunct(c) ( (_ctype+1)[c] & _PUNCT )
#define isalnum(c) ( (_ctype+1)[c] & (_UPPER|_LOWER|_DIGIT) )
#define isprint(c) ( (_ctype+1)[c] & (_BLANK|_PUNCT|_UPPER|_LOWER|_DIGIT) )
#define isgraph(c) ( (_ctype+1)[c] & (_PUNCT|_UPPER|_LOWER|_DIGIT) )
#define iscntrl(c) ( (_ctype+1)[c] & _CONTROL )
#define isascii(c) ( (unsigned)(c) < 0x80 )
#define _tolower(c) ( (c)-'A'+'a' )
#define _toupper(c) ( (c)-'a'+'A' )
#define toupper(c) ( (islower(c)) ? _toupper(c) : (c) )
#define tolower(c) ( (isupper(c)) ? _tolower(c) : (c) )
#define toascii(c) ( (c) & 0x7f )

Some files were not shown because too many files have changed in this diff Show More