borland turbo c v1

This commit is contained in:
davidly 2024-07-01 13:08:21 -07:00
parent 8fa92e847d
commit bbbda7d517
83 changed files with 7910 additions and 0 deletions

View File

@ -0,0 +1,35 @@
/* alloc.h
memory management functions and variables.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
int _Cdecl brk(char *addr);
void *_Cdecl calloc(unsigned nitems, unsigned size);
#if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
unsigned long _Cdecl coreleft(void);
#else
unsigned _Cdecl coreleft(void);
#endif
void _Cdecl free(void *block);
void *_Cdecl malloc(unsigned size);
void *_Cdecl realloc(void *block, unsigned size);
void *_Cdecl sbrk(int incr);
#if !__STDC__
void far * _Cdecl farcalloc(unsigned long nunits, unsigned long unitsz);
unsigned long _Cdecl farcoreleft(void);
void _Cdecl farfree(void far *block);
void far* _Cdecl farmalloc(unsigned long nbytes);
void far* _Cdecl farrealloc(void far* oldblock, unsigned long nbytes);
#endif


View File

@ -0,0 +1,16 @@
/* assert.h
assert macro
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if !defined(NDEBUG)
#define assert(p) if(!(p)){printf(\
"Assertion failed: file %s, line %d\n",\
__FILE__, __LINE__);exit(1);}
#else
#define assert(p)
#endif


138
Borland Turbo C v1/BAR.C Normal file
View File

@ -0,0 +1,138 @@
/* BAR.C
Sample program for interfacing Turbo C with Turbo Prolog
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#include <dos.h>
/* new prototype for _int86 */
int _int86(int intr_num, union REGS *inregs, union REGS *outregs);
videodot(int x, int y, int color)
{
union REGS inr,outr;
inr.h.ah = 12; /* write pixel */
inr.h.al = color;
inr.x.cx = x;
inr.x.dx = y;
_int86(16,&inr,&outr); /* call video intr */
}
/* Draws a line on the screen from (x1, y1) to (x2, y2) in a selected color */
line(int x1, int y1, int x2, int y2, int color)
{
int xdelta; /* The change in x coordinates */
int ydelta; /* The change in y coordinates */
int xstep; /* The change to make in the x coordinate in each step */
int ystep; /* The change to make in the y coordinate in each step */
int change; /* The amount that the x or y coordinate has changed */
xdelta = x2 - x1; /* Calculate the change in x coordinates */
ydelta = y2 - y1; /* Calculate the change in y coordinates */
if (xdelta < 0)
{ /* The line will be drawn from right to left */
xdelta = -xdelta;
xstep = -1;
}
else /* The line will be drawn from left to right */
xstep = 1;
if (ydelta < 0)
{ /* The line will be drawn from bottom to top */
ydelta = -ydelta;
ystep = -1;
}
else /* The line will be drawn from top to bottom */
ystep = 1;
if (xdelta > ydelta) /* x changes quicker than y */
{
change = xdelta >> 1; /* change set to twice the value of xdelta */
while (x1 != x2) /* Draw until the terminating dot is reached */
{
videodot(x1, y1, color); /* Draw a dot on the screen */
x1 += xstep; /* Update x coordinate */
change += ydelta; /* Update change */
if (change > xdelta)
/* If change is large enough to
update the y coordinate */
{
y1 += ystep; /* Update the y coordinate */
change -= xdelta; /* Reset change */
}
}
}
else /* y changes quicker than x */
{
change = ydelta >> 1; /* change set to twice the value of ydelta */
while (y1 != y2) /* Draw until the terminating dot is reached */
{
videodot(x1, y1, color); /* Draw a dot on the screen */
y1 += ystep; /* Update y coordinate */
change += xdelta; /* Update change */
if (change > ydelta)
/* If change is large enough to update the x coordinate */
{
x1 += xstep; /* Update the x coordinate */
change -= ydelta; /* Reset change */
}
}
}
} /* line */
bar_0(int x1, int y1, int width, int height, int color)
{
int count; /* Counter variable used in filling bar */
int x2, y2, x3, y3, x4, y4; /* Additional points on the bar */
int wfactor; /* The number of pixels to shift the bar to the right */
int hfactor; /* The number of pixels to shift the bar up */
/*
The x and y values are as follows:
x1 x2 x3 x4
| | | |
| v | v
y2--|>/ÚÄÄÄÄ|ÄÄ¿
v/ ³ v /³
y1->ÉÍÍÍÍÍÍÍ»/ ³
º ³ º ³
º ³ º ³
º ³ º ³
º ³ º ³
º ³ º ³
y3---->ÀÄÄÄĺÄÄÙ
º / º /
y4->ÈÍÍÍÍÍÍͼ/
*/
wfactor = width / 5; /* figure out wfactor and hfactor */
hfactor = height / 12;
x2 = x1 + wfactor; /* compute the location of the points on the bar */
x3 = x1 + width;
x4 = x3 + wfactor;
y2 = y1 - hfactor;
y3 = y1 + height - hfactor;
y4 = y1 + height;
line(x1, y1, x3, y1, 2); /* draw front of the bar */
line(x3, y1, x3, y4, 2);
line(x3, y4, x1, y4, 2);
line(x1, y4, x1, y1, 2);
line(x3, y1, x4, y2, 2); /* draw side of the bar */
line(x4, y2, x4, y3, 2);
line(x4, y3, x3, y4, 2);
line(x1, y1, x2, y2, 2); /* draw top of the bar */
line(x2, y2, x4, y2, 2);
line(x1, y4, x2, y3, 3);
line(x2, y3, x4, y3, 3); /* draw back of the bar */
line(x2, y3, x2, y2, 3);
for (count = y1 + 1; count < y4; count++) /* fill in the bar */
line(x1 + 1, count, x3, count, color);
} /* bar_0 */


22
Borland Turbo C v1/BIOS.H Normal file
View File

@ -0,0 +1,22 @@
/* bios.h
Access to bios services.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
int _Cdecl bioscom(int cmd, char abyte, int port);
int _Cdecl biosdisk(int cmd, int drive, int head, int track, int sector,
int nsects, void *buffer);
int _Cdecl biosequip(void);
int _Cdecl biosmemory(void);
long _Cdecl biostime(int cmd, long newtime);
int _Cdecl bioskey(int cmd);
int _Cdecl biosprint(int cmd, int abyte, int port);


View File

@ -0,0 +1,31 @@
echo off
if x%1 == xTINY goto ok
if x%1 == xSMALL goto ok
if x%1 == xCOMPACT goto ok
if x%1 == xMEDIUM goto ok
if x%1 == xLARGE goto ok
if x%1 == xHUGE goto ok
echo BUILD-C0 must have argument: TINY, SMALL, COMPACT, MEDIUM, LARGE or HUGE
goto done
:ok
echo on
goto make-%1
:make-TINY
MASM C0,C0T /D__TINY__ /MX;
goto done
:make-SMALL
MASM C0,C0S /D__SMALL__ /MX;
goto done
:make-COMPACT
MASM C0,C0C /D__COMPACT__ /MX;
goto done
:make-MEDIUM
MASM C0,C0M /D__MEDIUM__ /MX;
goto done
:make-LARGE
MASM C0,C0L /D__LARGE__ /MX;
goto done
:make-HUGE
MASM C0,C0H /D__HUGE__ /MX;
echo on
:done

450
Borland Turbo C v1/C0.ASM Normal file
View File

@ -0,0 +1,450 @@
NAME c0
PAGE 60,132
;[]------------------------------------------------------------[]
;| C0.ASM -- Start Up Code |
;| |
;| Turbo-C Run Time Library version 1.0 |
;| |
;| Copyright (c) 1987 by Borland International Inc. |
;| All Rights Reserved. |
;[]------------------------------------------------------------[]
INCLUDE RULES.ASI
; Segment and Group declarations
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT PARA PUBLIC 'DATA'
_DATA ENDS
_EMUSEG SEGMENT WORD PUBLIC 'DATA'
_EMUSEG ENDS
_CVTSEG SEGMENT WORD PUBLIC 'DATA'
_CVTSEG ENDS
_SCNSEG SEGMENT WORD PUBLIC 'DATA'
_SCNSEG ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
_BSSEND SEGMENT BYTE PUBLIC 'BSSEND'
_BSSEND ENDS
IFNDEF __TINY__
_STACK SEGMENT STACK 'STACK'
_STACK ENDS
ENDIF
IF LDATA
DGROUP GROUP _DATA, _EMUSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND
ELSE
IFNDEF __TINY__
DGROUP GROUP _DATA, _EMUSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND, _STACK
ELSE
DGROUP GROUP _TEXT, _DATA, _EMUSEG, _CVTSEG, _SCNSEG, _BSS, _BSSEND
ENDIF
ENDIF
ASSUME CS:_TEXT, DS:DGROUP
; External References
ExtProc@ main, __CDECL__
ExtProc@ _setargv, __CDECL__
ExtProc@ _setenvp, __CDECL__
ExtProc@ exit, __CDECL__
ExtSym@ _stklen, WORD, __CDECL__
ExtSym@ _emufak, ABS, __CDECL__
SUBTTL Start Up Code
PAGE
;/* */
;/*-----------------------------------------------------*/
;/* */
;/* Start Up Code */
;/* ------------- */
;/* */
;/*-----------------------------------------------------*/
;/* */
PSPHigh equ 00002h
PSPEnv equ 0002ch
PSPCmd equ 00080h
MINSTACK equ 128
;
; At the start, DS and ES both point to the segment prefix.
; SS points to the stack segment except in TINY model where
; SS is equal to CS
;
_TEXT SEGMENT
IFDEF __TINY__
ORG 100h
ENDIF
STARTX PROC NEAR
; Sometimes the compiler needs to load the DS register with the
; DGROUP value. In TINY model the DGROUP symbol cannot appear,
; otherwise it becomes impossible to EXE2BIN the .EXE file. For this
; reason, the DGROUP is saved in a variable of the code segment.
IFDEF __TINY__
mov dx, cs ; DX = GROUP Segment address
ELSE
mov dx, DGROUP ; DX = GROUP Segment address
ENDIF
mov cs:DGROUP@@, dx
; Save general information, such as :
; DOS version number
; Program Segment Prefix
; Environment address
; Top of far heap
mov ah, 30h
int 21h
mov bp, ds:[PSPHigh]; BP = Highest Memory Segment Addr
mov bx, ds:[PSPEnv] ; BX = Environment Segment address
mov ds, dx
mov _version@, ax ; Keep major and minor version number
mov _psp@, es ; Keep Program Segment Prefix address
mov _envseg@, bx ; Keep Environment Segment address
mov word ptr _heaptop@ + 2, bp
mov _8087@, -1
; Look for a '87' environment variable, and use this loop to
; count the number of environment variables and to compute the
; environment size.
; Each variable is ended by a 0 and a zero-length variable stops
; the environment. The environment can NOT be greater than 32k.
mov es, bx
xor ax, ax
mov cx, 07FFFh ; Environment cannot be > 32 Kbytes
mov di, ax
mov bx, ax
IsIt87Var label near
cmp word ptr es:[di], '78'
jne GetEnvLng
mov dx, es:[di+2]
cmp dl, '='
jne GetEnvLng
and dh, not ' '
inc _8087@
cmp dh, 'Y'
jne GetEnvLng
inc _8087@
GetEnvLng label near
repnz scasb
jcxz InitFailed ; Bad environment !!!
inc bx ; BX = Nb environment variables
cmp es:[di], al
jne IsIt87Var ; Next variable ...
or ch, 10000000b
neg cx
mov _envLng@, cx ; Save Environment size
add bx, 7
and bx, not 3
shl bx, 1
IF LDATA
shl bx, 1
ENDIF
mov _envSize@, bx ; Save Environment Variables Nb.
; Capture "Divide overflow" interrupt
push ds
mov ax, 03500h
int 021h
mov word ptr ZeroDivVector, bx
mov word ptr ZeroDivVector+2, es
mov ax, 02500h
push cs
pop ds
mov dx, offset ZeroDivision
int 021h
pop ds
; Install floating point software
IFNDEF __NOFLOAT
push cs
call word ptr ds:[__emu1st]
ENDIF
; Adjust _stklen if necessary
IFDEF __HUGE__
mov di, seg _stklen@
mov es, di
mov di, es:_stklen@
ELSE
mov di, _stklen@
ENDIF
mov bx, MINSTACK * 2
cmp di, bx
ja _stklenOk
mov di, bx
_stklenOk label near
; Determine the amount of memory that we need to keep
IF LDATA
mov dx, ss
mov cl, 4
shr di, cl ; $$$ Do not destroy CL $$$
inc di ; DI = Stack size in paragraphs
ELSE
mov dx, ds
add bx, offset DGROUP: edata@
jb InitFailed ; STACK could not be > 64 Kbytes
mov di, 1000h ; DI = Stack size in paragraphs
mov cl, 4
ENDIF
shr bx, cl ; $$$ Do not destroy CL $$$
inc bx ; MINIMUM needed
sub bp, dx
cmp bp, di
ja ExcessOfMemory ; Much more available than needed
xchg bx, di
cmp bp, di
ja ExcessOfMemory ; Enough to run the program
; All initialization errors arrive here
InitFailed label near
jmp near ptr abort@
; Return to DOS the amount of memory in excess
; Set far heap base and pointer
ExcessOfMemory label near
mov bx, di
add bx, dx
mov word ptr _heapbase@ + 2, bx
mov word ptr _brklvl@ + 2, bx
mov ax, _psp@
sub bx, ax ; BX = Number of paragraphs to keep
mov es, ax ; ES = Program Segment Prefix address
mov ah, 04Ah
int 021h
; Set the program stack
shl di, cl ; $$$ CX is still equal to 4 $$$
IF LDATA EQ false
mov ss, dx
ENDIF
mov sp, di
; Prepare main arguments
call _setargv@
call _setenvp@
IFNDEF __HUGE__
; Reset un-initialized datas
xor ax, ax
mov es, cs:DGROUP@@
mov di, offset DGROUP: bdata@
mov cx, offset DGROUP: edata@
sub cx, di
rep stosb
ENDIF
; ExitCode = main(argc,argv,envp);
IF LDATA
push word ptr environ@+2
push word ptr environ@
push word ptr __argv@+2
push word ptr __argv@
ELSE
push word ptr environ@
push word ptr __argv@
ENDIF
push __argc@
call main@
; Flush and close streams and files
push ax
call exit@
; Restore "Divide overflow" interrupt vector
PubProc@ _exit, __CDECL__
mov ax, 2500h
lds dx, ZeroDivVector
int 021h
; Set DS to DGROUP
mov ds, cs:DGROUP@@
; Restore interrupt vectors taken by __emu1st
IFNDEF __NOFLOAT
push cs ;Simulation of a FAR call
call word ptr ds:[__emuLast]
ENDIF
IF LDATA EQ false
IFNDEF __TINY__
; Check for null pointers before exit
xor ax, ax
mov si, ax
mov cx, lgth_CopyRight
cld
ComputeChecksum label near
add al, [si]
adc ah, 0
inc si
loop ComputeChecksum
sub ax, CheckSum
jz ExitToDOS
mov cx, lgth_NullCheck
mov dx, offset DGROUP: NullCheck
call ErrorDisplay
ENDIF
ENDIF
; Exit to DOS
ExitToDOS label near
mov bp,sp
IF LPROG
mov al,[bp+4]
ELSE
mov al,[bp+2]
ENDIF
mov ah,4Ch
int 21h ; Exit to DOS
EndProc@ _exit, __CDECL__
STARTX ENDP
SUBTTL Miscellaneous
PAGE
;[]------------------------------------------------------------[]
;| |
;| Miscellaneous functions |
;| |
;[]------------------------------------------------------------[]
ErrorDisplay PROC NEAR
mov ah, 040h
mov bx, 2
mov ds, cs: DGROUP@@
int 021h
ret
ErrorDisplay ENDP
PubProc@ abort, __CDECL__
mov cx, lgth_abortMSG
mov dx, offset DGROUP: abortMSG
call ErrorDisplay
CallExit3 label near
mov ax, 3
push ax
call _exit@ ; _exit(3);
EndProc@ abort, __CDECL__
ZeroDivision PROC FAR
mov cx, lgth_ZeroDivMSG
mov dx, offset DGROUP: ZeroDivMSG
call ErrorDisplay
jmp short CallExit3
ZeroDivision ENDP
; The DGROUP@ variable is used to reaload DS with DGROUP
PubSym@ DGROUP@, <dw ?>, __PASCAL__
_TEXT ENDS
SUBTTL Start Up Datas
PAGE
;/* */
;/*-----------------------------------------------------*/
;/* */
;/* Start Up Data */
;/* -------------- */
;/* */
;/*-----------------------------------------------------*/
;/* */
_DATA SEGMENT
; The CopyRight string must NOT be moved or changed without
; changing the null pointer check logic
CopyRight db 4 dup(0)
db 'Turbo-C - Copyright (c) 1987 Borland Intl.',0
lgth_CopyRight equ $ - CopyRight
IF LDATA EQ false
IFNDEF __TINY__
Checksum equ 00D36h
nullCheck db 'Null pointer assignment', 13, 10
lgth_nullCheck equ $ - nullCheck
ENDIF
ENDIF
ZeroDivMSG db 'Divide error', 13, 10
lgth_ZeroDivMSG equ $ - ZeroDivMSG
abortMSG db 'Abnormal program termination', 13, 10
lgth_abortMSG equ $ - abortMSG
; Miscellaneous variables
ZeroDivVector dd 0
PubSym@ __argc, <dw 0>, __CDECL__
dPtrPub@ __argv, 0, __CDECL__
dPtrPub@ environ, 0, __CDECL__
PubSym@ _envLng, <dw 0>, __CDECL__
PubSym@ _envseg, <dw 0>, __CDECL__
PubSym@ _envSize, <dw 0>, __CDECL__
PubSym@ _psp, <dw 0>, __CDECL__
PubSym@ _version, <label word>, __CDECL__
PubSym@ _osmajor, <db 0>, __CDECL__
PubSym@ _osminor, <db 0>, __CDECL__
PubSym@ errno, <dw 0>, __CDECL__
PubSym@ _8087, <dw 0>, __CDECL__
; Memory management variables
IF LDATA EQ false
dPtrPub@ __brklvl, DGROUP:edata@, __CDECL__
ENDIF
PubSym@ _heapbase, <dd 0>, __CDECL__
PubSym@ _brklvl, <dd 0>, __CDECL__
PubSym@ _heaptop, <dd 0>, __CDECL__
_DATA ENDS
_EMUSEG SEGMENT
__emu1st label word
__emuLast equ __emu1st + 2
_EMUSEG ENDS
_CVTSEG SEGMENT
PubSym@ _RealCvtVector, <label word>, __CDECL__
_CVTSEG ENDS
_SCNSEG SEGMENT
PubSym@ _ScanTodVector, <label word>, __CDECL__
_SCNSEG ENDS
_BSS SEGMENT
bdata@ label byte
_BSS ENDS
_BSSEND SEGMENT
edata@ label byte
_BSSEND ENDS
IFNDEF __TINY__
_STACK SEGMENT
dw 64 dup (?)
_STACK ENDS
ENDIF
END STARTX

BIN
Borland Turbo C v1/C0C.OBJ Normal file

Binary file not shown.

BIN
Borland Turbo C v1/C0H.OBJ Normal file

Binary file not shown.

BIN
Borland Turbo C v1/C0L.OBJ Normal file

Binary file not shown.

BIN
Borland Turbo C v1/C0M.OBJ Normal file

Binary file not shown.

BIN
Borland Turbo C v1/C0S.OBJ Normal file

Binary file not shown.

BIN
Borland Turbo C v1/C0T.OBJ Normal file

Binary file not shown.

BIN
Borland Turbo C v1/CC.LIB Normal file

Binary file not shown.

BIN
Borland Turbo C v1/CH.LIB Normal file

Binary file not shown.

BIN
Borland Turbo C v1/CL.LIB Normal file

Binary file not shown.

BIN
Borland Turbo C v1/CM.LIB Normal file

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,24 @@
/* conio.h
Direct MSDOS console input/output.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
char *_Cdecl cgets(char *str);
void _Cdecl cputs(char *str);
int _Cdecl cprintf(char *format, ...);
int _Cdecl cscanf(char *format, ...);
int _Cdecl getch(void);
int _Cdecl getche(void);
char *_Cdecl getpass(char *prompt);
int _Cdecl kbhit(void);
int _Cdecl putch(int ch);
int _Cdecl ungetch(unsigned ch);


Binary file not shown.

BIN
Borland Turbo C v1/CPP.EXE Normal file

Binary file not shown.

BIN
Borland Turbo C v1/CS.LIB Normal file

Binary file not shown.

View File

@ -0,0 +1,46 @@
/* ctype.h
Defines the ctype macros.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _CTYPE
#define _CTYPE
#define IS_SP 1 /* is space */
#define IS_DIG 2 /* is digit indicator */
#define IS_UPP 4 /* is upper case */
#define IS_LOW 8 /* is lower case */
#define IS_HEX 16 /* [A-F or [a-f] */
#define IS_CTL 32 /* Control */
#define IS_PUN 64 /* punctuation */
extern char _Cdecl _ctype[]; /* Character type array */
#define isalpha(c) (_ctype[(c) + 1] & (IS_UPP | IS_LOW))
#define isdigit(c) (_ctype[(c) + 1] & IS_DIG)
#define isspace(c) (_ctype[(c) + 1] & IS_SP)
#define isupper(c) (_ctype[(c) + 1] & IS_UPP)
#define islower(c) (_ctype[(c) + 1] & IS_LOW)
#define isxdigit(c) (_ctype[(c) + 1] & (IS_DIG | IS_HEX))
#define isalnum(c) (_ctype[(c) + 1] & (IS_DIG | IS_UPP | IS_LOW))
#define iscntrl(c) (_ctype[(c) + 1] & IS_CTL)
#define ispunct(c) (_ctype[(c) + 1] & IS_PUN)
#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e)
#define isgraph(c) ((c) >= 0x21 && (c) <= 0x7e)
#define _toupper(c) ((c) + 'A' - 'a')
#define _tolower(c) ((c) + 'a' - 'A')
#define toascii(c) ((c) & 0x7f)
#define isascii(c) ((unsigned)((c) + 1) < 0x81)
int _Cdecl tolower(int ch);
int _Cdecl toupper(int ch);
#endif


52
Borland Turbo C v1/DIR.H Normal file
View File

@ -0,0 +1,52 @@
/* dir.h
Defines structures, macros, and functions for dealing with
directories and pathnames.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
int _Cdecl chdir(char *path);
int _Cdecl getcurdir(int drive, char *directory);
char *_Cdecl getcwd(char *bufP, int bufL);
int _Cdecl getdisk(void);
int _Cdecl mkdir(char *path);
char *_Cdecl mktemp(char *template);
int _Cdecl rmdir(char *path);
char *_Cdecl searchpath(char *file);
int _Cdecl setdisk(int drive);
struct ffblk {
char ff_reserved[21];
char ff_attrib;
unsigned ff_ftime;
unsigned ff_fdate;
long ff_fsize;
char ff_name[13];
};
int _Cdecl findfirst(char *pathname, struct ffblk *ffblk, int attrib);
int _Cdecl findnext(struct ffblk *ffblk);
#define WILDCARDS 0x01
#define EXTENSION 0x02
#define FILENAME 0x04
#define DIRECTORY 0x08
#define DRIVE 0x10
#define MAXPATH 80
#define MAXDRIVE 3
#define MAXDIR 66
#define MAXFILE 9
#define MAXEXT 5
int _Cdecl fnsplit(char *path,char *drive,char *dir,char *name,char *ext);
void _Cdecl fnmerge(char *path,char *drive,char *dir,char *name,char *ext);


243
Borland Turbo C v1/DOS.H Normal file
View File

@ -0,0 +1,243 @@
/* dos.h
Defines structs, unions, macros, and functions for dealing
with MSDOS and the Intel iAPX86 microprocessor family.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
/* Variables */
extern unsigned int _Cdecl _psp;
extern char **_Cdecl environ;
extern unsigned int _Cdecl _version;
extern unsigned char _Cdecl _osmajor;
extern unsigned char _Cdecl _osminor;
extern int _Cdecl _doserrno;
#define FA_RDONLY 0x01 /* Read only attribute */
#define FA_HIDDEN 0x02 /* Hidden file */
#define FA_SYSTEM 0x04 /* System file */
#define FA_LABEL 0x08 /* Volume label */
#define FA_DIREC 0x10 /* Directory */
#define FA_ARCH 0x20 /* Archive */
#define NFDS 20 /* Maximum number of fds */
struct fcb {
char fcb_drive; /* 0 = default, 1 = A, 2 = B */
char fcb_name[8]; /* File name */
char fcb_ext[3]; /* File extension */
short fcb_curblk; /* Current block number */
short fcb_recsize; /* Logical record size in bytes */
long fcb_filsize; /* File size in bytes */
short fcb_date; /* Date file was last written */
char fcb_resv[10]; /* Reserved for DOS */
char fcb_currec; /* Current record in block */
long fcb_random; /* Random record number */
};
struct xfcb {
char xfcb_flag; /* Contains 0xff to indicate xfcb */
char xfcb_resv[5]; /* Reserved for DOS */
char xfcb_attr; /* Search attribute */
struct fcb xfcb_fcb; /* The standard fcb */
};
struct country {
int co_date;
char co_curr[5];
char co_thsep[2];
char co_desep[2];
char co_dtsep[2];
char co_tmsep[2];
char co_currstyle;
char co_digits;
long co_case;
char co_dasep;
char co_fill[10];
};
struct DOSERROR {
int exterror;
char class;
char action;
char locus;
};
struct dfree {
unsigned df_avail;
unsigned df_total;
unsigned df_bsec;
unsigned df_sclus;
};
struct fatinfo {
char fi_sclus;
char fi_fatid;
int fi_nclus;
int fi_bysec;
};
struct devhdr {
long dh_next; /* Next device pointer */
short dh_attr; /* Attributes */
unsigned short dh_strat; /* Driver strategy routine */
unsigned short dh_inter; /* Driver interrupt routine */
char dh_name[8]; /* Device name */
};
struct time {
unsigned char ti_min; /* Minutes */
unsigned char ti_hour; /* Hours */
unsigned char ti_hund; /* Hundredths of seconds */
unsigned char ti_sec; /* Seconds */
};
struct date {
int da_year; /* Year - 1980 */
char da_day; /* Day of the month */
char da_mon; /* Month (1 = Jan) */
};
struct WORDREGS
{
unsigned int ax, bx, cx, dx, si, di, cflag, flags;
};
struct BYTEREGS
{
unsigned char al, ah, bl, bh, cl, ch, dl, dh;
};
union REGS {
struct WORDREGS x;
struct BYTEREGS h;
};
struct SREGS {
unsigned int es;
unsigned int cs;
unsigned int ss;
unsigned int ds;
};
struct REGPACK
{
unsigned r_ax, r_bx, r_cx, r_dx;
unsigned r_bp, r_si, r_di, r_ds, r_es, r_flags;
};
#define FP_OFF(fp) ((unsigned)(fp))
#define FP_SEG(fp) ((unsigned)((unsigned long)(fp) >> 16))
typedef struct
{
char drive; /* do not change */
char pattern [13]; /* these fields, */
char reserved [7]; /* Microsoft reserved */
char attrib;
short time;
short date;
long size;
char nameZ [13]; /* result of the search, asciiz */
}
dosSearchInfo; /* used with DOS functions 4E, 4F */
int _Cdecl absread(int drive, int nsects, int lsect, void *buffer);
int _Cdecl abswrite(int drive, int nsects, int lsect, void *buffer);
int _Cdecl allocmem(unsigned size, unsigned *segp);
int _Cdecl bdos(int dosfun, unsigned dosdx, unsigned dosal);
int _Cdecl bdosptr(int dosfun, void *argument, unsigned dosal);
struct country *_Cdecl country(int xcode, struct country *cp);
void _Cdecl ctrlbrk(int (*fptr)(void));
int _Cdecl dosexterr(struct DOSERROR *eblkp);
long _Cdecl dostounix(struct date *d, struct time *t);
int _Cdecl freemem(unsigned segx);
int _Cdecl getcbrk(void);
void _Cdecl getdate(struct date *datep);
int _Cdecl getdfree(unsigned char drive, struct dfree *dtable);
int _Cdecl getfat(unsigned char drive, struct fatinfo *dtable);
int _Cdecl getfatd(struct fatinfo *dtable);
unsigned _Cdecl getpsp(void);
int _Cdecl getswitchar(void);
void _Cdecl gettime(struct time *timep);
void interrupt (* _Cdecl getvect(int interruptno)) ();
int _Cdecl getverify(void);
void _Cdecl harderr(int _Cdecl (*fptr)());
void _Cdecl hardresume(int axret);
int _Cdecl hardretn(int retn);
int _Cdecl int86(int intno, union REGS *inregs, union REGS *outregs);
int _Cdecl int86x(int intno, union REGS *inregs, union REGS *outregs,
struct SREGS *segregs);
int _Cdecl intdos(union REGS *inregs, union REGS *outregs);
int _Cdecl intdosx(union REGS *inregs, union REGS *outregs,
struct SREGS *segregs);
void _Cdecl intr(int int_type, struct REGPACK *preg);
void _Cdecl keep(unsigned char status, unsigned size);
char *_Cdecl parsfnm(char *cmdline, struct fcb *fcb, unsigned char opt);
int _Cdecl randbrd(struct fcb *fcb, int rcnt);
int _Cdecl randbwr(struct fcb *fcb, int rcnt);
void _Cdecl segread(struct SREGS *segp);
int _Cdecl setblock(unsigned segx, unsigned newsize);
int _Cdecl setcbrk(int cbrkvalue);
void _Cdecl setdate(struct date *datep);
void _Cdecl setswitchar(char ch);
void _Cdecl settime(struct time *timep);
void _Cdecl setvect(int interruptno, void interrupt (*isr) ());
int _Cdecl setverify(int value);
void _Cdecl sleep(unsigned seconds);
void _Cdecl unixtodos(long time, struct date *d, struct time *t);
int _Cdecl unlink(char *filename);
int _Cdecl peek(unsigned segment, unsigned offset);
void _Cdecl poke(unsigned segment, unsigned offset, int value);
int _Cdecl peekb(unsigned segment, unsigned offset);
void _Cdecl pokeb(unsigned segment, unsigned offset, char value);
int _Cdecl inport(int portid);
int _Cdecl inportb(int portid);
void _Cdecl outport(int portid, int value);
void _Cdecl outportb(int portid, char value);
void _Cdecl disable(void);
void _Cdecl enable(void);
/* These are in-line functions. These prototypes just clean up
some syntax checks and code generation.
*/
void __cli__(void);
void __sti__(void);
unsigned char __inportb__(int portid);
void __outportb__(int portid, char value);
void __int__(int interruptnum);
#define disable() __cli__() /* Clear interrupt flag */
#define enable() __sti__() /* Set interrupt flag */
#define inportb(portid) __inportb__(portid) /* Byte IN instruction */
#define outportb(portid, v) __outportb__(portid,v)/* Byte OUT instruction */
#define geninterrupt(i) __int__(i) /* Interrupt instruction */
/* some other compilers use inp, outp for inportb, outportb */
#define inp(portid) inportb(portid)
#define outp(portid,v) outportb(portid,v)
#if !__STDC__
char far *cdecl getdta(void);
void cdecl setdta(char far *dta);
#define MK_FP(seg,ofs) ((void far *)(((unsigned long)(seg) << 16) | (ofs)))
#define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c))
#define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c))
#define peek(a,b) (*((int far*)MK_FP((a),(b))))
#define peekb(a,b) (*((char far*)MK_FP((a),(b))))
#endif


35
Borland Turbo C v1/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 main() {
int N = DIGITS_TO_FIND;
int x = 0;
int a[ DIGITS_TO_FIND ];
int n;
for (n = N - 1; n > 0; --n) {
a[n] = 1;
}
a[1] = 2, a[0] = 0;
while (N > 9) {
n = N--;
while (--n) {
a[n] = x % n;
x = 10 * a[n-1] + x/n;
}
printf("%d", x);
}
printf( "\ndone\n" );
return 0;
}

BIN
Borland Turbo C v1/EMU.LIB Normal file

Binary file not shown.

View File

@ -0,0 +1,77 @@
/* errno.h
Defines the system error variable errno and the error
numbers set by system calls. Errors which exist in Unix(tm)
but not MSDOS have value 0.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
/* Dos Error Codes */
#define EZERO 0 /* Error 0 */
#define EINVFNC 1 /* Invalid function number */
#define ENOFILE 2 /* File not found */
#define ENOPATH 3 /* Path not found */
#define ECONTR 7 /* Memory blocks destroyed */
#define EINVMEM 9 /* Invalid memory block address */
#define EINVENV 10 /* Invalid environment */
#define EINVFMT 11 /* Invalid format */
#define EINVACC 12 /* Invalid access code */
#define EINVDAT 13 /* Invalid data */
#define EINVDRV 15 /* Invalid drive specified */
#define ECURDIR 16 /* Attempt to remove CurDir */
#define ENOTSAM 17 /* Not same device */
#define ENMFILE 18 /* No more files */
#define ENOENT 2 /* No such file or directory */
#define EMFILE 4 /* Too many open files */
#define EACCES 5 /* Permission denied */
#define EBADF 6 /* Bad file number */
#define ENOMEM 8 /* Not enough core */
#define ENODEV 15 /* No such device */
#define EINVAL 19 /* Invalid argument */
#define E2BIG 20 /* Arg list too long */
#define ENOEXEC 21 /* Exec format error */
#define EXDEV 22 /* Cross-device link */
#define EDOM 33 /* Math argument */
#define ERANGE 34 /* Result too large */
#define EFAULT -1 /* Unknown error */
#define EPERM -1 /* UNIX - not MSDOS */
#define ESRCH -1 /* UNIX - not MSDOS */
#define EINTR -1 /* UNIX - not MSDOS */
#define EIO -1 /* UNIX - not MSDOS */
#define ENXIO -1 /* UNIX - not MSDOS */
#define ECHILD -1 /* UNIX - not MSDOS */
#define EAGAIN -1 /* UNIX - not MSDOS */
#define ENOTBLK -1 /* UNIX - not MSDOS */
#define EBUSY -1 /* UNIX - not MSDOS */
#define EEXIST -1 /* UNIX - not MSDOS */
#define ENOTDIR -1 /* UNIX - not MSDOS */
#define EISDIR -1 /* UNIX - not MSDOS */
#define ENFILE -1 /* UNIX - not MSDOS */
#define ENOTTY -1 /* UNIX - not MSDOS */
#define ETXTBSY -1 /* UNIX - not MSDOS */
#define EFBIG -1 /* UNIX - not MSDOS */
#define ENOSPC -1 /* UNIX - not MSDOS */
#define ESPIPE -1 /* UNIX - not MSDOS */
#define EROFS -1 /* UNIX - not MSDOS */
#define EMLINK -1 /* UNIX - not MSDOS */
#define EPIPE -1 /* UNIX - not MSDOS */
#define EUCLEAN -1 /* UNIX - not MSDOS */
#define _sys_nerr 34 /* highest defined system error number */
extern int _Cdecl errno;
extern int _Cdecl _doserrno;


View File

@ -0,0 +1,43 @@
/* fcntl.h
Define flag values accessible to open.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
extern unsigned _Cdecl _fmode;
/* The first three can only be set by open */
#define O_RDONLY 1
#define O_WRONLY 2
#define O_RDWR 4
/* Flag values for open only */
#define O_CREAT 0x0100 /* create and open file */
#define O_TRUNC 0x0200 /* open with truncation */
#define O_EXCL 0x0400 /* exclusive open */
#define O_APPEND 0x0800 /* to end of file */
/* MSDOS special bits */
#define O_CHANGED 0x1000 /* user may read these bits, but */
#define O_DEVICE 0x2000 /* only RTL\io functions may touch. */
#define O_TEXT 0x4000 /* CR-LF translation */
#define O_BINARY 0x8000 /* no translation */
/* DOS 3.x options */
#define O_NOINHERIT 0x80
#define O_DENYALL 0x10
#define O_DENYWRITE 0x20
#define O_DENYREAD 0x30
#define O_DENYNONE 0x40


View File

@ -0,0 +1,451 @@
/* FILECOMP.C
file compare program, similar to unix diff
Copyright (c) Borland International 1987
All Rights Reserved.
*/
/**********************************************************************
The FILECOMP program implements Paul Heckel's algorithm from the
Communications of the Association for Computing Machinery,
April 1978 for detecting the differences between two files. This
algorithm has the advantage over more commonly used compare
algorithms that it is fast and can detect differences of an
arbitrary number of lines. It has the defect that it reads both
files twice if there are differences.
It uses getopt to parse command line options.
Compile with Turbo C,
tcc -O -Z filecomp getopt
You may also use the -p (pascal) option.
The command format is: FILECOMP [options] filespec1 filespec2
Options:
/f show full lines.
/t expand tabs before comparing.
/b ignore trailing blanks.
/w ignore spaces and tabs.
/y case insensitive compare.
Defaults are:
Brief show first 34 characters of lines.
No tabs don't expand tabs.
No trim don't ignore trailing blanks.
White compare spaces and tabs.
Case case sensitive compare.
Arbitrary path qualification is allowed in the filespecs. In addition,
the output can be redirected to the printer or a file with normal DOS
redirection conventions (e. g. >PRN).
By default (Brief), output is displayed with the two files side-by-side.
This is felt to make it easier to spot the location of differences, even
though only 34 characters of each record can be shown. The Full option
causes the whole record to be shown. Along with each record displayed is
its line number in the file it came from.
If either file contains tabs, they will not be expanded before
comparison unless the Tabs option is used. If Tabs is not used, any tabs
in displayed records will probably make the output appear strange, since
they will be expanded by DOS.
A design limitation of the program is that only the first 256
characters of each record are compared.
**********************************************************************/
#include <stdio.h>
#include <ctype.h> /* for toupper */
#include <string.h> /* for strcpy, strupr */
#define MAXLINES 5000
#define FULL 0x80
#define TABS 0x40
#define TRIM 0x20
#define WHITE 0x10
#define CASE 0x08
#define BLANK 0x04
#define TRUE 1
#define FALSE 0
long hash1[MAXLINES], hash2[MAXLINES];
unsigned char occ1[8192], occ2[8192];
int n1, n2;
FILE *file1, *file2;
char name[80], *s;
int different = 0;
unsigned char flag1 = WHITE;
void givehelp(void)
{
printf("Usage is: FILECOMP [options] filespec1 filespec2\n");
printf("Options:\n");
printf(" /f\tshow full lines.\n");
printf(" /t\texpand tabs before comparing.\n");
printf(" /b\tignore trailing blanks.\n");
printf(" /w\tignore spaces and tabs.\n");
printf(" /y\tcase insensitive compare.\n");
printf("filespec2 can be a drive or directory name.\n");
}
/* expand tabs */
void tabex(unsigned char *s1, unsigned char *s2)
{
int i;
unsigned char j;
for (i=j=0; s1[i]; i++) {
if (s1[i] != '\t') {
s2[j++] = s1[i];
continue;
}
do s2[j++] = ' '; while(j%8 != 0);
}
s2[j] = 0;
}
/* zap white space */
void zapwhite(unsigned char *s1, unsigned char *s2)
{
int i, j;
for (i=j=0; s1[i]; i++) {
if (s1[i] != ' ' && s1[i] != '\t')
s2[j++] = s1[i];
}
s2[j] = 0;
}
/* extract bits from the occurrence vector */
unsigned char getbits(unsigned char *array, unsigned long indx)
{
unsigned i, j;
indx &= 32767;
i = indx>>2;
j = indx - (i<<2);
return ((array[i]>>((3-j)<<1)) & 0x03);
}
/* store bits in the occurrence array */
void setbits(unsigned char *array, unsigned long indx, unsigned char x)
{
unsigned i, j, shift;
indx &= 32767;
i = indx>>2;
j = indx - (i<<2);
shift = (3-j)<<1;
array[i] &= ~(0x03<<shift);
array[i] |= x<<shift;
}
/* read in file, build hash & occurrence tables */
int input(FILE *file, long hashvect[], unsigned char occ[])
{
int i, j;
long h;
unsigned char bits, buffer[256], temp[256];
long hash();
for (i=0; i<MAXLINES; i++) {
if (flag1&WHITE) {
if (fgets(temp,256,file)==0) return i;
zapwhite(temp,buffer);
} else if ((flag1&TABS)==0) {
if (fgets(buffer,256,file)==0) return i;
} else {
if (fgets(temp,256,file)==0) return i;
tabex(temp,buffer);
}
if (flag1&CASE) strupr(buffer);
if (flag1&TRIM) {
for (j=0; j<256 && j>=0 && buffer[j] && buffer[j]!='\n'; j++);
for (j=j-1; j>=0 && buffer[j]==' ' ; j--);
buffer[j+1] = 0;
}
h = hash(buffer);
if (h<0)
hashvect[i] = h;
else
hashvect[i] = -h;
bits = getbits(occ,-hashvect[i]);
if (bits==0)
setbits(occ,-hashvect[i],1);
else if (bits==1)
setbits(occ,-hashvect[i],2);
}
printf("File truncated at %d lines.\n",MAXLINES);
return i-1;
}
/* hash a character string */
long hash(unsigned char *s)
{
long h=0, h1;
while (*s) {
h1 = h;
h = h<<1;
if (h1<0) h |= 1;
h ^= *s++;
}
if (h==0) h = 1;
return h;
}
/* display the results of comparison */
void output(int l1,int l2)
{
static int cl1 = 0, cl2 = 0;
char line[81];
unsigned int bi1=0, bi2=0;
unsigned char end1=1, end2=1;
int i;
char buffer1[256], buffer2[256], temp[256];
different = 1;
for (i=0; i<80; i++) line[i] = ' ';
line[80] = 0;
if (l1>=0) {
for (i=cl1; i<=l1; i++)
if((flag1&TABS)==0) fgets(buffer1,256,file1);
else {
fgets(temp,256,file1);
tabex(temp,buffer1);
}
cl1 = l1 + 1;
sprintf(line,"%4d ",l1+1);
line[5] = ' ';
for (i=0; buffer1[i+bi1] && buffer1[i+bi1]!='\n' && i<34; i++)
line[i+5] = buffer1[i+bi1];
if (i==34) {
bi1 += 34;
end1 = 0;
}
}
if (l2>=0) {
for (i=cl2; i<=l2; i++)
if((flag1&TABS)==0) fgets(buffer2,256,file2);
else {
fgets(temp,256,file2);
tabex(temp,buffer2);
}
cl2 = l2 + 1;
sprintf(line+40,"%4d ",l2+1);
line[45] = ' ';
for (i=0; buffer2[i+bi2] && buffer2[i+bi2]!='\n' && i<34; i++)
line[i+45] = buffer2[i+bi2];
if (i==34) {
bi2 += 34;
end2 = 0;
}
}
line[45+i] = '\n';
line[46+i] = 0;
fwrite(line,1,46+i,stdout);
if (flag1 & FULL) while (!end1 || !end2) {
for (i=0; i<80; i++) line[i] = ' ';
if (!end1) {
for (i=0; buffer1[i+bi1] && buffer1[i+bi1]!='\n' && i<34; i++)
line[i+5] = buffer1[i+bi1];
if (i==34) bi1 += 34; else end1 = 1;
}
if (!end2) {
for (i=0; buffer2[i+bi2] && buffer2[i+bi2]!='\n' && i<34; i++)
line[i+45] = buffer2[i+bi2];
if (i==34) bi2 += 34; else end2 = 1;
}
line[45+i] = '\n';
line[46+i] = 0;
fwrite(line,1,46+i,stdout);
}
}
/* match strings with specified minimum */
int match(unsigned char *s1, unsigned char *s2, unsigned char min)
{
unsigned int i;
for (i=0; *s1 && *s2; i++)
if (toupper(*s1++) != *s2++) return 0;
if (*s1==0) return i>=min;
return 0;
}
/* main program */
int cdecl main(int argc, char *argv[])
{
int i,j,k,opt,ifile;
unsigned char linked;
extern int getopt(int argc, char *argv[], char *optionS);
extern int opterr, optind;
if (argc<3) {
givehelp();
return 0;
}
/* get options */
opterr = FALSE; /* handle errors ourself */
while ((opt = getopt(argc, argv, "ftbwy")) != EOF) {
switch (opt) {
case '?':
printf("Invalid command line option\n");
givehelp();
return(1);
case 'f':
flag1 |= FULL; break;
case 't':
flag1 |= TABS; break;
case 'b':
flag1 |= TRIM; break;
case 'w':
flag1 &= ~WHITE; break;
case 'y':
flag1 |= CASE; break;
}
}
ifile = optind; /* index of first file parm */
/* step 1: read first file and hash it */
file1 = fopen(argv[ifile],"r");
if (file1==0) {
printf("Unable to open file '%s'\n",argv[ifile]);
return 2;
}
printf("Reading file '%s'.\n",argv[ifile]);
n1 = input(file1,hash1,occ1);
fseek(file1,0L,0);
/* get the file name, with dir name stripped off */
for (i=j=0; (k=argv[ifile][i]) != 0; ++i)
if (k == ':' || k == '\\' || k == '/') j = i + 1;
s = argv[1] + j;
/* if argv[ifile+1] ends in : or \, tack on 1st file name */
for (i=j=0; (k=argv[ifile+1][i]) != 0; ++i)
if (k == ':' || k == '\\' || k == '/') j = i + 1;
strcpy(name,argv[ifile+1]);
if (j == i) strcpy(name+j,s);
/* step 2: read second file and hash it */
file2 = fopen(name,"r");
if (file2==0) {
/* maybe argv[ifile] was a directory, so try again */
if (j != i) {
name[i] = '\\';
strcpy(name+i+1,s);
file2 = fopen(name,"r");
}
}
if (file2==0) {
printf("Unable to open file '%s'.\n",name);
return 2;
}
printf("Reading file '%s'.\n",name);
n2 = input(file2,hash2,occ2);
fseek(file2,0L,0);
/* step 3: identify lines that are unique in both files */
for (i=0; i<8192; i++) occ1[i] &= occ2[i];
/* step 4: link together matching unique lines */
for (i=0; i<n1; i++) {
if (getbits(occ1,-hash1[i])!=1) continue;
for (j=0; i+j<n2 || i-j>=0; j++) {
if (i+j<n2) if (hash2[i+j]==hash1[i]) {
hash1[i] = i+j;
hash2[i+j] = i;
break;
}
if (i-j>=0) if (hash2[i-j]==hash1[i]) {
hash1[i] = i-j;
hash2[i-j] = i;
break;
}
}
}
/* step 5: link the first and last lines, if possible */
if (hash1[0]<0 && hash1[0]==hash2[0]) hash1[0] = hash2[0] = 0;
if (hash1[n1-1]<0 && hash1[n1-1]==hash2[n2-1]) {
hash1[n1-1] = n2-1;
hash2[n2-1] = n1-1;
}
/* step 6: starting from linked lines, link following lines that match */
linked = 0;
for (i=0; i<n1; i++) {
if (hash1[i]>=0) linked = 1;
else if (linked==1) {
if (hash1[i]==hash2[hash1[i-1]+1]) {
hash1[i] = hash1[i-1]+1;
hash2[hash1[i]] = i;
}
else linked = 0;
}
}
/* step 7: link matching lines that precede linked lines */
linked = 0;
for (i=n1-1; i>=0; i--) {
if (hash1[i]>=0) linked = 1;
else if (linked==1) {
if (hash1[i]==hash2[hash1[i+1]-1]) {
hash1[i] = hash1[i+1] - 1;
hash2[hash1[i]] = i;
} else linked = 0;
}
}
/* step 8: display the results */
for (i=j=0; i<n1 && j<n2;) {
if (hash1[i]<j && hash2[j]<i) {
output(i++,j++);
continue;
}
if (hash1[i]<j) {
output(i++,-1);
continue;
}
if (hash2[j]<i) {
output(-1,j++);
continue;
}
if (hash1[i]==j) {
for (k=1; i+k<=n1 && j+k<=n2 && hash1[i+k]==j+k; k++);
printf("\n*** %d line(s) match. ***\n\n",k);
i += k;
j += k;
continue;
}
if (hash1[i]-j <= hash2[j]-i) {
for (k=j; k<hash1[i]; k++) output(-1,k);
j = hash1[i];
continue;
} else {
for (k=i; k<hash2[j]; k++) output(k,-1);
i = hash2[j];
continue;
}
}
if (i<n1) for (k=i; k<n1; k++) output(k,-1);
if (j<n2) for (k=j; k<n2; k++) output(-1,k);
fclose(file1);
fclose(file2);
return different;
}
/* end of program */


View File

@ -0,0 +1,69 @@
/* float.h
Defines implementation specific macros for dealing with
floating point.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#define FLT_RADIX 2
#define FLT_ROUNDS 1
#define FLT_GUARD 1
#define FLT_NORMALIZE 1
#define DBL_MAX_EXP +308
#define FLT_MAX_EXP +38
#define LDBL_MAX_EXP +308
#define DBL_MIN_EXP -308
#define FLT_MIN_EXP -38
#define LDBL_MIN_EXP -308
#define DBL_DIG 14
#define FLT_DIG 6
#define LDBL_DIG 14
unsigned int _Cdecl _control87(unsigned int new, unsigned int mask);
unsigned int _Cdecl _clear87(void);
void _Cdecl _fpreset(void);
unsigned int _Cdecl _status87(void);
/* 8087/80287 Status Word format */
#define SW_INVALID 0x0001 /* Invalid operation */
#define SW_DENORMAL 0x0002 /* Denormalized operand */
#define SW_ZERODIVIDE 0x0004 /* Zero divide */
#define SW_OVERFLOW 0x0008 /* Overflow */
#define SW_UNDERFLOW 0x0010 /* Underflow */
#define SW_INEXACT 0x0020 /* Precision (Inexact result) */
/* 8087/80287 Control Word format */
#define MCW_EM 0x003f /* interrupt Exception Masks */
#define EM_INVALID 0x0001 /* invalid */
#define EM_DENORMAL 0x0002 /* denormal */
#define EM_ZERODIVIDE 0x0004 /* zero divide */
#define EM_OVERFLOW 0x0008 /* overflow */
#define EM_UNDERFLOW 0x0010 /* underflow */
#define EM_INEXACT 0x0020 /* inexact (precision) */
#define MCW_IC 0x1000 /* Infinity Control */
#define IC_AFFINE 0x1000 /* affine */
#define IC_PROJECTIVE 0x0000 /* projective */
#define MCW_RC 0x0c00 /* Rounding Control */
#define RC_CHOP 0x0c00 /* chop */
#define RC_UP 0x0800 /* up */
#define RC_DOWN 0x0400 /* down */
#define RC_NEAR 0x0000 /* near */
#define MCW_PC 0x0300 /* Precision Control */
#define PC_24 0x0000 /* 24 bits */
#define PC_53 0x0200 /* 53 bits */
#define PC_64 0x0300 /* 64 bits */
#define CW_DEFAULT (RC_NEAR+PC_64+EM_DENORMAL+EM_UNDERFLOW+EM_INEXACT)


BIN
Borland Turbo C v1/FP87.LIB Normal file

Binary file not shown.

135
Borland Turbo C v1/GETOPT.C Normal file
View File

@ -0,0 +1,135 @@
/*
getopt.c -- Turbo C
Copyright (c) 1986,1987 by Borland International Inc.
All Rights Reserved.
*/
#include <errno.h>
#include <string.h>
#include <dos.h>
#include <stdio.h>
int optind = 1; /* index of which argument is next */
char *optarg; /* pointer to argument of current option */
int opterr = 1; /* allow error message */
static char *letP = NULL; /* remember next option char's location */
static char SW = 0; /* DOS switch character, either '-' or '/' */
/*
Parse the command line options, System V style.
Standard option syntax is:
option ::= SW [optLetter]* [argLetter space* argument]
where
- SW is either '/' or '-', according to the current setting
of the MSDOS switchar (int 21h function 37h).
- there is no space before any optLetter or argLetter.
- opt/arg letters are alphabetic, not punctuation characters.
- optLetters, if present, must be matched in optionS.
- argLetters, if present, are found in optionS followed by ':'.
- argument is any white-space delimited string. Note that it
can include the SW character.
- upper and lower case letters are distinct.
There may be multiple option clusters on a command line, each
beginning with a SW, but all must appear before any non-option
arguments (arguments not introduced by SW). Opt/arg letters may
be repeated: it is up to the caller to decide if that is an error.
The character SW appearing alone as the last argument is an error.
The lead-in sequence SWSW ("--" or "//") causes itself and all the
rest of the line to be ignored (allowing non-options which begin
with the switch char).
The string *optionS allows valid opt/arg letters to be recognized.
argLetters are followed with ':'. Getopt () returns the value of
the option character found, or EOF if no more options are in the
command line. If option is an argLetter then the global optarg is
set to point to the argument string (having skipped any white-space).
The global optind is initially 1 and is always left as the index
of the next argument of argv[] which getopt has not taken. Note
that if "--" or "//" are used then optind is stepped to the next
argument before getopt() returns EOF.
If an error occurs, that is an SW char precedes an unknown letter,
then getopt() will return a '?' character and normally prints an
error message via perror(). If the global variable opterr is set
to false (zero) before calling getopt() then the error message is
not printed.
For example, if the MSDOS switch char is '/' (the MSDOS norm) and
*optionS == "A:F:PuU:wXZ:"
then 'P', 'u', 'w', and 'X' are option letters and 'F', 'U', 'Z'
are followed by arguments. A valid command line may be:
aCommand /uPFPi /X /A L someFile
where:
- 'u' and 'P' will be returned as isolated option letters.
- 'F' will return with "Pi" as its argument string.
- 'X' is an isolated option.
- 'A' will return with "L" as its argument.
- "someFile" is not an option, and terminates getOpt. The
caller may collect remaining arguments using argv pointers.
*/
int getopt(int argc, char *argv[], char *optionS)
{
unsigned char ch;
char *optP;
if (SW == 0) {
/* get SW using dos call 0x37 */
_AX = 0x3700;
geninterrupt(0x21);
SW = _DL;
}
if (argc > optind) {
if (letP == NULL) {
if ((letP = argv[optind]) == NULL ||
*(letP++) != SW) goto gopEOF;
if (*letP == SW) {
optind++; goto gopEOF;
}
}
if (0 == (ch = *(letP++))) {
optind++; goto gopEOF;
}
if (':' == ch || (optP = strchr(optionS, ch)) == NULL)
goto gopError;
if (':' == *(++optP)) {
optind++;
if (0 == *letP) {
if (argc <= optind) goto gopError;
letP = argv[optind++];
}
optarg = letP;
letP = NULL;
} else {
if (0 == *letP) {
optind++;
letP = NULL;
}
optarg = NULL;
}
return ch;
}
gopEOF:
optarg = letP = NULL;
return EOF;
gopError:
optarg = NULL;
errno = EINVAL;
if (opterr)
perror ("get command line option");
return ('?');
}

View File

@ -0,0 +1,12 @@
/* HELLO.C -- Hello, world */
#include <stdio.h>
main()
{
printf("Hello, world\n");
}

73
Borland Turbo C v1/IO.H Normal file
View File

@ -0,0 +1,73 @@
/* io.h
Definitions for low level I/O functions.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _IO_H
#define _IO_H 1
#define HANDLE_MAX 20U
extern unsigned int _Cdecl _openfd[];
struct ftime {
unsigned ft_tsec : 5; /* Two second interval */
unsigned ft_min : 6; /* Minutes */
unsigned ft_hour : 5; /* Hours */
unsigned ft_day : 5; /* Days */
unsigned ft_month : 4; /* Months */
unsigned ft_year : 7; /* Year */
};
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
int _Cdecl access (char *filename, int amode);
int _Cdecl chmod (char *filename, int amode);
int _Cdecl close (int handle);
int _Cdecl creat (char *path, int amode);
int _Cdecl dup (int handle);
int _Cdecl dup2 (int oldhandle, int newhandle);
int _Cdecl eof (int handle);
long _Cdecl filelength (int handle);
int _Cdecl getftime (int handle, struct ftime *ftimep);
int _Cdecl ioctl (int handle, char func, ...);
/* optional 3rd and 4th args are: void * argdx, int argcx */
int _Cdecl isatty (int handle);
int _Cdecl lock (int handle, long offset, long length);
long _Cdecl lseek (int handle, long offset, unsigned char kind);
int _Cdecl open (char *path, unsigned access,... /*unsigned mode*/);
int _Cdecl read (int handle, char *buf, unsigned int len);
int _Cdecl setmode (int handle, int amode);
int _Cdecl setftime (int handle, struct ftime *ftimep);
long _Cdecl tell (int handle);
unsigned _Cdecl umask (unsigned cmask);
int _Cdecl unlock (int handle, long offset, long length);
int _Cdecl write (int handle, char *buf, unsigned int len);
/* Low level routines close to DOS.
*/
int _Cdecl _chmod (char *pathname, int func, ... /* int attr */);
int _Cdecl _close (int handle);
int _Cdecl _creat (char *path, int attribute);
int _Cdecl creattemp (char *path, int amode); /* DOS 3.0 or later */
int _Cdecl creatnew (char *pathP, int mode); /* DOS 3.0 or later */
int _Cdecl _open (char *filename, unsigned oflags);
int _Cdecl _read (int handle, void *buf, int len);
int _Cdecl _write (int handle, void *buf, int len);
/* macros for compatibility with earlier versions & other compilers.
*/
#define sopen(path,access,shflag,mode) open (path, (access) | (shflag), mode)
#endif /* _IO_H */


View File

@ -0,0 +1,39 @@
/* limits.h
Defines implementation specific limits on type values.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#define CHAR_BIT 8
#if (((int)((char)0x80)) < 0)
#define CHAR_MAX 0x7F
#define CHAR_MIN 0x80
#else
#define CHAR_MAX 0xFFU
#define CHAR_MIN 0x00
#endif
#define SCHAR_MAX 0x7F
#define SCHAR_MIN 0x80
#define UCHAR_MAX 0xFFU
#define SHRT_MAX 0x7FFF
#define SHRT_MIN ((int)0x8000)
#define USHRT_MAX 0xFFFFU
#define INT_MAX 0x7FFF
#define INT_MIN ((int)0x8000)
#define UINT_MAX 0xFFFFU
#define LONG_MAX 0x7FFFFFFFL
#define LONG_MIN ((long)0x80000000L)
#define ULONG_MAX 0xFFFFFFFFUL


45
Borland Turbo C v1/MAIN.C Normal file
View File

@ -0,0 +1,45 @@
/* MAIN.C
Alternate, standalone main() file. Demonstrates
linking to the startup code without having to link
to any of the Turbo C library routines.
Copyright (c) 1987 Borland International. All rights reserved.
*/
/*
Compile and link with:
tcc -c -ms main
masm c0 /D__SMALL__ /D__NOFLOAT /t/mx;
masm setargv /D__SMALL__ /t/mx;
tlink c0 main setargv /c/m,main
For another memory model, replace __SMALL__ with one of
__MEDIUM__, __COMPACT__, __LARGE__, __HUGE__
If using tiny model, replace __SMALL__ with __TINY__ and run
exe2bin main.exe main.com
del main.exe
Resulting main.exe has no references to the library.
Caution: This example works only with no floating point code.
*/
void exit(int c)
{ _exit(c);}
void _setenvp(void){} /* dummy out _setenvp */
int _stklen = 0x200;
main(int argc,char **argv)
{
/* print Hello, world using int 21, function 9 */
_DX = (unsigned) "Hello, world.\r\n$";
_AX = 0x900;
__int__(0x21); /* use built-in, inline function */
exit(0);
}


BIN
Borland Turbo C v1/MAKE.EXE Normal file

Binary file not shown.

110
Borland Turbo C v1/MATH.H Normal file
View File

@ -0,0 +1,110 @@
/* math.h
Definitions for the math floating point package.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _MATH_H
#define _MATH_H 1
#define EDOM 33 /* Math argument */
#define ERANGE 34 /* Result too large */
#define HUGE_VAL (_huge_val())
double _Cdecl atof (char *s);
double _Cdecl _huge_val(void);
double _Cdecl sin (double x);
double _Cdecl cos (double x);
double _Cdecl tan (double x);
double _Cdecl asin (double x);
double _Cdecl acos (double x);
double _Cdecl atan (double x);
double _Cdecl atan2 (double y, double x);
double _Cdecl sinh (double x);
double _Cdecl cosh (double x);
double _Cdecl tanh (double x);
double _Cdecl floor (double x);
double _Cdecl ceil (double x);
double _Cdecl fmod (double x, double y);
double _Cdecl modf (double x, double *ipart);
double _Cdecl fabs (double x);
double _Cdecl exp (double x);
double _Cdecl log (double x);
double _Cdecl log10 (double x);
double _Cdecl pow (double x, double y);
double _Cdecl sqrt (double x);
double _Cdecl ldexp (double x, int exponent);
double _Cdecl frexp (double x, int *exponent);
struct exception
{
int type;
char *name;
double arg1, arg2, retval;
};
int _Cdecl matherr (struct exception *e);
#if !__STDC__
double cdecl hypot (double x, double y);
double cdecl poly (double x, int degree, double coeffs []);
double cdecl pow10 (int p);
struct complex /* as used by "cabs" function */
{
double x, y;
};
#define cabs(z) (hypot ((z).x, (z).y))
/* The customary matherr() exception handler for maths functions is
not compatible with the x3j11 draft standard for C. _matherr() is
provided as a compromise.
*/
typedef enum
{
DOMAIN = 1, /* argument domain error -- log (-1) */
SING, /* argument singularity -- pow (0,-2)) */
OVERFLOW, /* overflow range error -- exp (1000) */
UNDERFLOW, /* underflow range error -- exp (-1000) */
TLOSS, /* total loss of significance -- sin(10e70) */
PLOSS, /* partial loss of signif. -- not used */
}
_mexcep;
double cdecl _matherr (_mexcep why,
char *fun,
double *arg1p,
double *arg2p,
double retval);
/* Constants rounded for 18 decimals.
*/
#define M_E 2.71828182845904524
#define M_LOG2E 1.44269504088896341
#define M_LOG10E 0.434294481903251828
#define M_LN2 0.693147180559945309
#define M_LN10 2.30258509299404568
#define M_PI 3.14159265358979324
#define M_PI_2 1.57079632679489662
#define M_PI_4 0.785398163397448310
#define M_1_PI 0.318309886183790672
#define M_2_PI 0.636619772367581343
#define M_1_SQRTPI 0.564189583547756287
#define M_2_SQRTPI 1.12837916709551257
#define M_SQRT2 1.41421356237309505
#define M_SQRT_2 0.707106781186547524
#endif /* __STDC__ */
#endif


Binary file not shown.

View File

@ -0,0 +1,73 @@
/* matherr
Turbo-C Run Time Library
Copyright (c) 1987 by Borland International. All rights reserved.
*/
#include <stdio.h>
#include <math.h>
#include <errno.h>
/*
When exceptions are detected in the maths library then a call is
made to _matherr() with all the available information.
That function does very little, except to map the exception "why"
into either ERANGE or EDOMAIN in errno. Its main purpose is to
act as a focal point for changes in error handling.
For example, if you were writing a spreadsheet you might replace
this function with one which pops up an error window explaining
something like:
"log (-2.0) caused domain error, in cell J7"
and then longjmp() to a reset state in the spreadsheet and await
the next command from the user.
The important thing is that we don't know what error handling
you want, but you are assured that all errors will arrive at
matherr() with all the information you need to design a custom
format.
We do not ship as standard the function named matherr() which may
be familiar to UNIX users, since the ANSI x3j11 draft specifies
an incompatible style. This version is as close as we could
get without breaking the ANSI rules. You can, however, convert
this version to the UNIX style if you prefer. The necessary
code is included but switched off.
*/
#ifdef UNIX_matherr
char *whyS [] =
{
"argument domain error",
"argument singularity ",
"overflow range error ",
"underflow range error",
"total loss of significance",
"partial loss of significance"
};
int matherr (struct exception *e)
/*
The default version of matherr() traditionally explains what has
gone wrong and then kills the program.
*/
{
fprintf (stderr,
"%s (%8g,%8g): %s\n", e->name, e->arg1, e->arg2, whyS [e->type - 1]);
exit (1);
}
#else
int matherr (struct exception *e)
{
return (0);
}
#endif


Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

162
Borland Turbo C v1/MCALC.C Normal file
View File

@ -0,0 +1,162 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#define MAIN
#include <string.h>
#include <alloc.h>
#include <stdarg.h>
#include "mcalc.h"
CELLPTR cell[MAXCOLS][MAXROWS], curcell;
unsigned char format[MAXCOLS][MAXROWS];
unsigned char colwidth[MAXCOLS];
unsigned char colstart[SCREENCOLS];
int leftcol, rightcol, toprow, bottomrow, curcol, currow, lastcol, lastrow;
char changed = FALSE;
char formdisplay = FALSE;
char autocalc = TRUE;
char stop = FALSE;
char colortable[128];
char colorcard;
char snow;
char far *displayptr;
long memleft;
void run()
/* The main program loop */
{
int input;
do
{
displaycell(curcol, currow, HIGHLIGHT, NOUPDATE);
curcell = cell[curcol][currow];
showcelltype();
input = getkey();
switch(input)
{
case '/' :
mainmenu();
break;
case '!' :
recalc();
break;
case F2 :
editcell(curcell);
break;
case DELKEY :
deletecell(curcol, currow, UPDATE);
printfreemem();
if (autocalc)
recalc();
break;
case PGUPKEY :
toprow -= 20;
currow -= 20;
if (currow < 0)
currow = toprow = 0;
else if (toprow < 0)
{
currow -= toprow;
toprow = 0;
}
setbottomrow();
displayscreen(NOUPDATE);
break;
case PGDNKEY :
toprow += 20;
currow += 20;
if ((currow >= MAXROWS) && (toprow >= MAXROWS))
{
currow = MAXROWS - 1;
toprow = MAXROWS - 20;
}
else if (toprow > (MAXROWS - 20))
{
currow -= (toprow + 20 - MAXROWS);
toprow = MAXROWS - 20;
}
setbottomrow();
displayscreen(NOUPDATE);
break;
case CTRLLEFTKEY :
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (leftcol == 0)
curcol = 0;
else
{
curcol = rightcol = leftcol - 1;
setleftcol();
setrightcol();
displayscreen(NOUPDATE);
}
break;
case CTRLRIGHTKEY :
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (rightcol == MAXCOLS - 1)
curcol = rightcol;
else
{
curcol = leftcol = rightcol + 1;
setrightcol();
setleftcol();
displayscreen(NOUPDATE);
}
break;
case HOMEKEY :
currow = curcol = leftcol = toprow = 0;
setrightcol();
setbottomrow();
displayscreen(NOUPDATE);
break;
case ENDKEY :
rightcol = curcol = lastcol;
currow = bottomrow = lastrow;
settoprow();
setleftcol();
setrightcol();
displayscreen(NOUPDATE);
break;
case UPKEY :
moverowup();
break;
case DOWNKEY :
moverowdown();
break;
case LEFTKEY :
movecolleft();
break;
case RIGHTKEY :
movecolright();
break;
default :
if ((input >= ' ') && (input <= '~'))
getinput(input);
break;
} /* switch */
}
while (!stop);
} /* run */
main(int argc, char *argv[])
{
initdisplay();
clrscr();
writef((80 - strlen(MSGHEADER)) >> 1, 10, MSGHEADERCOLOR, strlen(MSGHEADER),
MSGHEADER);
writef((80 - strlen(MSGKEYPRESS)) >> 1, 12, PROMPTCOLOR,
strlen(MSGKEYPRESS), MSGKEYPRESS);
gotoxy(79, 24);
getkey();
clrscr();
initvars();
memleft = memsize;
redrawscreen();
if (argc > 1)
loadsheet(argv[1]);
clearinput();
run();
clrscr();
gotoxy(0, 0);
}


View File

@ -0,0 +1,97 @@
How to compile MicroCalc
------------------------
With TC.EXE:
1. Run TC.EXE
2. In the Project pulldown menu specify the project name "MCALC.PRJ"
3. From the main menu select the Run option
With TCC.EXE:
Compile from DOS with the following command line:
TCC mcalc mcparser mcdisply mcinput mcommand mcutil mcmvsmem.obj
In both cases, compiling under a large data model (COMPACT, LARGE, or HUGE)
will give you much more memory for your spreadsheets.
The MicroCalc parser
--------------------
The state and goto information for the parser was created using the UNIX YACC
utility. The input to YACC was as follows:
%token CONST CELL FUNC
%%
e : e '+' t
| e '-' t
| t
;
t : t '*' f
| t '/' f
| f
;
f : x '^' f
| x
;
x : '-' u
| u
;
u : CELL ':' CELL
| o
;
o : CELL
| '(' e ')'
| CONST
| FUNC '(' e ')'
;
%%
Additional MicroCalc information
--------------------------------
Formulas are entered as text. MicroCalc will determine if what you entered
is a legal formula or text.
Cell names in formulas are typed in with the column followed by the row.
Examples:
A1+A2
B6^5
To sum a group of cells, put a colon between the first cell and the last
cell in the group.
Example:
A1:A10 sums all of the cells from A1 to A10 and puts the result in the
current cell.
The available MicroCalc functions are:
ABS - absolute value
ACOS - arc cosine
ASIN - arc sine
ATAN - arc tangent
COS - cosine
COSH - hyperbolic cosine
EXP - exponential function
LOG - logarithm
LOG10 - base 10 logarithm
POW10 - raise argument to the 10th power
ROUND - round to the nearest whole number
SIN - sine
SINH - hyperbolic sine
SQR - square
SQRT - square root
TAN - tangent
TANH - hyperbolic tangent
TRUNC - return the whole part of a number
Examples:
TRUNC(A1)
SQRT(SQR(34.5))
ABS(TRUNC(B16))


279
Borland Turbo C v1/MCALC.H Normal file
View File

@ -0,0 +1,279 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#define S_IREAD 0x0100 /* from SYS\STAT.H */
#define S_IWRITE 0x0080 /* from SYS\STAT.H */
#define TRUE 1
#define FALSE 0
#define MSGHEADER "MICROCALC - A Turbo C Demonstration Program"
#define MSGKEYPRESS "Press any key to continue."
#define MSGCOMMAND "Press / for the list of commands"
#define MSGMEMORY "Memory Available:"
#define MSGERROR "ERROR"
#define MSGLOMEM "Not enough memory to allocate cell."
#define MSGEMPTY "Empty"
#define MSGTEXT "Text"
#define MSGVALUE "Value"
#define MSGFORMULA "Formula"
#define MSGAUTOCALC "AutoCalc"
#define MSGFORMDISPLAY "Form"
#define MSGFILENAME "Enter the file name of the spreadsheet:"
#define MSGNAME "MicroCalc Spreadsheet"
#define MSGCOLWIDTH "Enter the new column width:"
#define MSGNOOPEN "Can't open the file."
#define MSGOVERWRITE "The file exists. Do you want to overwrite it?"
#define MSGFILELOMEM "Not enough memory for entire spreadsheet."
#define MSGNOMICROCALC "That is not a MicroCalc spreadsheet."
#define MSGNOEXIST "The file does not exist."
#define MSGGOTO "Enter the cell to go to:"
#define MSGBADNUMBER "You must enter a number from %d to %d."
#define MSGBADCELL "That is not a legal cell."
#define MSGCELL1 "Enter the first cell to format:"
#define MSGCELL2 "Enter the last cell to format:"
#define MSGDIFFCOLROW "The row or the column must be the same."
#define MSGRIGHTJUST "Do you want the cell right-justified?"
#define MSGDOLLAR "Do you want numbers in a dollar format?"
#define MSGCOMMAS "Do you want commas in numbers?"
#define MSGPLACES "How many decimal places should the number be rounded to?"
#define MSGCOLUMNS "Do you want to print in 132 columns?"
#define MSGPRINT "Enter the file name to print to, or press ENTER to print on the printer."
#define MSGBORDER "Print the border?"
#define MSGLOADING "Loading..."
#define MSGSAVING "Saving..."
#define MSGSAVESHEET "Save current spreadsheet?"
#define MSGSTACKERROR "Parser stack overflow."
#define MENU "Spreadsheet, Format, Delete, Goto, Col, Row, Edit, Utility, Auto, Quit"
#define COMMAND "SFDGCREUAQ"
#define SMENU "Load, Save, Print, Clear"
#define SCOMMAND "LSPC"
#define CMENU "Insert, Delete, Width"
#define CCOMMAND "IDW"
#define RMENU "Insert, Delete"
#define RCOMMAND "ID"
#define UMENU "Recalc, Formula display"
#define UCOMMAND "RF"
#define MAXCOLS 100 /* Maximum is 702 */
#define MAXROWS 100
#define VIDEOWRITE 1
#define LEFTMARGIN 3
#define MINCOLWIDTH 3
#define MAXCOLWIDTH 80 - LEFTMARGIN
#define SCREENCOLS (80 - LEFTMARGIN) / MINCOLWIDTH + 1
#define SCREENROWS 20
#define DEFAULTWIDTH 10
#define DEFAULTFORMAT 2
#define MAXINPUT 79
#define MAXPLACES 8
#define TOPMARGIN 5
#define PARSERSTACKSIZE 20
#define TEXTCOLOR WHITE
#define ERRORCOLOR LIGHTRED + BLINK
#define VALUECOLOR LIGHTCYAN
#define FORMULACOLOR LIGHTMAGENTA
#define BLANKCOLOR BLACK
#define HEADERCOLOR WHITE + (RED << 4)
#define HIGHLIGHTCOLOR WHITE + (BLUE << 4)
#define HIGHLIGHTERRORCOLOR WHITE + (BLUE << 4) + BLINK
#define MSGAUTOCALCCOLOR LIGHTCYAN
#define MSGFORMDISPLAYCOLOR LIGHTMAGENTA
#define MSGMEMORYCOLOR LIGHTGREEN
#define MSGHEADERCOLOR LIGHTCYAN
#define PROMPTCOLOR YELLOW
#define COMMANDCOLOR LIGHTCYAN
#define LOWCOMMANDCOLOR WHITE
#define MEMORYCOLOR LIGHTRED
#define CELLTYPECOLOR LIGHTGREEN
#define CELLCONTENTSCOLOR YELLOW
#define HIGHLIGHT TRUE
#define NOHIGHLIGHT FALSE
#define UPDATE TRUE
#define NOUPDATE FALSE
#define FORMAT TRUE
#define NOFORMAT FALSE
#define LEFT 0
#define RIGHT 1
#define UP 2
#define DOWN 3
#define TEXT 0
#define VALUE 1
#define FORMULA 2
#define COLADD 0
#define COLDEL 1
#define ROWADD 2
#define ROWDEL 3
#define OVERWRITE 0X80
#define RJUSTIFY 0X40
#define COMMAS 0X20
#define DOLLAR 0X10
struct CELLREC
{
char attrib;
union
{
char text[MAXINPUT + 1];
double value;
struct
{
double fvalue;
char formula[MAXINPUT + 1];
} f;
} v;
};
typedef struct CELLREC *CELLPTR;
#if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#define memsize coreleft() - 1000
#define textcellsize(s) (((strlen(s) >> 1) + 3) << 1)
#define valuecellsize 12
#define formulacellsize(s) (((strlen(s) >> 1) + 7) << 1)
#else
#define memsize farcoreleft() - 1000
#define textcellsize(s) (((strlen(s) >> 1) + 5) << 1)
#define valuecellsize 16
#define formulacellsize(s) (((strlen(s) >> 1) + 9) << 1)
#endif
#define BS 8
#define FORMFEED 12
#define CR 13
#define ESC 27
#define HOMEKEY 327
#define ENDKEY 335
#define UPKEY 328
#define DOWNKEY 336
#define PGUPKEY 329
#define PGDNKEY 337
#define LEFTKEY 331
#define INSKEY 338
#define RIGHTKEY 333
#define DELKEY 339
#define CTRLLEFTKEY 371
#define CTRLRIGHTKEY 372
#define F1 315
#define F2 316
#define F3 317
#define F4 318
#define F5 319
#define F6 320
#define F7 321
#define F8 322
#define F9 323
#define F10 324
#define BLACK 0
#define BLUE 1
#define GREEN 2
#define CYAN 3
#define RED 4
#define MAGENTA 5
#define BROWN 6
#define LIGHTGRAY 7
#define DARKGRAY 8
#define LIGHTBLUE 9
#define LIGHTGREEN 10
#define LIGHTCYAN 11
#define LIGHTRED 12
#define LIGHTMAGENTA 13
#define YELLOW 14
#define WHITE 15
#define BLINK 128
int getkey(void);
int editstring(char *s, char *legal, int maxlength);
int getint(int *number, int low, int high);
void getinput(int c);
void scroll(int direction, int lines, int x1, int y1, int x2, int y2,
int attrib);
void setcursor(int startline, int endline);
void clrscr(void);
void gotoxy(int col, int row);
void writef(int col, int row, int color, int width, va_list arg_list, ...);
void printcol(void);
void printrow(void);
void displaycell(int col, int row, int highlighting, int updating);
void displaycol(int col, int updating);
void displayrow(int row, int updating);
void displayscreen(int updating);
void clearinput(void);
void changecursor(int insmode);
void showcelltype(void);
void initdisplay(void);
double parse(char *s, int *att);
int alloctext(int col, int row, char *s);
int allocvalue(int col, int row, double amt);
int allocformula(int col, int row, char *s, double amt);
void deletecell(int col, int row, int display);
void printfreemem(void);
void moverowup(void);
void moverowdown(void);
void movecolleft(void);
void movecolright(void);
void recalc(void);
void changeautocalc(int newmode);
void changeformdisplay(int newmode);
void errormsg(char *s);
void colstring(int col, char *colstr);
void centercolstring(int col, char *colstr);
void setleftcol(void);
void setrightcol(void);
void settoprow(void);
void setbottomrow(void);
void movehighlight(void);
void setlastcol(void);
void setlastrow(void);
void act(char *s);
void initvars(void);
void far movescreenmem(char far *source, char far *dest, unsigned len,
int snowcheck);
int getcommand(char *msgstr, char *comstr);
void mainmenu(void);
void editcell(CELLPTR ecell);
int setoflags(int col, int row, int display);
void clearoflags(int col, int row, int display);
void updateoflags(int col, int row, int display);
void loadsheet(char *filename);
int getcell(int *col, int *row);
char *cellstring(int col, int row, int *color, int formatting);
void writeprompt(char *prompt);
int getyesno(int *yesno, char *prompt);
void swap(int *val1, int *val2);
void redrawscreen(void);
void checkforsave(void);
void savesheet(void);
int formulastart(char **input, int *col, int *row);
int rowwidth(int row);
void fixformula(int col, int row, int action, int place);
void clearlastcol(void);
#if !defined(MAIN)
extern CELLPTR cell[MAXCOLS][MAXROWS], curcell;
extern unsigned char format[MAXCOLS][MAXROWS];
extern unsigned char colwidth[MAXCOLS];
extern unsigned char colstart[SCREENCOLS];
extern char formdisplay;
extern char changed;
extern char autocalc;
extern int leftcol, rightcol, toprow, bottomrow, curcol, currow, lastcol,
lastrow, direction;
extern long memleft;
extern char stop;
extern char colortable[128];
extern char colorcard;
extern char snow;
extern char matherror;
extern char far *displayptr;
#endif


View File

@ -0,0 +1,8 @@
mcalc (mcalc.h)
mcparser (mcalc.h)
mcdisply (mcalc.h)
mcinput (mcalc.h)
mcommand (mcalc.h)
mcutil (mcalc.h)
mcmvsmem.obj


View File

@ -0,0 +1,347 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#include <dos.h>
#include <stdio.h>
#include <string.h>
#include <mem.h>
#include "mcalc.h"
struct screenelement
{
char character;
char color;
};
void scroll(int direction, int lines, int x1, int y1, int x2, int y2,
int attrib)
/* Scrolls an area of the screen */
{
union REGS reg;
#if VIDEOWRITE
int row, size;
char far *source;
char far *dest;
if (direction <= RIGHT)
{
size = (x2 - x1 + 1) << 1;
source = displayptr + (y1 * 160) + (x1 << 1);
if (direction == RIGHT)
dest = source + (lines << 1);
else
dest = source - (lines << 1);
for (row = y1; row <= y2; row++)
{
movescreenmem(source, dest, size, snow);
source += 160;
dest += 160;
}
return;
}
#endif
reg.x.ax = ((direction + 4) << 8) + lines;
reg.h.bh = colortable[attrib];
reg.x.cx = (y1 << 8) + x1;
reg.x.dx = (y2 << 8) + x2;
int86(0X10, &reg, &reg);
} /* scroll */
int egainstalled(void)
/* Tests for the presence of an EGA */
{
union REGS reg;
reg.x.ax = 0X1200;
reg.x.bx = 0X0010;
reg.x.cx = 0XFFFF;
int86(0X10, &reg, &reg);
return((reg.x.cx == 0XFFFF) ? 0 : 1);
} /* egainstalled */
void setcursor(int startline, int endline)
/* Sets the shape of the cursor */
{
union REGS reg;
reg.h.ah = 1;
reg.x.cx = (startline << 8) + endline;
int86(0X10, &reg, &reg);
} /* setcursor */
void clrscr(void)
/* Clears the screen */
{
scroll(UP, 0, 0, 0, 79, 24, WHITE);
} /* clrscr */
void gotoxy(int col, int row)
/* Moves the cursor to a specific column and row */
{
union REGS reg;
reg.h.ah = 2;
reg.h.bh = 0;
reg.x.dx = (row << 8) + col;
int86(0X10, &reg, &reg);
} /* gotoxy */
#if VIDEOWRITE
void writef(int col, int row, int color, int width, va_list arg_list, ...)
/* Prints a string in video memory at a selected location in a color */
{
va_list arg_ptr;
char *format;
char output[81];
struct screenelement buffer[80];
int counter, len;
unsigned size;
va_start(arg_ptr, arg_list);
format = arg_list;
vsprintf(output, format, arg_ptr);
color = (color > 127) ? colortable[color - 128] + 128 : colortable[color];
if ((len = strlen(output)) < width)
setmem(&output[len], width - len, ' ');
size = width << 1;
setmem(buffer, size, color);
for (counter = 0; counter < width; counter++)
buffer[counter].character = output[counter];
movescreenmem((char far *)(buffer),
displayptr + (row * 160) + (col << 1), size, snow);
} /* writef */
#else
void writef(int col, int row, int color, int width, va_list arg_list, ...)
/* Prints a string in video memory at a selected location in a color */
{
va_list arg_ptr;
char *format;
char output[81];
int counter, len, oldcol, oldrow;
register pcol = col;
union REGS inreg, outreg;
va_start(arg_ptr, arg_list);
format = arg_list;
vsprintf(output, format, arg_ptr);
color = (color > 127) ? colortable[color - 128] + 128 : colortable[color];
if ((len = strlen(output)) < width)
setmem(&output[len], width - len, ' ');
inreg.h.ah = 3;
inreg.h.bh = 0;
int86(0X10, &inreg, &outreg);
oldrow = outreg.h.dh;
oldcol = outreg.h.dl;
inreg.h.ah = 9;
inreg.x.bx = color;
inreg.x.cx = 1;
for (counter = 0; counter < width; counter++)
{
gotoxy(pcol++, row);
inreg.h.al = output[counter];
int86(0X10, &inreg, &outreg);
}
gotoxy(oldcol, oldrow);
} /* writef */
#endif
void initcolortable(int blackwhite)
/* Sets up the color table */
{
int color, fg, bg, tempfg, tempbg;
if (!blackwhite)
{
for (color = 0; color < 128; color++)
colortable[color] = color;
}
else
{
for (fg = BLACK; fg <= WHITE; fg++)
{
for (bg = BLACK; bg <= LIGHTGRAY; bg++)
{
tempfg = ((fg >= DARKGRAY) ? WHITE : ((fg >= BLUE) ? LIGHTGRAY : fg));
if (bg != BLACK)
{
tempbg = LIGHTGRAY;
tempfg = ((tempfg <= DARKGRAY) && (tempfg != BLACK) ? DARKGRAY :
BLACK);
}
else
tempbg = BLACK;
colortable[fg + (bg << 4)] = tempfg + (tempbg << 4);
};
};
};
} /* initcolortable */
void printcol(void)
/* Prints the column headings */
{
int col;
char colstr[MAXCOLWIDTH + 1];
scroll(UP, 0, 0, 1, 79, 1, HEADERCOLOR);
for (col = leftcol; col <= rightcol; col++)
{
centercolstring(col, colstr);
writef(colstart[col - leftcol], 1, HEADERCOLOR, colwidth[col], colstr);
}
} /* printcol */
void clearlastcol()
/* Clears any data left in the last column */
{
int col;
if ((col = colstart[rightcol - leftcol] + colwidth[rightcol]) < 80)
scroll(UP, 0, col, 2, 79, SCREENROWS + 1, WHITE);
} /* clearlastcol */
void printrow(void)
/* Prints the row headings */
{
int row;
for (row = 0; row < SCREENROWS; row++)
writef(0, row + 2, HEADERCOLOR, LEFTMARGIN, "%-d", row + toprow + 1);
} /* printrow */
void displaycell(int col, int row, int highlighting, int updating)
/* Displays the contents of a cell */
{
int color;
char *s;
if ((updating) &&
((cell[col][row] == NULL) || (cell[col][row]->attrib != FORMULA)))
return;
s = cellstring(col, row, &color, FORMAT);
if (highlighting)
{
if (color == ERRORCOLOR)
color = HIGHLIGHTERRORCOLOR;
else
color = HIGHLIGHTCOLOR;
}
writef(colstart[col - leftcol], row - toprow + 2, color, colwidth[col],
"%s", s);
} /* displaycell */
void displaycol(int col, int updating)
/* Displays a column on the screen */
{
int row;
for (row = toprow; row <= bottomrow; row++)
displaycell(col, row, NOHIGHLIGHT, updating);
} /* displaycol */
void displayrow(int row, int updating)
/* Displays a row on the screen */
{
int col;
for (col = leftcol; col <= rightcol; col++)
displaycell(col, row, NOHIGHLIGHT, updating);
} /* displayrow */
void displayscreen(int updating)
/* Displays the current screen of the spreadsheet */
{
int row;
for (row = toprow; row <= bottomrow; row++)
displayrow(row, updating);
clearlastcol();
} /* displayscreen */
void clearinput(void)
/* Clears the input line */
{
scroll(UP, 0, 0, 24, 79, 24, WHITE);
gotoxy(0, 24);
} /* clearinput */
void changecursor(insmode)
/* Changes the cursor shape based on the current insert mode */
{
if (insmode)
{
if (colorcard)
setcursor(5, 7);
else
setcursor(9, 12);
}
else
{
if (colorcard)
setcursor(6, 7);
else
setcursor(10, 12);
}
} /* changecursor */
void showcelltype(void)
/* Prints the type of cell and what is in it */
{
char colstr[3], *s;
int color;
formdisplay = !formdisplay;
s = cellstring(curcol, currow, &color, NOFORMAT);
colstring(curcol, colstr);
if (curcell == NULL)
writef(0, 22, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1, MSGEMPTY);
else switch(curcell->attrib)
{
case TEXT :
writef(0, 22, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1,
MSGTEXT);
break;
case VALUE :
writef(0, 22, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1,
MSGVALUE);
break;
case FORMULA :
writef(0, 22, CELLTYPECOLOR, 80, "%s%d %s", colstr, currow + 1,
MSGFORMULA);
break;
} /* switch */
writef(0, 23, CELLCONTENTSCOLOR, 80, "%s", s);
formdisplay = !formdisplay;
} /* showcelltype */
void redrawscreen(void)
/* Displays the entire screen */
{
setrightcol();
setbottomrow();
writef(0, 0, MSGMEMORYCOLOR, strlen(MSGMEMORY), MSGMEMORY);
writef(28, 0, PROMPTCOLOR, strlen(MSGCOMMAND), MSGCOMMAND);
changeautocalc(autocalc);
changeformdisplay(formdisplay);
printfreemem();
displayscreen(NOUPDATE);
} /* redrawscreen */
void initdisplay(void)
/* Initializes various global variables - must be called before using the
above procedures and functions.
*/
{
union REGS reg;
reg.h.ah = 15;
int86(0X10, &reg, &reg);
colorcard = (reg.h.al != 7);
snow = (!egainstalled() && colorcard);
initcolortable(!colorcard || (reg.h.al == 0) || (reg.h.al == 2));
displayptr = (char far *)(colorcard ? 0XB8000000L : 0XB0000000L);
} /* initdisplay */


View File

@ -0,0 +1,184 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#include <string.h>
#include <mem.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <bios.h>
#include "mcalc.h"
int getkey(void)
/* Uses the BIOS to read the next keyboard character */
{
int key, lo, hi;
key = bioskey(0);
lo = key & 0X00FF;
hi = (key & 0XFF00) >> 8;
return((lo == 0) ? hi + 256 : lo);
} /* getkey */
int editstring(char *s, char *legal, int maxlength)
/* Allows the user to edit a string with only certain characters allowed -
Returns TRUE if ESC was not pressed, FALSE is ESC was pressed.
*/
{
int c, len = strlen(s), pos = len, insert = FALSE;
do
{
writef(0, 24, WHITE, 80, "%s", s);
gotoxy(pos, 24);
switch(c = getkey())
{
case HOMEKEY :
pos = 0;
break;
case ENDKEY :
pos = len;
break;
case INSKEY :
insert = !insert;
changecursor(insert);
break;
case LEFTKEY :
if (pos > 0)
pos--;
break;
case RIGHTKEY :
if (pos < len)
pos++;
break;
case BS :
if (pos > 0)
{
movmem(&s[pos], &s[pos - 1], len - pos + 1);
pos--;
len--;
}
break;
case DELKEY :
if (pos < len)
{
movmem(&s[pos + 1], &s[pos], len - pos);
len--;
}
break;
case CR :
break;
case UPKEY :
c = CR;
break;
case DOWNKEY :
c = CR;
break;
case ESC :
len = 0;
break;
default :
if (((legal[0] == 0) || (strchr(legal, c) != NULL)) &&
((c >= ' ') && (c <= '~')) &&
(len < maxlength))
{
if (insert)
{
memmove(&s[pos + 1], &s[pos], len - pos + 1);
len++;
}
else if (pos >= len)
len++;
s[pos++] = c;
}
break;
} /* switch */
s[len] = 0;
}
while ((c != CR) && (c != ESC));
clearinput();
changecursor(FALSE);
return(c != ESC);
} /* editstring */
void getinput(int c)
/* Reads and acts on an input string from the keyboard that started with c. */
{
char s[MAXINPUT + 1];
s[0] = c;
s[1] = 0;
if (!editstring(s, "", MAXINPUT) || (s[0] == 0))
return;
act(s);
changed = TRUE;
} /* getinput */
int getint(int *number, int low, int high)
/* Reads in a positive integer from low to high */
{
int i, good = FALSE;
char s[5] = "", message[81];
sprintf(message, MSGBADNUMBER, low, high);
do
{
if (!editstring(s, "1234567890", 4))
return(FALSE);
i = atoi(s);
if (!(good = (i >= low) && (i <= high)))
errormsg(message);
}
while (!good);
*number = i;
return(TRUE);
} /* getint */
int getcell(int *col, int *row)
/* Reads in a cell name that was typed in - Returns FALSE if ESC was pressed */
{
int first = TRUE, good = FALSE, len, numlen = rowwidth(MAXROWS),
oldcol = *col, oldrow = *row;
char data[10] = "", *input, *start, numstring[6];
do
{
if (!first)
errormsg(MSGBADCELL);
first = FALSE;
input = data;
if (!editstring(data, "", numlen + 2))
{
*col = oldcol;
*row = oldrow;
return(FALSE);
}
*col = toupper(*(input++)) - 'A';
if (isalpha(*input))
{
*col *= 26;
*col += toupper(*(input++)) - 'A' + 26;
}
if (*col >= MAXCOLS)
continue;
start = input;
for (len = 0; len < numlen; len++)
{
if (!isdigit(*(input++)))
{
input--;
break;
}
}
if (len == 0)
continue;
strncpy(numstring, start, len);
numstring[len] = 0;
*row = atoi(numstring) - 1;
if ((*row >= MAXROWS) || (*row == -1))
continue;
good = TRUE;
}
while (!good);
return(TRUE);
} /* getcell */


View File

@ -0,0 +1,66 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#pragma inline
void far movescreenmem(char far *source, char far *dest, unsigned len,
int snowcheck)
/* Moves screen memory, doing snow control if necessary. */
{
unsigned char right;
asm push ds
asm push es
right = ((unsigned long)source < (unsigned long)dest);
asm mov bh,snowcheck
asm lds si,source
asm les di,dest
asm mov cx,len
asm cmp cx,0
asm je j9
asm mov al,right
asm cmp al,1
asm je j1
asm cld
asm jmp short j4
j1:
asm cmp bh,1
asm je j2
asm add si,cx
asm sub si,2
asm add di,cx
asm sub di,2
asm jmp short j3
j2:
asm add si,cx
asm dec si
asm add di,cx
asm dec di
j3:
asm std
j4:
asm cmp bh,1
asm jne j7
asm mov dx,3DAh
j5:
asm in al,dx
asm rcr al,1
asm jb j5
asm cli
j6:
asm in al,dx
asm rcr al,1
asm jnb j6
asm movsb
asm sti
asm loop j5
asm jmp short j9
j7:
asm shr cx,1
j8:
asm movsw
asm loop j8
j9:
asm pop es
asm pop ds
}


Binary file not shown.

View File

@ -0,0 +1,844 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#include <string.h>
#include <mem.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include "mcalc.h"
char *name = MSGNAME;
void moverowup(void)
/* Moves up 1 row */
{
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (currow > toprow)
currow--;
else if (toprow != 0)
{
scroll(DOWN, 1, LEFTMARGIN, 2, 79, SCREENROWS + 1, WHITE);
displayrow(--toprow, NOUPDATE);
currow--;
setbottomrow();
}
} /* moverowup */
void moverowdown(void)
/* Moves down one row */
{
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (currow < bottomrow)
currow++;
else if (bottomrow < (MAXROWS - 1))
{
scroll(UP, 1, LEFTMARGIN, 2, 79, SCREENROWS + 1, WHITE);
toprow++;
currow++;
setbottomrow();
displayrow(bottomrow, NOUPDATE);
}
} /* moverowdown */
void movecolleft(void)
/* Moves left one column */
{
#if VIDEOWRITE
int col, oldleftcol, start, finish, amt;
unsigned char oldcolstart[SCREENCOLS];
oldleftcol = leftcol;
movmem(colstart, oldcolstart, sizeof(colstart));
#endif
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (curcol > leftcol)
curcol--;
else if (leftcol != 0)
{
curcol--;
leftcol--;
setrightcol();
setleftcol();
#if VIDEOWRITE
start = LEFTMARGIN;
finish = oldcolstart[rightcol - oldleftcol] + colwidth[rightcol] - 1;
amt = colstart[oldleftcol - leftcol] - LEFTMARGIN;
if (oldleftcol <= rightcol)
scroll(RIGHT, amt, start, 2, finish, SCREENROWS + 1, WHITE);
clearlastcol();
for (col = leftcol; col <= oldleftcol - 1; col++)
displaycol(col, NOUPDATE);
#else
clearlastcol();
displayscreen(NOUPDATE);
#endif
}
} /* movecolleft */
void movecolright(void)
/* Moves right one column */
{
#if VIDEOWRITE
int col, oldleftcol, oldrightcol, start, finish, amt;
unsigned char oldcolstart[SCREENCOLS];
movmem(colstart, oldcolstart, sizeof(colstart));
oldleftcol = leftcol;
oldrightcol = rightcol;
#endif
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
if (curcol < rightcol)
curcol++;
else if (rightcol < (MAXCOLS - 1))
{
curcol++;
rightcol++;
setleftcol();
setrightcol();
#if VIDEOWRITE
start = oldcolstart[leftcol - oldleftcol];
amt = start - LEFTMARGIN;
finish = oldcolstart[oldrightcol - oldleftcol] + colwidth[oldrightcol] - 1;
if (oldrightcol >= leftcol)
scroll(LEFT, amt, start, 2, finish, SCREENROWS + 1, WHITE);
clearlastcol();
for (col = oldrightcol + 1; col <= rightcol; col++)
displaycol(col, NOUPDATE);
#else
clearlastcol();
displayscreen(NOUPDATE);
#endif
}
} /* movecolright */
void recalc(void)
/* Recalculates all of the numbers in the speadsheet */
{
int col, row, dummy;
for (col = 0; col <= lastcol; col++)
{
for (row = 0; row <= lastrow; row++)
{
if ((cell[col][row] != NULL) && (cell[col][row]->attrib == FORMULA))
cell[col][row]->v.f.fvalue = parse(cell[col][row]->v.f.formula, &dummy);
}
}
displayscreen(UPDATE);
} /* recalc */
void changeautocalc(int newmode)
/* Changes and prints the current AutoCalc value on the screen */
{
char s[15];
if (!autocalc && newmode)
recalc();
autocalc = newmode;
if (autocalc)
strcpy(s, MSGAUTOCALC);
else
s[0] = 0;
writef(72, 0, MSGAUTOCALCCOLOR, strlen(MSGAUTOCALC), s);
} /* autocalc */
void changeformdisplay(int newmode)
/* Changes and prints the current formula display value on the screen */
{
char s[15];
formdisplay = newmode;
if (formdisplay)
strcpy(s, MSGFORMDISPLAY);
else
s[0] = 0;
writef(64, 0, MSGFORMDISPLAYCOLOR, strlen(MSGFORMDISPLAY), s);
} /* autocalc */
void editcell(CELLPTR ecell)
/* Edits a selected cell */
{
char s[MAXINPUT + 1];
if (ecell == NULL)
return;
switch(ecell->attrib)
{
case TEXT :
strcpy(s, ecell->v.text);
break;
case VALUE :
if (ecell->v.value == HUGE_VAL)
strcpy(s, "0");
else
sprintf(s, "%.*f", MAXPLACES, ecell->v.value);
break;
case FORMULA :
strcpy(s, ecell->v.f.formula);
break;
} /* switch */
if (!editstring(s, "", MAXINPUT) || (s[0] == 0))
return;
act(s);
changed = TRUE;
} /* editcell */
void clearsheet(void)
/* Clears the current spreadsheet */
{
int col, row;
for (row = 0; row <= lastrow; row++)
{
for (col = 0; col <= lastcol; col++)
deletecell(col, row, NOUPDATE);
}
initvars();
setrightcol();
setbottomrow();
displayscreen(NOUPDATE);
printfreemem();
changed = FALSE;
} /* clearsheet */
struct CELLREC rec;
void loadsheet(char *filename)
/* Loads a new spreadsheet */
{
int size, allocated, reallastcol = 0, reallastrow = 0, file;
char check[81];
if (filename[0] == 0)
{
writeprompt(MSGFILENAME);
if (!editstring(filename, "", MAXINPUT))
return;
}
if (access(filename, 0))
{
errormsg(MSGNOEXIST);
return;
}
if ((file = open(filename, O_RDWR | O_BINARY)) == -1)
{
errormsg(MSGNOOPEN);
return;
}
read(file, check, strlen(name) + 1);
if (strcmp(check, name) != 0)
{
errormsg(MSGNOMICROCALC);
close(file);
return;
}
writef(0, 24, PROMPTCOLOR, 80, MSGLOADING);
gotoxy(strlen(MSGLOADING), 24);
clearsheet();
read(file, (char *)&size, 1);
read(file, (char *)&lastcol, 2);
read(file, (char *)&lastrow, 2);
read(file, (char *)&size, 2);
read(file, colwidth, sizeof(colwidth));
do
{
if (read(file, (char *)&curcol, 2) <= 0)
break;
read(file, (char *)&currow, 2);
read(file, &format[curcol][currow], 1);
read(file, (char *)&size, 2);
read(file, (char *)&rec, size);
switch (rec.attrib)
{
case TEXT :
if ((allocated = alloctext(curcol, currow, rec.v.text)) == TRUE)
setoflags(curcol, currow, NOUPDATE);
break;
case VALUE :
allocated = allocvalue(curcol, currow, rec.v.value);
break;
case FORMULA :
allocated = allocformula(curcol, currow, rec.v.f.formula, rec.v.f.fvalue);
break;
} /* switch */
if (!allocated)
{
errormsg(MSGFILELOMEM);
lastrow = reallastrow;
lastcol = reallastcol;
format[curcol][currow] = DEFAULTFORMAT;
break;
}
else
{
if (curcol > reallastcol)
reallastcol = curcol;
if (currow > reallastrow)
reallastrow = currow;
}
}
while (TRUE);
writef(0, 24, WHITE, strlen(MSGLOADING), "");
gotoxy(0, 24);
printfreemem();
close(file);
curcol = currow = 0;
setrightcol();
displayscreen(NOUPDATE);
changed = FALSE;
} /* loadsheet */
void savesheet(void)
/* Saves the current spreadsheet */
{
char filename[MAXINPUT+1] = "", eof = 26;
int size, col, row, overwrite, file;
CELLPTR cellptr;
writeprompt(MSGFILENAME);
if (!editstring(filename, "", MAXINPUT))
return;
if (!access(filename, 0))
{
if (!getyesno(&overwrite, MSGOVERWRITE) || (overwrite == 'N'))
return;
}
if ((file = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
S_IREAD | S_IWRITE)) == -1)
{
errormsg(MSGNOOPEN);
return;
}
writef(0, 24, PROMPTCOLOR, 80, MSGSAVING);
gotoxy(strlen(MSGSAVING), 24);
write(file, name, strlen(name) + 1);
write(file, &eof, 1);
write(file, (char *)&lastcol, 2);
write(file, (char *)&lastrow, 2);
size = MAXCOLS;
write(file, (char *)&size, 2);
write(file, colwidth, sizeof(colwidth));
for (row = 0; row <= lastrow; row++)
{
for (col = lastcol; col >= 0; col--)
{
if (cell[col][row] != NULL)
{
cellptr = cell[col][row];
switch(cellptr->attrib)
{
case TEXT :
size = strlen(cellptr->v.text) + 2;
break;
case VALUE :
size = sizeof(double) + 1;
break;
case FORMULA :
size = strlen(cellptr->v.f.formula) + 2 + sizeof(double);
break;
} /* switch */
write(file, (char *)&col, 2);
write(file, (char *)&row, 2);
write(file, (char *)&format[col][row], 1);
write(file, (char *)&size, 2);
write(file, (char *)cellptr, size);
}
}
}
close(file);
writef(0, 24, WHITE, strlen(MSGSAVING), "");
gotoxy(0, 24);
changed = FALSE;
} /* savesheet */
int pagerows(int row, int toppage, int border)
/* Returns the number of rows to print */
{
int rows;
rows = toppage ? 66 - TOPMARGIN : 66;
if (border)
rows--;
if (row + rows - 1 > lastrow)
return(lastrow - row + 1);
else
return(rows);
} /* pagerows */
int pagecols(int col, int border, int columns)
/* Returns the number of columns to print starting at col */
{
int len = ((col == 0) && (border)) ? columns - LEFTMARGIN : columns;
int firstcol = col;
while ((len > 0) && (col <= lastcol))
len -= colwidth[col++];
if (len < 0)
col--;
return(col - firstcol);
} /* pagecols */
void printsheet(void)
/* Prints a copy of the spreadsheet to a file or to the printer */
{
char filename[MAXINPUT + 1] = "", s[133], colstr[MAXCOLWIDTH + 1];
FILE *file;
int columns, counter1, counter2, counter3, col = 0, row, border, toppage,
lcol, lrow, dummy, printed, oldlastcol;
writeprompt(MSGPRINT);
if (!editstring(filename, "", MAXINPUT))
return;
if (filename[0] == 0)
strcpy(filename, "PRN");
if ((file = fopen(filename, "wt")) == NULL)
{
errormsg(MSGNOOPEN);
return;
}
oldlastcol = lastcol;
for (counter1 = 0; counter1 <= lastrow; counter1++)
{
for (counter2 = lastcol; counter2 < MAXCOLS; counter2++)
{
if (format[counter2][counter1] >= OVERWRITE)
lastcol = counter2;
}
}
if (!getyesno(&columns, MSGCOLUMNS))
return;
columns = (columns == 'Y') ? 131 : 79;
if (!getyesno(&border, MSGBORDER))
return;
border = (border == 'Y');
while (col <= lastcol)
{
row = 0;
toppage = TRUE;
lcol = pagecols(col, border, columns) + col;
while (row <= lastrow)
{
lrow = pagerows(row, toppage, border) + row;
printed = 0;
if (toppage)
{
for (counter1 = 0; counter1 < TOPMARGIN; counter1++)
{
fprintf(file, "\n");
printed++;
}
}
for (counter1 = row; counter1 < lrow; counter1++)
{
if ((border) && (counter1 == row) && (toppage))
{
if ((col == 0) && (border))
sprintf(s, "%*s", LEFTMARGIN, "");
else
s[0] = 0;
for (counter3 = col; counter3 < lcol; counter3++)
{
centercolstring(counter3, colstr);
strcat(s, colstr);
}
fprintf(file, "%s\n", s);
printed++;
}
if ((col == 0) && (border))
sprintf(s, "%-*d", LEFTMARGIN, counter1 + 1);
else
s[0] = 0;
for (counter2 = col; counter2 < lcol; counter2++)
strcat(s, cellstring(counter2, counter1, &dummy, FORMAT));
fprintf(file, "%s\n", s);
printed++;
}
row = lrow;
toppage = FALSE;
if (printed < 66)
fprintf(file, "%c", FORMFEED);
}
col = lcol;
}
fclose(file);
lastcol = oldlastcol;
} /* printsheet */
void setcolwidth(int col)
/* Sets the new column width for a selected column */
{
int width, row;
writeprompt(MSGCOLWIDTH);
if (!getint(&width, MINCOLWIDTH, MAXCOLWIDTH))
return;
colwidth[col] = width;
setrightcol();
if (rightcol < col)
{
rightcol = col;
setleftcol();
setrightcol();
}
for (row = 0; row <= lastrow; row++)
{
if ((cell[col][row] != NULL) && (cell[col][row]->attrib == TEXT))
clearoflags(col + 1, row, NOUPDATE);
else
clearoflags(col, row, NOUPDATE);
updateoflags(col, row, NOUPDATE);
}
displayscreen(NOUPDATE);
changed = TRUE;
} /* setcolwidth */
void gotocell()
/* Moves to a selected cell */
{
writeprompt(MSGGOTO);
if (!getcell(&curcol, &currow))
return;
leftcol = curcol;
toprow = currow;
setbottomrow();
setrightcol();
setleftcol();
displayscreen(NOUPDATE);
} /* gotocell */
void formatcells(void)
/* Prompts the user for a selected format and range of cells */
{
int col, row, col1, col2, row1, row2, temp, newformat = 0;
writeprompt(MSGCELL1);
if (!getcell(&col1, &row1))
return;
writeprompt(MSGCELL2);
if (!getcell(&col2, &row2))
return;
if ((col1 != col2) && (row1 != row2))
errormsg(MSGDIFFCOLROW);
else
{
if (col1 > col2)
swap(&col1, &col2);
if (row1 > row2)
swap(&row1, &row2);
if (!getyesno(&temp, MSGRIGHTJUST))
return;
newformat += (temp == 'Y') * RJUSTIFY;
if (!getyesno(&temp, MSGDOLLAR))
return;
newformat += (temp == 'Y') * DOLLAR;
if (!getyesno(&temp, MSGCOMMAS))
return;
newformat += (temp == 'Y') * COMMAS;
if (newformat & DOLLAR)
newformat += 2;
else
{
writeprompt(MSGPLACES);
if (!getint(&temp, 0, MAXPLACES))
return;
newformat += temp;
}
for (col = col1; col <= col2; col++)
{
for (row = row1; row <= row2; row++)
{
format[col][row] = (format[col][row] & OVERWRITE) | newformat;
if ((col >= leftcol) && (col <= rightcol) &&
(row >= toprow) && (row <= bottomrow))
displaycell(col, row, NOHIGHLIGHT, NOUPDATE);
}
}
}
changed = TRUE;
} /* formatcells */
void deletecol(int col)
/* Deletes a column */
{
int counter, row;
for (counter = 0; counter <= lastrow; counter++)
deletecell(col, counter, NOUPDATE);
printfreemem();
if (col != MAXCOLS - 1)
{
movmem(&cell[col + 1][0], &cell[col][0], MAXROWS * sizeof(CELLPTR) *
(MAXCOLS - col - 1));
movmem(&format[col + 1][0], &format[col][0], MAXROWS * (MAXCOLS - col - 1));
movmem(&colwidth[col + 1], &colwidth[col], MAXCOLS - col - 1);
}
setmem(&cell[MAXCOLS - 1][0], MAXROWS * sizeof(CELLPTR), 0);
setmem(&format[MAXCOLS - 1][0], MAXROWS, DEFAULTFORMAT);
colwidth[MAXCOLS - 1] = DEFAULTWIDTH;
if ((lastcol >= col) && (lastcol > 0))
lastcol--;
setrightcol();
if (curcol > rightcol)
{
rightcol++;
setleftcol();
}
clearlastcol();
for (counter = 0; counter <= lastcol; counter++)
{
for (row = 0; row <= lastrow; row++)
{
if ((cell[counter][row] != NULL) &&
(cell[counter][row]->attrib == FORMULA))
fixformula(counter, row, COLDEL, col);
updateoflags(col, row, NOUPDATE);
}
}
while (col <= rightcol)
displaycol(col++, NOUPDATE);
changed = TRUE;
recalc();
} /* deletecol */
void insertcol(int col)
/* Inserts a column */
{
int counter, row;
if (lastcol == MAXCOLS - 1)
{
for (counter = 0; counter <= lastrow; counter++)
deletecell(lastcol, counter, NOUPDATE);
printfreemem();
}
if (col != MAXCOLS - 1)
{
movmem(&cell[col][0], &cell[col + 1][0], MAXROWS * sizeof(CELLPTR) *
(MAXCOLS - col - 1));
movmem(&format[col][0], &format[col + 1][0], MAXROWS * (MAXCOLS - col - 1));
movmem(&colwidth[col], &colwidth[col + 1], MAXCOLS - col - 1);
}
setmem(&cell[col][0], MAXROWS * sizeof(CELLPTR), 0);
setmem(&format[col][0], MAXROWS, DEFAULTFORMAT);
colwidth[col] = DEFAULTWIDTH;
lastcol = MAXCOLS - 1;
setlastcol();
setrightcol();
if (curcol > rightcol)
{
rightcol++;
setleftcol();
}
for (counter = 0; counter <= lastcol; counter++)
{
for (row = 0; row <= lastrow; row++)
{
if ((cell[counter][row] != NULL) &&
(cell[counter][row]->attrib == FORMULA))
fixformula(counter, row, COLADD, col);
updateoflags(col, row, NOUPDATE);
}
}
while (col <= rightcol)
displaycol(col++, NOUPDATE);
changed = TRUE;
recalc();
} /* insertcol */
void deleterow(int row)
/* Deletes a row */
{
int counter, rowc;
for (counter = 0; counter <= lastcol; counter++)
deletecell(counter, row, NOUPDATE);
printfreemem();
if (row != MAXROWS - 1)
{
for (counter = 0; counter < MAXCOLS; counter++)
{
movmem(&cell[counter][row + 1], &cell[counter][row],
sizeof(CELLPTR) * (MAXROWS - row - 1));
movmem(&format[counter][row + 1], &format[counter][row], MAXROWS - row - 1);
}
}
else
{
for (counter = 0; counter <= lastcol; counter++)
{
cell[counter][MAXROWS - 1] = NULL;
format[counter][MAXROWS - 1] = DEFAULTFORMAT;
}
}
if ((lastrow >= row) && (lastrow > 0))
lastrow--;
for (counter = 0; counter <= lastcol; counter++)
{
for (rowc = 0; rowc <= lastrow; rowc++)
{
if ((cell[counter][rowc] != NULL) &&
(cell[counter][rowc]->attrib == FORMULA))
fixformula(counter, rowc, ROWDEL, row);
}
}
while (row <= bottomrow)
displayrow(row++, NOUPDATE);
changed = TRUE;
recalc();
} /* deleterow */
void insertrow(int row)
/* Inserts a row */
{
int counter, rowc;
if (lastrow == MAXROWS - 1)
{
for (counter = 0; counter <= lastcol; counter++)
deletecell(counter, lastrow, NOUPDATE);
printfreemem();
}
if (row != MAXROWS - 1)
{
for (counter = 0; counter < MAXCOLS; counter++)
{
movmem(&cell[counter][row], &cell[counter][row + 1],
sizeof(CELLPTR) * (MAXROWS - row - 1));
movmem(&format[counter][row], &format[counter][row + 1], MAXROWS - row - 1);
}
}
for (counter = 0; counter <= lastcol; counter++)
{
cell[counter][row] = NULL;
format[counter][row] = DEFAULTFORMAT;
}
lastrow = MAXROWS - 1;
setlastrow();
for (counter = 0; counter <= lastcol; counter++)
{
for (rowc = 0; rowc <= lastrow; rowc++)
{
if ((cell[counter][rowc] != NULL) &&
(cell[counter][rowc]->attrib == FORMULA))
fixformula(counter, rowc, ROWADD, row);
}
}
while (row <= bottomrow)
displayrow(row++, NOUPDATE);
changed = TRUE;
recalc();
} /* insertrow */
void smenu(void)
/* Executes the commands in the spreadsheet menu */
{
char filename[MAXINPUT + 1] = "";
switch(getcommand(SMENU, SCOMMAND))
{
case 0 :
checkforsave();
loadsheet(filename);
break;
case 1 :
savesheet();
break;
case 2 :
printsheet();
break;
case 3 :
checkforsave();
clearsheet();
break;
} /* switch */
} /* smenu */
void cmenu(void)
/* Executes the commands in the column menu */
{
switch(getcommand(CMENU, CCOMMAND))
{
case 0 :
insertcol(curcol);
break;
case 1 :
deletecol(curcol);
break;
case 2 :
setcolwidth(curcol);
break;
} /* switch */
} /* cmenu */
void rmenu(void)
/* Executes the commands in the row menu */
{
switch(getcommand(RMENU, RCOMMAND))
{
case 0 :
insertrow(currow);
break;
case 1 :
deleterow(currow);
break;
} /* switch */
} /* rmenu */
void umenu(void)
/* Executes the commands in the utility menu */
{
switch(getcommand(UMENU, UCOMMAND))
{
case 0 :
recalc();
break;
case 1 :
changeformdisplay(!formdisplay);
displayscreen(UPDATE);
break;
} /* switch */
} /* umenu */
void mainmenu(void)
/* Executes the commands in the main menu */
{
switch(getcommand(MENU, COMMAND))
{
case 0 :
smenu();
break;
case 1 :
formatcells();
break;
case 2 :
deletecell(curcol, currow, UPDATE);
printfreemem();
if (autocalc)
recalc();
break;
case 3 :
gotocell();
break;
case 4 :
cmenu();
break;
case 5 :
rmenu();
break;
case 6 :
editcell(curcell);
break;
case 7 :
umenu();
break;
case 8 :
changeautocalc(!autocalc);
break;
case 9 :
checkforsave();
stop = TRUE;
break;
} /* switch */
} /* mainmenu */


View File

@ -0,0 +1,609 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include "mcalc.h"
#define PLUS 0
#define MINUS 1
#define TIMES 2
#define DIVIDE 3
#define EXP 4
#define COLON 5
#define OPAREN 6
#define CPAREN 7
#define NUM 8
#define CELL 9
#define FUNC 10
#define EOLN 11
#define BAD 12
#define MAXFUNCNAMELEN 5
struct TOKENREC
{
char state;
union
{
double value;
struct
{
int row, col;
} c;
char funcname[MAXFUNCNAMELEN + 1];
} x;
};
static struct TOKENREC stack[PARSERSTACKSIZE], curtoken;
int stacktop, tokentype, error;
char *input, isformula;
#pragma warn -par
int matherr(struct exception *e)
{
e->retval = HUGE_VAL;
return(1);
} /* matherr */
#pragma warn +par
int isfunc(char *s)
/* Checks to see if the string is a legal function. Returns TRUE if it is,
FALSE otherwise.
*/
{
int len = strlen(s);
if (strncmp(s, input, len) == 0)
{
strncpy(curtoken.x.funcname, input, len);
curtoken.x.funcname[len] = 0;
input += len;
return(TRUE);
}
return(FALSE);
} /* isfunc */
int nexttoken(void)
/* Gets the next token from the input stream */
{
char *start, numstring[80];
int decimal, len, numlen;
while (*input == ' ')
input++;
if (*input == 0)
return(EOLN);
if (strchr("0123456789.", *input))
{
start = input;
len = 0;
decimal = FALSE;
while ((isdigit(*input)) ||
((*input == '.') && (!decimal)))
{
if (*input == '.')
decimal = TRUE;
input++;
len++;
}
if ((len == 1) && (start[0] == '.'))
return(BAD);
if (*input == 'E')
{
input++;
len++;
if (strchr("+-", *input) != NULL)
{
input++;
len++;
}
numlen = 0;
while ((isdigit(*input)) && (++numlen <= 3))
{
input++;
len++;
}
}
strncpy(numstring, start, len);
numstring[len] = 0;
curtoken.x.value = atof(numstring);
if (errno == ERANGE)
return(BAD);
return(NUM);
}
else if (isalpha(*input))
{
if (isfunc("ABS") ||
isfunc("ACOS") ||
isfunc("ASIN") ||
isfunc("ATAN") ||
isfunc("COSH") ||
isfunc("COS") ||
isfunc("EXP") ||
isfunc("LOG10") ||
isfunc("LOG") ||
isfunc("POW10") ||
isfunc("ROUND") ||
isfunc("SINH") ||
isfunc("SIN") ||
isfunc("SQRT") ||
isfunc("SQR") ||
isfunc("TANH") ||
isfunc("TAN") ||
isfunc("TRUNC"))
return(FUNC);
if (formulastart(&input, &curtoken.x.c.col, &curtoken.x.c.row))
{
isformula = TRUE;
return(CELL);
}
else
return(BAD);
}
else switch(*(input++))
{
case '+' : return(PLUS);
case '-' : return(MINUS);
case '*' : return(TIMES);
case '/' : return(DIVIDE);
case '^' : return(EXP);
case ':' : return(COLON);
case '(' : return(OPAREN);
case ')' : return(CPAREN);
default : return(BAD);
} /* switch */
} /* nexttoken */
void push(struct TOKENREC token)
/* Pushes a new token onto the stack */
{
if (stacktop == PARSERSTACKSIZE - 1)
{
errormsg(MSGSTACKERROR);
error = TRUE;
}
else
stack[++stacktop] = token;
} /* push */
struct TOKENREC pop(void)
/* Pops the top token off of the stack */
{
return(stack[stacktop--]);
} /* pop */
int gotostate(int production)
/* Finds the new state based on the just-completed production and the
top state.
*/
{
int state = stack[stacktop].state;
if (production <= 3)
{
switch(state)
{
case 0 : return(1);
case 9 : return(19);
case 20 : return(28);
} /* switch */
}
else if (production <= 6)
{
switch(state)
{
case 0 :
case 9 :
case 20 : return(2);
case 12 : return(21);
case 13 : return(22);
} /* switch */
}
else if (production <= 8)
{
switch(state)
{
case 0 :
case 9 :
case 12 :
case 13 :
case 20 : return(3);
case 14 : return(23);
case 15 : return(24);
case 16 : return(25);
} /* switch */
}
else if (production <= 10)
{
switch(state)
{
case 0 :
case 9 :
case 12 :
case 13 :
case 14 :
case 15 :
case 16 :
case 20 : return(4);
} /* switch */
}
else if (production <= 12)
{
switch(state)
{
case 0 :
case 9 :
case 12 :
case 13 :
case 14 :
case 15 :
case 16 :
case 20 : return(6);
case 5 : return(17);
} /* switch */
}
else
{
switch(state)
{
case 0 :
case 5 :
case 9 :
case 12 :
case 13 :
case 14 :
case 15 :
case 16 :
case 20 : return(8);
} /* switch */
}
return(30);
} /* gotostate */
double cellvalue(int col, int row)
/* Finds the value of a particular cell */
{
if (cell[col][row] == NULL)
return(0);
if (cell[col][row]->attrib == TEXT)
return(HUGE_VAL);
if (cell[col][row]->attrib == FORMULA)
return(cell[col][row]->v.f.fvalue);
return(cell[col][row]->v.value);
} /* cellvalue */
void shift(int state)
/* Shifts a token onto the stack */
{
curtoken.state = state;
push(curtoken);
tokentype = nexttoken();
} /* shift */
void reduce(int reduction)
/* Completes a reduction */
{
struct TOKENREC token1, token2;
int counter;
switch (reduction)
{
case 1 :
token1 = pop();
pop();
token2 = pop();
curtoken.x.value = token1.x.value + token2.x.value;
break;
case 2 :
token1 = pop();
pop();
token2 = pop();
curtoken.x.value = token2.x.value - token1.x.value;
break;
case 4 :
token1 = pop();
pop();
token2 = pop();
curtoken.x.value = token1.x.value * token2.x.value;
break;
case 5 :
token1 = pop();
pop();
token2 = pop();
if (token1.x.value == 0)
curtoken.x.value = HUGE_VAL;
else
curtoken.x.value = token2.x.value / token1.x.value;
break;
case 7 :
token1 = pop();
pop();
token2 = pop();
curtoken.x.value = pow(token2.x.value, token1.x.value);
break;
case 9 :
token1 = pop();
pop();
curtoken.x.value = -token1.x.value;
break;
case 11 :
token1 = pop();
pop();
token2 = pop();
curtoken.x.value = 0;
if (token1.x.c.row == token2.x.c.row)
{
if (token1.x.c.col < token2.x.c.col)
error = TRUE;
else
{
for (counter = token2.x.c.col; counter <= token1.x.c.col; counter++)
curtoken.x.value += cellvalue(counter, token1.x.c.row);
}
}
else if (token1.x.c.col == token2.x.c.col)
{
if (token1.x.c.row < token2.x.c.row)
error = TRUE;
else
{
for (counter = token2.x.c.row; counter <= token1.x.c.row; counter++)
curtoken.x.value += cellvalue(token1.x.c.col, counter);
}
}
else
error = TRUE;
break;
case 13 :
curtoken = pop();
curtoken.x.value = cellvalue(curtoken.x.c.col, curtoken.x.c.row);
break;
case 14 :
pop();
curtoken = pop();
pop();
break;
case 16 :
pop();
curtoken = pop();
pop();
token1 = pop();
if (strcmp(token1.x.funcname, "ABS") == 0)
curtoken.x.value = fabs(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ACOS") == 0)
curtoken.x.value = acos(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ASIN") == 0)
curtoken.x.value = asin(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ATAN") == 0)
curtoken.x.value = atan(curtoken.x.value);
else if (strcmp(token1.x.funcname, "COSH") == 0)
curtoken.x.value = cosh(curtoken.x.value);
else if (strcmp(token1.x.funcname, "COS") == 0)
curtoken.x.value = cos(curtoken.x.value);
else if (strcmp(token1.x.funcname, "EXP") == 0)
curtoken.x.value = exp(curtoken.x.value);
else if (strcmp(token1.x.funcname, "LOG10") == 0)
curtoken.x.value = log10(curtoken.x.value);
else if (strcmp(token1.x.funcname, "LOG") == 0)
curtoken.x.value = log(curtoken.x.value);
else if (strcmp(token1.x.funcname, "ROUND") == 0)
curtoken.x.value = (int)(curtoken.x.value + 0.5);
else if (strcmp(token1.x.funcname, "POW10") == 0)
curtoken.x.value = pow10(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SINH") == 0)
curtoken.x.value = sinh(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SIN") == 0)
curtoken.x.value = sin(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SQRT") == 0)
curtoken.x.value = sqrt(curtoken.x.value);
else if (strcmp(token1.x.funcname, "SQR") == 0)
curtoken.x.value *= curtoken.x.value;
else if (strcmp(token1.x.funcname, "TANH") == 0)
curtoken.x.value = tanh(curtoken.x.value);
else if (strcmp(token1.x.funcname, "TAN") == 0)
curtoken.x.value = tan(curtoken.x.value);
else if (strcmp(token1.x.funcname, "TRUNC") == 0)
curtoken.x.value = (int)curtoken.x.value;
break;
case 3 :
case 6 :
case 8 :
case 10 :
case 12 :
case 15 :
curtoken = pop();
break;
} /* switch */
curtoken.state = gotostate(reduction);
push(curtoken);
} /* reduce */
double parse(char *s, int *att)
/* Parses the string s - returns the value of the evaluated string, and puts
the attribute in att: TEXT = 0, CONSTANT = 1, FORMULA = 2.
*/
{
struct TOKENREC firsttoken;
char accepted = FALSE;
char copy[80];
error = FALSE;
isformula = FALSE;
input = copy;
strupr(strcpy(copy, s));
stacktop = -1;
firsttoken.state = 0;
firsttoken.x.value = 0;
push(firsttoken);
tokentype = nexttoken();
do
{
switch (stack[stacktop].state)
{
case 0 :
case 9 :
case 12 :
case 13 :
case 14 :
case 15 :
case 16 :
case 20 :
if (tokentype == NUM)
shift(10);
else if (tokentype == CELL)
shift(7);
else if (tokentype == FUNC)
shift(11);
else if (tokentype == MINUS)
shift(5);
else if (tokentype == OPAREN)
shift(9);
else
error = TRUE;
break;
case 1 :
if (tokentype == EOLN)
accepted = TRUE;
else if (tokentype == PLUS)
shift(12);
else if (tokentype == MINUS)
shift(13);
else
error = TRUE;
break;
case 2 :
if (tokentype == TIMES)
shift(14);
else if (tokentype == DIVIDE)
shift(15);
else
reduce(3);
break;
case 3 :
reduce(6);
break;
case 4 :
if (tokentype == EXP)
shift(16);
else
reduce(8);
break;
case 5 :
if (tokentype == NUM)
shift(10);
else if (tokentype == CELL)
shift(7);
else if (tokentype == FUNC)
shift(11);
else if (tokentype == OPAREN)
shift(9);
else
error = TRUE;
break;
case 6 :
reduce(10);
break;
case 7 :
if (tokentype == COLON)
shift(18);
else
reduce(13);
break;
case 8 :
reduce(12);
break;
case 10 :
reduce(15);
break;
case 11 :
if (tokentype == OPAREN)
shift(20);
else
error = TRUE;
break;
case 17 :
reduce(9);
break;
case 18 :
if (tokentype == CELL)
shift(26);
else
error = TRUE;
break;
case 19 :
if (tokentype == PLUS)
shift(12);
else if (tokentype == MINUS)
shift(13);
else if (tokentype == CPAREN)
shift(27);
else
error = TRUE;
break;
case 21 :
if (tokentype == TIMES)
shift(14);
else if (tokentype == DIVIDE)
shift(15);
else
reduce(1);
break;
case 22 :
if (tokentype == TIMES)
shift(14);
else if (tokentype == DIVIDE)
shift(15);
else
reduce(2);
break;
case 23 :
reduce(4);
break;
case 24 :
reduce(5);
break;
case 25 :
reduce(7);
break;
case 26 :
reduce(11);
break;
case 27 :
reduce(14);
break;
case 28 :
if (tokentype == PLUS)
shift(12);
else if (tokentype == MINUS)
shift(13);
else if (tokentype == CPAREN)
shift(29);
else
error = TRUE;
break;
case 29 :
reduce(16);
break;
case 30 :
error = TRUE;
break;
} /* switch */
}
while ((!accepted) && (!error));
if (error)
{
*att = TEXT;
return(0);
}
if (isformula)
*att = FORMULA;
else
*att = VALUE;
strcpy(s, copy);
return(stack[stacktop].x.value);
} /* parse */


623
Borland Turbo C v1/MCUTIL.C Normal file
View File

@ -0,0 +1,623 @@
/* Turbo C - (C) Copyright 1987 by Borland International */
#include <math.h>
#include <alloc.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <mem.h>
#include <stdio.h>
#include "mcalc.h"
int alloctext(int col, int row, char *s)
/* Allocates space for a text cell */
{
int size;
CELLPTR cellptr;
if (memleft < (size = textcellsize(s)))
return(FALSE);
memleft -= size;
cellptr = (CELLPTR)(malloc(strlen(s) + 2));
cellptr->attrib = TEXT;
strcpy(cellptr->v.text, s);
cell[col][row] = cellptr;
return(TRUE);
} /* alloctext */
int allocvalue(int col, int row, double amt)
/* Allocates space for a value cell */
{
CELLPTR cellptr;
if (memleft < valuecellsize)
return(FALSE);
memleft -= valuecellsize;
cellptr = (CELLPTR)(malloc(sizeof(double) + 1));
cellptr->attrib = VALUE;
cellptr->v.value = amt;
cell[col][row] = cellptr;
return(TRUE);
} /* allocvalue */
int allocformula(int col, int row, char *s, double amt)
/* Allocates space for a formula cell */
{
int size;
CELLPTR cellptr;
if (memleft < (size = formulacellsize(s)))
return(FALSE);
memleft -= size;
cellptr = (CELLPTR)(malloc(strlen(s) + sizeof(double) + 2));
cellptr->attrib = FORMULA;
strcpy(cellptr->v.f.formula, s);
cellptr->v.f.fvalue = amt;
cell[col][row] = cellptr;
return(TRUE);
} /* allocformula */
void deletecell(int col, int row, int display)
/* Deletes a cell */
{
CELLPTR cellptr = cell[col][row];
if (cellptr == NULL)
return;
switch (cellptr->attrib)
{
case TEXT :
memleft += textcellsize(cellptr->v.text);
clearoflags(col + 1, row, display);
break;
case VALUE :
memleft += valuecellsize;
break;
case FORMULA :
memleft += formulacellsize(cellptr->v.f.formula);
break;
} /* switch */
format[col][row] &= ~OVERWRITE;
free(cell[col][row]);
cell[col][row] = NULL;
if (col == lastcol)
setlastcol();
if (row == lastrow)
setlastrow();
updateoflags(col, row, display);
changed = TRUE;
} /* deletecell */
void printfreemem(void)
/* Prints the amount of free memory */
{
writef(strlen(MSGMEMORY) + 1, 0, MEMORYCOLOR, 6, "%6ld", memleft);
} /* printfreemem */
int rowwidth(int row)
/* Returns the width in spaces of row */
{
return((row == 0) ? 1 : (int)log10(row + 1) + 1);
} /* rowwidth */
int formulastart(char **input, int *col, int *row)
/* Returns TRUE if the string is the start of a formula, FALSE otherwise.
Also returns the column and row of the formula.
*/
{
int len, maxlen = rowwidth(MAXROWS);
char *start, numstring[10];
if (!isalpha(**input))
return(FALSE);
*col = *((*input)++) - 'A';
if (isalpha(**input))
{
*col *= 26;
*col += *((*input)++) - 'A' + 26;
}
if (*col >= MAXCOLS)
return(FALSE);
start = *input;
for (len = 0; len < maxlen; len++)
{
if (!isdigit(*((*input)++)))
{
(*input)--;
break;
}
}
if (len == 0)
return(FALSE);
strncpy(numstring, start, len);
numstring[len] = 0;
*row = atoi(numstring) - 1;
if ((*row >= MAXROWS) || (*row == -1))
return(FALSE);
return(TRUE);
} /* formulastart */
void errormsg(char *s)
/* Prints an error message at the bottom of the screen */
{
printf("%c", 7); /* Beeps the speaker */
writef(0, 24, ERRORCOLOR, 80, "%s %s", s, MSGKEYPRESS);
gotoxy(strlen(s) + strlen(MSGKEYPRESS) + 2, 24);
getkey();
gotoxy(0, 24);
writef(0, 24, WHITE, 80, "");
} /* errormsg */
void fixformula(int col, int row, int action, int place)
/* Modifies a formula when its column or row designations need to change. */
{
char *colstart, *rowstart, s[6], newformula[MAXINPUT + 1],
*curpos = newformula;
int fcol, frow;
CELLPTR cellptr = cell[col][row];
double value;
strcpy(newformula, cellptr->v.f.formula);
while (*curpos != 0)
{
if (formulastart(&curpos, &fcol, &frow))
{
rowstart = curpos - rowwidth(frow);
colstart = rowstart - ((fcol > 25) ? 2 : 1);
switch (action)
{
case COLADD :
if (fcol < place)
break;
if (fcol == 25)
{
if (strlen(newformula) == MAXINPUT)
{
deletecell(col, row, NOUPDATE);
alloctext(col, row, newformula);
return;
}
movmem(colstart, colstart + 1, strlen(colstart) + 1);
}
colstring(fcol + 1, s);
movmem(s, colstart, strlen(s));
break;
case ROWADD :
if (frow < place)
break;
if (rowwidth(frow + 1) != rowwidth(frow))
{
if (strlen(newformula) == MAXINPUT)
{
deletecell(col, row, NOUPDATE);
alloctext(col, row, newformula);
return;
}
movmem(rowstart, rowstart + 1, strlen(rowstart) + 1);
}
sprintf(s, "%d", frow + 2);
movmem(s, rowstart, strlen(s));
break;
case COLDEL :
if (fcol <= place)
break;
if (fcol == 26)
movmem(colstart + 1, colstart, strlen(colstart) + 1);
colstring(fcol - 1, s);
movmem(s, colstart, strlen(s));
break;
case ROWDEL :
if (frow <= place)
break;
if (rowwidth(frow) != rowwidth(frow - 1))
movmem(rowstart + 1, rowstart, strlen(rowstart) + 1);
sprintf(s, "%d", frow);
movmem(s, rowstart, strlen(s));
break;
} /* switch */
}
else
curpos++;
}
if (strlen(newformula) != strlen(cellptr->v.f.formula))
{
value = cellptr->v.f.fvalue;
deletecell(col, row, NOUPDATE);
allocformula(col, row, newformula, value);
}
else
strcpy(cellptr->v.f.formula, newformula);
} /* fixformula */
void colstring(int col, char *colstr)
/* Changes a column number to a string */
{
setmem(colstr, 3, 0);
if (col < 26)
colstr[0] = col + 'A';
else
{
colstr[0] = (col / 26) - 1 + 'A';
colstr[1] = (col % 26) + 'A';
}
} /* colstring */
void centercolstring(int col, char *colstr)
/* Changes a column to a centered string */
{
char s[3];
int spaces1, spaces2;
colstring(col, s);
spaces1 = (colwidth[col] - strlen(s)) >> 1;
spaces2 = colwidth[col] - strlen(s) - spaces1;
sprintf(colstr, "%*s%s%*s", spaces1, "", s, spaces2, "");
} /* centercolstring */
void setleftcol(void)
/* Sets the value of leftcol based on the value of rightcol */
{
int total = 80, col = 0;
while ((total >= LEFTMARGIN) && (rightcol - col >= 0))
{
colstart[SCREENCOLS - col - 1] = total - colwidth[rightcol - col];
total -= colwidth[rightcol - col++];
}
if (total >= LEFTMARGIN)
col++;
movmem(&colstart[SCREENCOLS - col + 1], colstart, col - 1);
leftcol = rightcol - col + 2;
total = colstart[0] - LEFTMARGIN;
if (total != 0)
{
for (col = leftcol; col <= rightcol; col++)
colstart[col - leftcol] -= total;
}
printcol();
} /* setleftcol */
void setrightcol(void)
/* Sets the value of rightcol based on the value of leftcol */
{
int total = LEFTMARGIN, col = 0;
do
{
colstart[col] = total;
total += colwidth[leftcol + col++];
}
while ((total <= 80) && (leftcol + col <= MAXCOLS));
rightcol = leftcol + col - 2;
printcol();
} /* setrightcol */
void settoprow(void)
/* Figures out the value of toprow based on the value of bottomrow */
{
if (bottomrow - SCREENROWS < -1)
bottomrow = 19;
toprow = bottomrow - 19;
printrow();
} /* settoprow */
void setbottomrow(void)
/* Figures out the value of bottomrow based on the value of toprow */
{
if (toprow + SCREENROWS > MAXROWS)
toprow = MAXROWS - 20;
bottomrow = toprow + 19;
printrow();
} /* setbottomrow */
void setlastcol(void)
/* Sets the value of lastcol based on the current value */
{
register int row, col;
for (col = lastcol; col >= 0; col--)
{
for (row = 0; row <= lastrow; row++)
{
if (cell[col][row] != NULL)
{
lastcol = col;
return;
}
}
}
lastcol = 0;
} /* setlastcol */
void setlastrow(void)
/* Sets the value of lastrow based on the current value */
{
register int row, col;
for (row = lastrow; row >= 0; row--)
{
for (col = 0; col <= lastcol; col++)
{
if (cell[col][row] != NULL)
{
lastrow = row;
return;
}
}
}
lastrow = 0;
} /* setlastrow */
void act(char *s)
/* Acts on a particular input */
{
int attrib, allocated;
double value;
deletecell(curcol, currow, UPDATE);
value = parse(s, &attrib);
switch(attrib)
{
case TEXT :
allocated = alloctext(curcol, currow, s);
if (allocated)
displaycell(curcol, currow, NOHIGHLIGHT, NOUPDATE);
break;
case VALUE :
allocated = allocvalue(curcol, currow, value);
break;
case FORMULA :
allocated = allocformula(curcol, currow, s, value);
break;
} /* switch */
if (allocated)
{
format[curcol][currow] &= ~OVERWRITE;
clearoflags(curcol + 1, currow, UPDATE);
if (attrib == TEXT)
setoflags(curcol, currow, UPDATE);
if (curcol > lastcol)
lastcol = curcol;
if (currow > lastrow)
lastrow = currow;
if (autocalc)
recalc();
}
else
errormsg(MSGLOMEM);
printfreemem();
} /* act */
int setoflags(int col, int row, int display)
/* Sets the overwrite flag on cells starting at (col + 1, row) - returns
the number of the column after the last column set.
*/
{
int len;
len = strlen(cell[col][row]->v.text) - colwidth[col];
while ((++col < MAXCOLS) && (len > 0) && (cell[col][row] == NULL))
{
format[col][row] |= OVERWRITE;
len -= colwidth[col];
if (display && (col >= leftcol) && (col <= rightcol))
displaycell(col, row, NOHIGHLIGHT, NOUPDATE);
}
return(col);
} /* setoflags */
void clearoflags(int col, int row, int display)
/* Clears the overwrite flag on cells starting at (col, row) */
{
while ((format[col][row] >= OVERWRITE) && (col < MAXCOLS) &&
(cell[col][row] == NULL))
{
format[col][row] &= ~OVERWRITE;
if (display && (col >= leftcol) && (col <= rightcol))
displaycell(col, row, NOHIGHLIGHT, NOUPDATE);
col++;
}
} /* clearoflags */
void updateoflags(int col, int row, int display)
/* Starting in col, moves back to the last TEXT cell and updates all flags */
{
while ((cell[col][row] == NULL) && (col-- > 0));
if ((cell[col][row]->attrib == TEXT) && (col >= 0))
setoflags(col, row, display);
} /* updateoflags */
void textstring(char *instring, char *outstring, int col, int fvalue,
int formatting)
/* Sets the string representation of text */
{
char *just, *ljust = "%-*s", *rjust = "%*s";
if ((fvalue & RJUSTIFY) && (formatting))
just = rjust;
else
just = ljust;
sprintf(outstring, just, colwidth[col], instring);
if (formatting)
outstring[colwidth[col]] = 0;
} /* textstring */
void valuestring(CELLPTR cellptr, double value, char *vstring, int col,
int fvalue, int *color, int formatting)
/* Sets the string representation of a value */
{
char s[81];
char *fstring;
char *fdollar = " $%*s";
char *fnormal = "%*s";
int width, pos;
if (value == HUGE_VAL)
{
strcpy(vstring, MSGERROR);
*color = ERRORCOLOR;
}
else
{
if (formatting)
{
if (fvalue & DOLLAR)
{
fstring = fdollar;
width = colwidth[col] - 2;
}
else
{
fstring = fnormal;
width = colwidth[col];
}
sprintf(s, "%*.*f", 1, fvalue & 15, cellptr->v.value);
if (fvalue & COMMAS)
{
pos = strcspn(s, ".");
while (pos > 3)
{
pos -= 3;
movmem(&s[pos], &s[pos + 1], strlen(s) - pos + 1);
s[pos] = ',';
}
}
sprintf(vstring, fstring, width, s);
}
else
sprintf(vstring, "%.*f", MAXPLACES, value);
*color = VALUECOLOR;
}
} /* valuestring */
char *cellstring(int col, int row, int *color, int formatting)
/* Creates an output string for the data in the cell in (col, row), and
also returns the color of the cell */
{
CELLPTR cellptr = cell[col][row];
int newcol, formatvalue;
static char s[81], temp[MAXCOLWIDTH + 1];
char *p;
double value;
if (cellptr == NULL)
{
if (!formatting || (format[col][row] < OVERWRITE))
{
sprintf(s, "%*s", colwidth[col], "");
*color = BLANKCOLOR;
}
else
{
newcol = col;
while (cell[--newcol][row] == NULL);
p = cell[newcol][row]->v.text;
while (newcol < col)
p += colwidth[newcol++];
strncpy(temp, p, colwidth[col]);
temp[colwidth[col]] = 0;
sprintf(s, "%s%*s", temp, colwidth[col] - strlen(temp), "");
*color = TEXTCOLOR;
}
}
else
{
formatvalue = format[col][row];
switch (cellptr->attrib)
{
case TEXT :
textstring(cellptr->v.text, s, col, formatvalue, formatting);
*color = TEXTCOLOR;
break;
case FORMULA :
if (formdisplay)
{
textstring(cellptr->v.f.formula, s, col, formatvalue, formatting);
*color = FORMULACOLOR;
break;
}
else
value = cellptr->v.f.fvalue;
case VALUE :
if (cellptr->attrib == VALUE)
value = cellptr->v.value;
valuestring(cellptr, value, s, col, formatvalue, color,
formatting);
break;
} /* switch */
}
return(s);
} /* cellstring */
void writeprompt(char *prompt)
/* Prints a prompt on the screen */
{
writef(0, 23, PROMPTCOLOR, 80, prompt);
} /* writeprompt */
int getyesno(int *yesno, char *prompt)
/* Prints a prompt and gets a yes or no answer - returns TRUE if ESC was
pressed, FALSE if not.
*/
{
writeprompt(prompt);
do
{
*yesno = toupper(getkey());
if (*yesno == ESC)
return(FALSE);
}
while (strchr("YN", *yesno) == NULL);
return(TRUE);
} /* getyesno */
void swap(int *val1, int *val2)
/* Swaps the first and second values */
{
int temp;
temp = *val1;
*val1 = *val2;
*val2 = temp;
} /* swap */
void checkforsave(void)
/* If the spreadsheet has been changed, will ask the user if they want to
save it.
*/
{
int save;
if (changed && getyesno(&save, MSGSAVESHEET) && (save == 'Y'))
savesheet();
} /* checkforsave */
void initvars(void)
/* Initializes various global variables */
{
leftcol = toprow = curcol = currow = lastcol = lastrow = 0;
setmem(colwidth, sizeof(colwidth), DEFAULTWIDTH);
setmem(cell, sizeof(cell), 0);
setmem(format, sizeof(format), DEFAULTFORMAT);
} /* initvars */
int getcommand(char *msgstr, char *comstr)
/* Reads in a command and acts on it */
{
int ch, counter, len = strlen(msgstr);
scroll(UP, 0, 0, 23, 79, 23, WHITE);
for (counter = 0; counter < len; counter++)
{
if (isupper(msgstr[counter]))
writef(counter, 23, COMMANDCOLOR, 1, "%c", msgstr[counter]);
else
writef(counter, 23, LOWCOMMANDCOLOR, 1, "%c", msgstr[counter]);
}
do
ch = toupper(getkey());
while ((strchr(comstr, ch) == NULL) && (ch != ESC));
clearinput();
return((ch == ESC) ? -1 : strlen(comstr) - strlen(strchr(comstr, ch)));
} /* getcommand */


26
Borland Turbo C v1/MEM.H Normal file
View File

@ -0,0 +1,26 @@
/* mem.h
Memory manipulation functions
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
void *_Cdecl memchr(void *s, unsigned char c, unsigned n);
int _Cdecl memcmp(void *s1, void *s2, unsigned n);
void *_Cdecl memcpy(void *dest, void *src, unsigned n);
void *_Cdecl memset(void *s, unsigned char c, unsigned n);
void *_Cdecl memccpy(void *dest, void *src, unsigned char c, unsigned n);
void *_Cdecl memmove(void *dest, void *src, unsigned n);
int _Cdecl memicmp(void *s1, void *s2, unsigned n);
void _Cdecl movebytes(void *src, void *dst, unsigned n);
void _Cdecl movedata(unsigned srcseg, unsigned srcoff, unsigned dstseg,
unsigned dstoff, unsigned n);
void _Cdecl movmem(void *src, void *dest, unsigned length);
void _Cdecl setmem(void *dest, unsigned length, char value);


View File

@ -0,0 +1,80 @@
database
barchart(integer)
chartbar(integer,integer,integer,integer,integer,integer)
global predicates
bar(integer,integer,integer,integer,integer)-(i,i,i,i,i) language c
predicates
process(char)
repeat
retractall
drawbar(integer,integer,integer,integer)
goal
graphics(1,0,0),
asserta(barchart(0)),
makewindow(1,1,1,"Bar",0,0,20,40),
makewindow(2,1,1,"",20,0,4,40),
repeat,
write("Press any key to continue"), readchar(_),
clearwindow,
makewindow(1,1,1,"Bar",0,0,20,40),
write("m. Make a bar Chart.\n"),
write("s. Save your bar Chart.\n"),
write("l. Load your bar Chart.\n"),
write("d. Draw your bar Chart.\n"),
write("e. End\nEnter Choice: "),
readchar(Choice),
clearwindow,
shiftwindow(2),
process(Choice),
bios(16,reg(3,0,0,0,0,0,0,0),_).
clauses
process('m'):-
barchart(Nu),
retract(barchart(Nu)),
NewNu = Nu+1,
asserta(barchart(NewNu)),
write("Enter the number of bars: "),
readint(NuOfBars),clearwindow,
write("Enter max value on Y scale: "),
readint(Max),clearwindow,
YScale = 140/Max,
Width = 265/NuOfBars,
Start = 305-Width,
clearwindow,
drawbar(NuOfBars, Width, Start, Yscale),
fail.
process('s'):-
write("Enter file name of chart: "),readln(Name),
concat(Name,".CHT",FName),save(Fname),fail.
process('l'):-
retractall,
write("Enter file name of chart: "),readln(Name),
concat(Name,".CHT",FName),consult(FName),fail.
process('d'):-
barchart(Chart),
chartbar(Chart,XPosition,Ypos,Width,YBarSize,1),
bar(XPosition,Ypos,Width,YBarSize,1),fail.
process('e').
drawbar(0,_,_,_):-!.
drawbar(Nu,Width,XPosition,Yscale):-
XNuNew=Nu-1,clearwindow,
write("Enter the value associated bar ",Nu ,": "),
readint(Y),
YBarSize=Y*YScale,
Ypos=140 - YBarSize,
bar(XPosition,Ypos,Width,YBarSize,1),
barchart(Chart),
asserta(chartbar(Chart,XPosition,Ypos,Width,YBarSize,1)),
XNewPos= XPosition-Width-5,
drawbar(XNuNew,Width,XNewPos,Yscale).
repeat.
repeat:- repeat.
retractall:- retract(_),fail.
retractall.

View File

@ -0,0 +1,52 @@
/* process.h
Symbols and structures for process management.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
/* Modes available as first argument to the spawnxx functions. */
#define P_WAIT 0 /* child runs separately, parent waits until exit */
#define P_NOWAIT 1 /* both concurrent -- not implemented */
#define P_OVERLAY 2 /* child replaces parent, parent no longer exists */
/* MSDOS does not have any abstract identifier for a process, but the
process Program Segment Prefix location provides a similar token.
*/
#ifndef _psp
extern unsigned _Cdecl _psp; /* provided unconditionally in dos.h */
#endif
#define getpid() (_psp)
void _Cdecl abort(void);
int _Cdecl execl(char *path, char *arg0, ...);
int _Cdecl execle(char *path, char *arg0, ...);
int _Cdecl execlp(char *path, char *arg0, ...);
int _Cdecl execlpe(char *path, char *arg0, ...);
int _Cdecl execv(char *path, char *argv[]);
int _Cdecl execve(char *path, char *argv[], char **env);
int _Cdecl execvp(char *path, char *argv[]);
int _Cdecl execvpe(char *path, char *argv[], char **env);
void _Cdecl exit(int status);
void _Cdecl _exit(int status);
int _Cdecl spawnl(int mode, char *path, char *arg0, ...);
int _Cdecl spawnle(int mode, char *path, char *arg0, ...);
int _Cdecl spawnlp(int mode, char *path, char *arg0, ...);
int _Cdecl spawnlpe(int mode, char *path, char *arg0, ...);
int _Cdecl spawnv(int mode, char *path, char *argv[]);
int _Cdecl spawnve(int mode, char *path, char *argv[], char **env);
int _Cdecl spawnvp(int mode, char *path, char *argv[]);
int _Cdecl spawnvpe(int mode, char *path, char *argv[], char **env);
int _Cdecl system(char *str);


381
Borland Turbo C v1/README Normal file
View File

@ -0,0 +1,381 @@
WELCOME TO TURBO C
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
This README file contains information that will be useful and/or of
interest to you. Please read it in its entirety, referring to it
when you encounter problems not addressed in the Owner's Handbook.
TABLE OF CONTENTS
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
1. How to get Help
2. Corrections/Additions to the Manual
3. Important tips
4. Files on the disk
5. Using Turbo C with DOS 3.2 and a Floating Point Coprocessor
6. How to compile MicroCalc
1. HOW TO GET HELP
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
If you have any problems, please read this file and the Owner's
Handbook first. If you still have a question and need assistance,
help is available from the following sources:
1. Type GO BORLAND on the CompuServe bulletin board system
for instant access to the Borland forums with their
libraries of technical information and answers to
common questions.
If you are not a member of CompuServe, see the enclosed
special offer, and write for full details on how to
receive a free IntroPak containing a $15 credit toward
your first month's on-line charges.
2. Check with your local software dealer or users' group.
3. Write to us at the following address:
Borland International
Turbo C Technical Support
4585 Scotts Valley Dr
Scotts Valley, CA 95066
Please remember to include your serial number or we
will be unable to process your letter.
4. If you have an urgent problem that cannot wait and you have
sent in the license agreement from the front of your manual,
you may call the Borland Technical Support department. Please
have the following information ready before calling:
a. Product name and serial number on your original
distribution disk. Please have your serial number
ready or we will be unable to process your call.
b. Product version number. The version number for Turbo C is
displayed when you first load the program and before you
press any keys.
c. Computer brand, model, and the brands and model numbers of
any additional hardware.
d. Operating system and version number. (The version number
can be determined by typing VER at the DOS prompt.)
e. Contents of your AUTOEXEC.BAT file.
f. Contents of your CONFIG.SYS file.
2. CORRECTIONS/ADDITIONS TO THE MANUAL
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
User's Guide (Volume I)
- Page 10 - The Distribution List is inaccurate. The correct
list of files included with Turbo C is given in this readme
in Section Four.
- Page 98 - The example has a statement:
while ((ch=getch()) != '\n') {
The correct statement is:
while ((ch=getch()) != '\r') {
Note the '\n' is changed to '\r'.
Reference Guide (Volume II)
- Page 29 - The description for assert says that to disable
the assert macro, the symbol NDEBUG must be defined before the
assert macro is used. In fact it must be placed before
assert.h is included:
#define NDEBUG
#include <assert.h>
- Page 46 - The correct usage for the bsearch function is:
void *bsearch(void *key, void *base, int nelem,
int width, int (*fcmp)());
That is, nelem is an int, not a pointer to an int, as
given in the documentation.
- Page 108 - The Portability paragraph for the getc function
says that the functions described in that section (getc,
getchar, fgetc, etc.) are all in Unix. In fact, all but getch,
getche, and ungetch are in Unix; these others are MSDOS
specific.
- Page 181 - The printf chart is incorrect. The correct chart is:
prefix 6d 6o 8x 10.2e 10.2f
%-+#0 |+555 |01053 |0x22b |+5.50e+000 |+5.50 |
%-+# |+555 |01053 |0x22b |+5.50e+000 |+5.50 |
%-+0 |+555 |1053 |22b |+5.50e+000 |+5.50 |
%-+ |+555 |1053 |22b |+5.50e+000 |+5.50 |
%-#0 |555 |01053 |0x22b |5.50e+000 |5.50 |
%-# |555 |01053 |0x22b |5.50e+000 |5.50 |
%-0 |555 |1053 |22b |5.50e+000 |5.50 |
%- |555 |1053 |22b |5.50e+000 |5.50 |
%+#0 |+00555 |001053 |0x00022b |+5.50e+000 |+000005.50 |
%+# | +555 | 01053 | 0x22b |+5.50e+000 | +5.50 |
%+0 |+00555 |001053 |0000022b |+5.50e+000 |+000005.50 |
%+ | +555 | 1053 | 22b |+5.50e+000 | +5.50 |
%#0 |000555 |001053 |0x00022b |05.50e+000 |0000005.50 |
%# | 555 | 01053 | 0x22b | 5.50e+000 | 5.50 |
%0 |000555 |001053 |0000022b |05.50e+000 |0000005.50 |
% | 555 | 1053 | 22b | 5.50e+000 | 5.50 |
- Page 197 - The description of the scanf conversion type
characters lists F to indicate a float conversion. This
is not correct. F is not a valid type character. It is
used instead to override the default size of the corresponding
address argument to be a far pointer. That is, the format %F
is not valid; it does not specify a float conversion.
The format %Ff specifies a float conversion into an argument
that is given with a far pointer.
- Page 231 - The proper description for the strstr function
is: strstr scans str1 for the first occurrence of the substring
str2.
- The Merge string option (O/C/Code generation/Merge duplicate
strings or -d) is actually default OFF, not default ON.
- The discussion of text mode I/O in the functions close (p. 54)
and read (p. 188) states that Ctrl-Z is written to the end of a
text mode file when that file is closed, if that file was opened
for write. That is incorrect. No Ctrl-Z is written for you.
If you want your text file to be terminated with a Ctrl-Z,
you need to explicitly output one yourself. Some older programs on
DOS require a Ctrl-Z at the end of text files. This is an outmoded
practice inherited from CP/M.
- The description of the intdos, intdosx, int86 and int86x
functions is incomplete. The union REGS structure used by all
four functions has the additional field x.flags. This field is
set to the 8086 flags register after the system call is made.
This is in contrast to the x.cflag field, which simply contains
the state of the carry flag.
Further, for int86x and intdosx, the segregs->es and
segregs->ds fields are set to the values of the corresponding
segment registers after the system call.
- The variable int _doserrno is declared in dos.h and errno.h.
_stklen
Name _stklen
Usage extern unsigned _stklen;
Description
_stklen is used to specify the size of the stack.
In large data models (compact, large and huge), _stklen is
the exact stack size in bytes. In small data models
(tiny, small and medium), _stklen is used by the startup code
to compute the minimum size of the DATA segment:
min DATA segment size = size of _DATA segment +
size of _BSS segment +
_stklen + MINSTACK (128 words).
If the memory available is less than this, the startup
aborts the program.
_8087
Name _8087
Usage extern int _8087;
Description
The _8087 variable is set to 1 if an 8087 or 80287 is detected
or if the 87 environment variable is set to Y (set 87=Y). It is
set to 0 otherwise. You must have floating point code in your
program for _8087 to be set to 1.
3. IMPORTANT TIPS
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
- When copying the *.H files from the Libraries and Header Files
disk be sure to copy the SYS sub-directory and its contents.
- The C startup routine (c0?.obj) parses the command line
to set up the argc, argv arguments to main. Double quotes on
the command line can be used to bracket a single argument that
has embedded blanks. For example, in the following, the
program MYPROG.EXE is invoked with three arguments:
myprog arg1 "arg2 with embedded blanks" arg3
The second argument contains embedded blanks.
- Here is further explanation of the switch to disable
register variables (-r- or O/C/Optimization/Use register
variables..Off). Not only will the compiler not use register
variables, but it also will not respect and preserve register
variables (si,di) from any caller. For that reason, you should
not have code that uses register variables call code which has
been compiled -r-.
4. FILES ON THE DISK
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Disk 1
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
README COM -- Reads this README
TC EXE -- Turbo C Compiler
TCINST COM -- Installation program for TC.EXE
TCHELP TCH -- Help file for Turbo C
HELLO C -- Example Turbo C program
README -- This file!
Disk 2
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
TCC EXE -- Command line version of Turbo C Compiler
CPP EXE -- Turbo C preprocessor
MAKE EXE -- Program for managing projects
TLINK EXE -- Borland Turbo Linker
TOUCH COM -- Program that updates a file's date and time
CNVTCFG EXE -- Program to convert configuration files
BUILD-C0 BAT -- Batch file for building the startup code modules
C0 ASM -- Assembler source for startup code
RULES ASI -- Assembler include file for interfacing with Turbo C
SETENVP ASM -- Assembler source code for preparing the environment
SETARGV ASM -- Assembler source code for parsing the command line
MAIN C -- Alternative, stripped-down C main file
Disk 3
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
???????? H -- Turbo C header files
C0T OBJ -- Tiny model startup code
C0S OBJ -- Small model startup code
MATHS LIB -- Small model math library
CS LIB -- Small model run-time library
C0L OBJ -- Large model startup code
MATHL LIB -- Large model math library
CL LIB -- Large model run-time library
EMU LIB -- 8087 emulator library
FP87 LIB -- 8087 library
MCALC C -- MicroCalc main program source code
MCALC H -- The header file for MicroCalc
MCALC PRJ -- The MicroCalc project file
MCALC DOC -- Documentation for MicroCalc
MCOMMAND C -- MicroCalc commands source code
MCDISPLY C -- MicroCalc screen display source code
MCINPUT C -- MicroCalc input routines source code
MCPARSER C -- MicroCalc input parser source code
MCUTIL C -- MicroCalc utilities source code
MCMVSMEM C -- MicroCalc direct screen memory write source code
MCMVSMEM OBJ -- Compiled version of MCMVSMEM.C - will link with any
memory model
SYS DIRECTORY
ÄÄÄÄÄÄÄÄÄÄÄÄÄ
STAT H -- Turbo C header file with file status/directory
functions
Disk 4
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
C0C OBJ -- Compact model startup code
MATHC LIB -- Compact model math library
CC LIB -- Compact model run-time library
C0M OBJ -- Medium model startup code
MATHM LIB -- Medium model math library
CM LIB -- Medium model run-time library
C0H OBJ -- Huge model startup code
MATHH LIB -- Huge model math library
CH LIB -- Huge model run-time library
MATHERR C -- Source code for handling math library exceptions
FILECOMP C -- Example Turbo C program to compare files
GETOPT C -- Parses options in commmand line
CPINIT OBJ -- Initialization code to be used when linking
Turbo C and Turbo Prolog.
BAR C -- Example function to be used with PBAR.PRO
PBAR PRO -- Example Turbo Prolog program to be used with BAR.C
5. USING TURBO C WITH DOS 3.2 AND A FLOATING POINT COPROCESSOR
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
DOS 3.2 has a bug in its handling of floating exceptions. When
an exception occurs, the system allocates a local stack for the
exception handler. Unfortunately, when a system stack gets
allocated, it never gets deallocated. The default number of
stacks is 8. After 9 floating point exceptions occur, the system
hangs and a cold reboot is required. Typical exceptions are
overflow and divide by zero. The stacks are not reclaimed when
a program terminates, so a program which divides by zero once
will crash the machine if run 9 times. To avoid this problem,
you can either:
1. Not use DOS 3.2.
2. Obtain a patch from IBM or Microsoft which fixes the
bug, and install it on your copy of DOS.
3. Not use a floating point coprocessor.
4. Disable the exception trapping in your Turbo C program.
You can do this easily by calling the _clear87() library
function. For example,
#include <float.h>
unsigned int fpstatus;
/* stdlib.h included for exit, stdio.h for puts */
#include <stdlib.h>
#include <stdio.h>
main()
{
_clear87();
/* do floating point work here */
/* ... */
/* now, check for masked exceptions before exiting */
fpstatus = _status87();
if (fpstatus & SW_INVALID)
puts("Floating point error: invalid operation.");
if (fpstatus & SW_ZERODIVIDE)
puts("Floating point error: zero divide.");
if (fpstatus & SW_OVERFLOW)
puts("Floating point error: overflow.");
exit(fpstatus & (SW_INVALID | SW_ZERODIVIDE | SW_OVERFLOW));
}
6. HOW TO COMPILE MICROCALC
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
In order to compile MicroCalc do the following:
With TC.EXE:
1. Run TC.EXE
2. In the Project pulldown menu specify the project name
"MCALC.PRJ"
3. From the main menu select the Run option
With TCC.EXE:
Compile from DOS with the following command line:
TCC mcalc mcparser mcdisply mcinput mcommand mcutil mcmvsmem.obj
In both cases, compiling under a large data model (COMPACT, LARGE,
or HUGE) will give you much more memory for your spreadsheets.
END
ÄÄÄ
>


Binary file not shown.

View File

@ -0,0 +1,482 @@
.XLIST
PAGE
;[]------------------------------------------------------------[]
;| RULES.ASI -- Rules & Structures for assembler |
;| |
;| Turbo-C Run Time Library version 1.0 |
;| |
;| Copyright (c) 1987 by Borland International Inc. |
;| All Rights Reserved. |
;[]------------------------------------------------------------[]
;*** First we begin with a few of the major constants of C.
false equ 0 ; Beware ! For incoming parameters, non-false = true.
true equ 1 ; For results, we generate the proper numbers.
lesser equ -1 ; Incoming, lesser < 0
equal equ 0
greater equ 1 ; Incoming, greater > 0
PAGE
;[]------------------------------------------------------------[]
;| |
;| Conditional Assembly Directives |
;| |
;[]------------------------------------------------------------[]
IFNDEF __TINY__
IFNDEF __SMALL__
IFNDEF __MEDIUM__
IFNDEF __COMPACT__
IFNDEF __LARGE__
IFNDEF __HUGE__
%OUT You must supply a model symbol.
.ERR
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
IFDEF __TINY__ ; *** Special case ***
__SMALL__ equ true
ENDIF
IFDEF __HUGE__ ; *** Special case ***
__LARGE__ equ true
ENDIF
IFDEF __SMALL__ ; Small Code - Small Data
LPROG equ false
LDATA equ false
ENDIF
IFDEF __MEDIUM__ ; Small Code - Large Data
LPROG equ true
LDATA equ false
ENDIF
IFDEF __COMPACT__ ; Large Code - Small Data
LPROG equ false
LDATA equ true
ENDIF
IFDEF __LARGE__ ; Large Code - Large Data
LPROG equ true
LDATA equ true
ENDIF
IFNDEF LPROG ; *** Default = __COMPACT__ ***
__COMPACT__ equ true
LPROG equ false
LDATA equ true
ENDIF
PAGE
;[]------------------------------------------------------------[]
;| |
;| Segment Declarations Macros |
;| |
;[]------------------------------------------------------------[]
CSeg@ MACRO ;; Open a Code Segment
_TEXT SEGMENT BYTE PUBLIC 'CODE'
ASSUME CS:_TEXT
ENDM
CSegEnd@ MACRO ;; Close a Code Segment
_TEXT ENDS
ENDM
DSeg@ MACRO ;; Open a Data Segment (initialized)
_DATA SEGMENT WORD PUBLIC 'DATA'
ENDM
DSegEnd@ MACRO ;; Close a Data Segment (initialized)
_DATA ENDS
ENDM
BSeg@ MACRO ;; Open a Data Segment (un-initialized)
_BSS SEGMENT WORD PUBLIC 'BSS'
ENDM
BSegEnd@ MACRO ;; Close a Data Segment (un-initialized)
_BSS ENDS
ENDM
Header@ MACRO
_TEXT SEGMENT BYTE PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
IFDEF __TINY__
DGROUP GROUP _TEXT, _DATA, _BSS
ELSE
DGROUP GROUP _DATA, _BSS
ENDIF
ASSUME CS:_TEXT, DS:DGROUP
ENDM
PAGE
;[]------------------------------------------------------------[]
;| |
;| C Naming Convention Macros |
;| |
;[]------------------------------------------------------------[]
UNDERSCORE EQU 1
ExtSym@ MACRO Sym, sType, sName
IFNB <sName>
IFIDN <sName>, <__PASCAL__>
NAMING = 0
ELSE
NAMING = UNDERSCORE
ENDIF
ENDIF
IF NAMING
EXTRN _&Sym : sType
Sym&@ equ _&Sym
ELSE
EXTRN Sym : sType
Sym&@ equ Sym
ENDIF
ENDM
PubSym@ MACRO Sym, Definition, sName
IFNB <sName>
IFIDN <sName>, <__PASCAL__>
NAMING = 0
ELSE
NAMING = UNDERSCORE
ENDIF
ENDIF
IF NAMING
PUBLIC _&Sym
_&Sym Definition
Sym&@ equ _&Sym
ELSE
PUBLIC Sym
Sym Definition
Sym&@ equ Sym
ENDIF
ENDM
Static@ MACRO Sym, Definition, sName
IFNB <sName>
IFIDN <sName>, <__PASCAL__>
NAMING = 0
ELSE
NAMING = UNDERSCORE
ENDIF
ENDIF
IF NAMING
_&Sym Definition
Sym&@ equ _&Sym
ELSE
Sym Definition
Sym&@ equ Sym
ENDIF
ENDM
PAGE
;[]------------------------------------------------------------[]
;| |
;| Macros which are Data Size Dependent |
;| |
;[]------------------------------------------------------------[]
IF LDATA
DPTR_ equ DWORD PTR
dPtrSize equ 4
LES_ equ LES
ES_ equ ES:
SS_ equ SS:
LDS_ equ LDS
pushDS_ MACRO
PUSH DS
ENDM
popDS_ MACRO
POP DS
ENDM
PushPtr MACRO dPtrOff, dPtrSeg
PUSH dPtrSeg
PUSH dPtrOff
ENDM
dPtr@ MACRO Sym, VALUE, sName ;; Static Data pointer
Static@ Sym, <DD VALUE>, sName
ENDM
dPtrPub@ MACRO Sym, VALUE, sName ;; Global Data Pointer
PubSym@ Sym, <DD VALUE>, sName
ENDM
dPtrExt@ MACRO Sym, sName ;; External Data Pointer
ExtSym@ Sym, DWORD, sName
ENDM
ELSE
DPTR_ equ WORD PTR
dPtrSize equ 2
LES_ equ MOV
ES_ equ DS:
SS_ equ DS:
LDS_ equ MOV
pushDS_ MACRO
ENDM
popDS_ MACRO
ENDM
PushPtr MACRO dPtrOff, dPtrSeg
PUSH dPtrOff
ENDM
dPtr@ MACRO Sym, VALUE, sName ;; Static Data pointer
Static@ Sym, <DW VALUE>, sName
ENDM
dPtrPub@ MACRO Sym, VALUE, sName ;; Global Data Pointer
PubSym@ Sym, <DW VALUE>, sName
ENDM
dPtrExt@ MACRO Sym, sName ;; External Data Pointer
ExtSym@ Sym, WORD, sName
ENDM
ENDIF
PAGE
;[]------------------------------------------------------------[]
;| |
;| Macros which are Code Size Dependent |
;| |
;[]------------------------------------------------------------[]
IF LPROG
CPTR_ equ DWORD PTR
cPtrSize equ 4
Proc@ MACRO Sym, sName ;; Open a Static function
Static@ Sym, <PROC FAR>, sName
ENDM
PubProc@ MACRO Sym, sName ;; Open a Public function
PubSym@ Sym, <PROC FAR>, sName
ENDM
ExtProc@ MACRO Sym, sName ;; External Function
ExtSym@ Sym, FAR, sName
ENDM
cPtr@ MACRO Sym, VALUE, sName ;; Static Function pointer
Static@ Sym, <DD VALUE>, sName
ENDM
cPtrPub@ MACRO Sym, VALUE, sName;; Global Function Pointer
PubSym@ Sym, <DD VALUE>, sName
ENDM
cPtrExt@ MACRO Sym, sName ;; External Function Pointer
ExtSym@ Sym, DWORD, sName
ENDM
ELSE
CPTR_ equ WORD PTR
cPtrSize equ 2
Proc@ MACRO Sym, sName ;; Open a Static function
Static@ Sym, <PROC NEAR>, sName
ENDM
PubProc@ MACRO Sym, sName ;; Open a Public function
PubSym@ Sym, <PROC NEAR>, sName
ENDM
ExtProc@ MACRO Sym, sName ;; External Function
ExtSym@ Sym, NEAR, sName
ENDM
cPtr@ MACRO Sym, VALUE, sName ;; Static Function pointer
Static@ Sym, <DW VALUE>, sName
ENDM
cPtrPub@ MACRO Sym, VALUE, sName ;; Global Function Pointer
PubSym@ Sym, <DW VALUE>, sName
ENDM
cPtrExt@ MACRO Sym, sName ;; External Function Pointer
ExtSym@ Sym, WORD, sName
ENDM
ENDIF
EndProc@ MACRO Sym, sName ;; Close a function
Static@ Sym, ENDP, sName
ENDM
PAGE
;[]------------------------------------------------------------[]
;| |
;| Miscellaneous Definitions |
;| |
;[]------------------------------------------------------------[]
;*** Set up some macros for procedure parameters and export/import
nearCall STRUC
nearBP dw ?
nearIP dw ?
nearParam dw ?
nearCall ENDS
farCall STRUC
farBP dw ?
farCSIP dd ?
aParam dw ?
farCall ENDS
;*** Next, we define some convenient structures to access the parts
; of larger objects.
_twoBytes STRUC
BY0 db ?
BY1 db ?
_twoBytes ENDS
_fourWords STRUC
W0 dw ?
W1 dw ?
W2 dw ?
W3 dw ?
_fourWords ENDS
_twoDwords STRUC
DD0 dd ?
DD1 dd ?
_twoDwords ENDS
_aFloat STRUC
double dq ?
_aFloat ENDS
; How to invoke MSDOS.
MSDOS@ MACRO
int 21h
ENDM
PAGE
;[]------------------------------------------------------------[]
;| |
;| Emulator Segments and Definitions |
;| |
;| The Emu287 module is in a separate model from other |
;| code. It uses the DSeg@ data segment, but since it |
;| does not actually share data the important aspect of |
;| the Data is the class name 'DATA'. It has its own |
;| stack inside the data segment. The code segment is |
;| completely separate from other code segments. The |
;| only contact between Emu287 and other code is via |
;| soft interrupts 34h..3Eh. |
;| |
;[]------------------------------------------------------------[]
EmuSeg@ MACRO
EMU_PROG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS : EMU_PROG
ENDM
EmuSegEnd@ MACRO
EMU_PROG ENDS
ENDM
E87Seg@ MACRO
E87_PROG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS : E87_PROG
ENDM
E87SegEnd@ MACRO
E87_PROG ENDS
ENDM
; The next section concerns the use of registers. SI and DI are used
; for register variables, and must be conserved.
; Registers AX, BX, CX, DX will not be preserved across function calls.
; Firstly, the registers to be conserved through function calls, including
; the setup of local variables.
link@ MACRO _si,_di,_ES,locals
push bp
mov bp, sp
IFNB <locals>
lea sp, locals
ENDIF
IFNB <_si>
push si
ENDIF
IFNB <_di>
push di
ENDIF
ENDM
unLink@ MACRO _si,_di,_ES,locals
IFNB <_di>
pop di
ENDIF
IFNB <_si>
pop si
ENDIF
IFNB <locals>
mov sp, bp
ENDIF
pop bp
ENDM
PAGE
;[]------------------------------------------------------------[]
;| |
;| iNDP Status and Control words definitions |
;| |
;[]------------------------------------------------------------[]
;/* 8087/80287 Status Word format */
SW_INVALID equ 00001h ;/* Invalid operation */
SW_DENORMAL equ 00002h ;/* Denormalized operand */
SW_ZERODIVIDE equ 00004h ;/* Zero divide */
SW_OVERFLOW equ 00008h ;/* Overflow */
SW_UNDERFLOW equ 00010h ;/* Underflow */
SW_INEXACT equ 00020h ;/* Precision (Inexact result) */
;/* 8087/80287 Control Word format */
MCW_EM equ 0003Fh ;/* interrupt Exception Masks */
EM_INVALID equ 00001h ;/* invalid */
EM_DENORMAL equ 00002h ;/* denormal */
EM_ZERODIVIDE equ 00004h ;/* zero divide */
EM_OVERFLOW equ 00008h ;/* overflow */
EM_UNDERFLOW equ 00010h ;/* underflow */
EM_INEXACT equ 00020h ;/* inexact (precision) */
MCW_IC equ 01000h ;/* Infinity Control */
IC_AFFINE equ 01000h ;/* affine */
IC_PROJECTIVE equ 00000h ;/* projective */
MCW_RC equ 00C00h ;/* Rounding Control */
RC_CHOP equ 00C00h ;/* chop */
RC_UP equ 00800h ;/* up */
RC_DOWN equ 00400h ;/* down */
RC_NEAR equ 00000h ;/* near */
MCW_PC equ 00300h ;/* Precision Control */
PC_24 equ 00000h ;/* 24 bits */
PC_53 equ 00200h ;/* 53 bits */
PC_64 equ 00300h ;/* 64 bits */
;/* 8087/80287 Initial Control Word */
CW_DEFAULT equ (RC_NEAR+PC_64+EM_DENORMAL+EM_UNDERFLOW+EM_INEXACT)
.LIST

View File

@ -0,0 +1,230 @@
NAME setargv
PAGE 60,132
;[]------------------------------------------------------------[]
;| SETARGV.ASM -- Parse Command Line |
;| |
;| Turbo-C Run Time Library version 1.0 |
;| |
;| Copyright (c) 1987 by Borland International Inc. |
;| All Rights Reserved. |
;[]------------------------------------------------------------[]
INCLUDE RULES.ASI
; Segment and Group declarations
Header@
; External references
ExtSym@ __argc, WORD, __CDECL__
dPtrExt@ __argv, __CDECL__
ExtSym@ _psp, WORD, __CDECL__
ExtSym@ _envseg, WORD, __CDECL__
ExtSym@ _envLng, WORD, __CDECL__
ExtSym@ _osmajor, BYTE, __CDECL__
ExtProc@ abort, __CDECL__
SUBTTL Parse Command Line
PAGE
;/* */
;/*-----------------------------------------------------*/
;/* */
;/* Parse Command Line */
;/* ------------------ */
;/* */
;/*-----------------------------------------------------*/
;/* */
PSPCmd equ 00080h
CSeg@
IF LPROG
SavedReturn dd ?
ELSE
SavedReturn dw ?
ENDIF
SavedDS dw ?
SavedBP dw ?
PubProc@ _setargv, __CDECL__
; First, save caller context and Return Address
pop word ptr SavedReturn
IF LPROG
pop word ptr SavedReturn+2
ENDIF
mov SavedDS, ds
; Then, Process command line
cld
mov es, _psp@
mov si, PSPCmd ; ES: SI = Command Line address
xor ax, ax
mov bx, ax
mov dx, ax ; AX = BX = CX = DX = 0
mov cx, ax ; AX = BX = CX = DX = 0
lods byte ptr es:[si]
mov di, si
xchg ax, bx
mov es:[di+bx], al ; Append a \0 at the end
inc bx
xchg bx, cx ; CX = Command Line size including \0
Processing label near
call NextChar
ja NotQuote ; Not a quote and there are more
InString label near
jb GetArg0Lgth ; Command line is empty now
call NextChar
ja InString ; Not a quote and there are more
NotQuote label near
cmp al, ' '
je EndArgument ; Space is an argument separator
cmp al, 9
jne Processing ; TAB is an argument separator
EndArgument label near
xor al, al ; Space and TAB are argument separators
jmp short Processing
; Character test function used in SetArgs
; On entry AL holds the previous character
; On exit AL holds the next character
; ZF on if the next character is quote (") and AL = 0
; CF on if end of command line and AL = 0
NextChar PROC NEAR
or ax, ax
jz NextChar0
inc dx ; DX = Actual length of CmdLine
stosb
or al, al
jnz NextChar0
inc bx ; BX = Number of parameters
NextChar0 label near
xchg ah, al
xor al, al
stc
jcxz NextChar2 ; End of command line --> CF ON
lods byte ptr es:[si]
dec cx
sub al, '"'
jz NextChar2 ; Quote found --> AL = 0 and ZF ON
add al, '"'
cmp al,'\'
jne NextChar1 ; It is not a \
cmp byte ptr es:[si], '"'
jne NextChar1 ; Only " is transparent after \
lods byte ptr es:[si]
dec cx
NextChar1 label near
or si, si ; Be sure both CF & ZF are OFF
NextChar2 label near
ret
NextChar ENDP
; Invalid program name
BadProgName label near
jmp abort@
; Now, Compute Argv[0] length
GetArg0Lgth label near
mov bp, es ; BP = Program Segment Prefix address
mov si, _envLng@
add si, 2 ; SI = Program name offset
mov cx, 1 ; CX = Filename size (includes \0)
cmp _osmajor@, 3
jb NoProgramName
mov es, _envseg@
mov di, si ; SI = argv[0] address
mov cl, 07fh
repnz scasb
jcxz BadProgName
xor cl, 07fh ; CX = Filename size (includes \0)
NoProgramName label near
; Now, reserve space for the arguments
ReserveSpace label near
inc bx ; argv[0] = PgmName
mov __argc@, bx
inc bx ; argv ends with NULL
mov ax, cx ; Size = PgmNameLgth +
add ax, dx ; CmdLineLgth +
add bx, bx ; argc * 2 (LDATA = 0)
IF LDATA
add bx, bx ; argc * 4 (LDATA = 1)
ENDIF
add ax, 1
and ax, not 1 ; Keep stack word aligned
add bx, ax
mov di, sp
sub di, ax ; SS:DI = DestAddr for PgmName
sub sp, bx ; SS:SP = &argv[0]
xchg bx, bp ; BX = Program Segment Prefix address
mov bp, sp ; BP = &argv[0]
mov word ptr __argv@, sp
IF LDATA
mov word ptr __argv@+2, ss
ENDIF
mov ax, ss
mov es, ax ; ES:DI = Argument's area
; Copy program name
CopyArg0 label near
mov [bp], di ; Set argv[n]
IF LDATA
mov [bp+2], es
add bp, 4
ELSE
add bp, 2
ENDIF
mov ds, _envseg@
dec cx
rep movsb
xor al, al
stosb
; Copy the command line
mov ds, bx
xchg cx, dx ; CX = Command Line size
mov si, PSPCmd + 1 ; DS: SI = Command Line address
CopyArgs label near
jcxz SetLastArg
mov [bp], di ; Set argv[n]
IF LDATA
mov [bp+2], es
add bp, 4
ELSE
add bp, 2
ENDIF
CopyArg label near
lodsb
or al, al
stosb
loopnz CopyArg
jz CopyArgs
SetLastArg label near
xor ax, ax
mov [bp], ax
IF LDATA
mov [bp+2], ax
ENDIF
; Restore caller context and exit
mov ds, SavedDS
IF LPROG
jmp dword ptr SavedReturn
ELSE
jmp word ptr SavedReturn
ENDIF
EndProc@ _setargv, __CDECL__
CSegEnd@
END

View File

@ -0,0 +1,117 @@
NAME setenvp
PAGE 60,132
;[]------------------------------------------------------------[]
;| SETENVP.ASM -- Prepare Environment |
;| |
;| Turbo-C Run Time Library version 1.0 |
;| |
;| Copyright (c) 1987 by Borland International Inc. |
;| All Rights Reserved. |
;[]------------------------------------------------------------[]
INCLUDE RULES.ASI
; Segment and Group declarations
Header@
; External references
ExtProc@ malloc, __CDECL__
ExtProc@ abort, __CDECL__
ExtSym@ _envseg, WORD, __CDECL__
ExtSym@ _envLng, WORD, __CDECL__
ExtSym@ _envSize, WORD, __CDECL__
dPtrExt@ environ, __CDECL__
SUBTTL Prepare Environment
PAGE
;/* */
;/*-----------------------------------------------------*/
;/* */
;/* Prepare Environment */
;/* ------------------- */
;/* */
;/*-----------------------------------------------------*/
;/* */
CSeg@
PubProc@ _setenvp, __CDECL__
; Allocate a buffer to hold environment variables
IF LDATA EQ 0
mov cx, _envLng@
push cx
call malloc@
pop cx
mov di, ax
or ax, ax
jz _Failed ; Memory allocation failed
push ds
push ds
pop es
mov ds, _envseg@
xor si, si
cld
rep movsb
pop ds
mov di, ax
ELSE
mov es, _envseg@
xor di, di
ENDIF
; Allocate a buffer to hold envp array
push es ; Save Environment Segment address
push _envSize@
call malloc@
add sp, 2
mov bx, ax
pop es ; Restore Environment Segment address
IF LDATA
mov word ptr environ@, ax
mov word ptr environ@+2, dx
push ds
mov ds, dx
or ax, dx
ELSE
mov word ptr environ@, ax
or ax, ax
ENDIF
jnz SetEnviron ; Memory allocation failed
_Failed label near ; Memory allocation failed
jmp abort@
; Now, store environment variables address
SetEnviron label near
xor ax, ax
mov cx, -1
SetEnviron0 label near
mov [bx], di
IF LDATA
mov [bx+2], es
add bx, 4
ELSE
add bx, 2
ENDIF
repnz scasb
cmp es:[di], al
jne SetEnviron0 ; Set next pointer
IF LDATA
mov [bx], ax
mov [bx+2], ax
pop ds
ELSE
mov [bx], ax
ENDIF
ret
EndProc@ _setenvp, __CDECL__
CsegEnd@
END

View File

@ -0,0 +1,33 @@
/* setjmp.h
Defines typedef and functions for setjmp/longjmp.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _SETJMP
#define _SETJMP
typedef struct {
unsigned j_sp;
unsigned j_ss;
unsigned j_flag;
unsigned j_cs;
unsigned j_ip;
unsigned j_bp;
unsigned j_di;
unsigned j_es;
unsigned j_si;
unsigned j_ds;
} jmp_buf[1];
void _Cdecl longjmp(jmp_buf jmpb, int retval);
int _Cdecl setjmp(jmp_buf jmpb);
#endif


View File

@ -0,0 +1,22 @@
/* share.h
File sharing mode for use with sopen.
See DOS function 3Dh for definition.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#define SH_COMPAT 0x0000
#define SH_DENYRW 0x0010
#define SH_DENYWR 0x0020
#define SH_DENYRD 0x0030
#define SH_DENYNONE 0x0040
#define SH_DENYNO SH_DENYNONE /* MS documentation uses both */


View File

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

View File

@ -0,0 +1,29 @@
/* Signal.H
Definitions For Software Signalling Mechanism.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#define SIG_DFL ((int(*)())0) /* Default action */
#define SIG_IGN ((int(*)())1) /* Ignore action */
#define SIG_ERR ((int(*)())-1) /* Error return */
#define SIGABRT 1
#define SIGFPE 2 /* Floating point trap */
#define SIGILL 3 /* Illegal instruction */
#define SIGINT 4
#define SIGSEGV 5 /* Memory access violation */
#define SIGTERM 6
#if !__STDC__
int cdecl gsignal(int sig);
int (*cdecl ssignal(int sig, int (*action)())) ();
#endif


View File

@ -0,0 +1,25 @@
/* stdarg.h
Definitions for accessing parameters in functions that accept
a variable number of arguments.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#if !defined(__STDARG)
#define __STDARG
typedef void *va_list;
#define va_start(ap, parmN) (ap = ...)
#define va_arg(ap, type) (*((type *)(ap))++)
#define va_end(ap)
#define _va_ptr (...)
#endif


View File

@ -0,0 +1,40 @@
/* stddef.h
Definitions for common types, NULL, and errno.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _STDDEF
#define _STDDEF
#ifndef _PTRDIFF_T
#define _PTRDIFF_T
#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
typedef long ptrdiff_t;
#else
typedef int ptrdiff_t;
#endif
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif
#ifndef NULL
#if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#define NULL 0
#else
#define NULL 0L
#endif
#endif
extern int _Cdecl errno;
#endif


151
Borland Turbo C v1/STDIO.H Normal file
View File

@ -0,0 +1,151 @@
/* stdio.h
Definitions for stream input/output.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#if !defined(__STDIO_DEF_)
#define __STDIO_DEF_
typedef struct {
short level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
char hold; /* Ungetc char if no buffer */
short bsize; /* Buffer size */
unsigned char *buffer; /* Data transfer buffer */
unsigned char *curp; /* Current active pointer */
short token; /* Used for validity checking */
} FILE; /* This is the FILE object */
#define _IOFBF 0
#define _IOLBF 1
#define _IONBF 2
#define _F_RDWR 0x0003 /* Read/write flag */
#define _F_READ 0x0001 /* Read only file */
#define _F_WRIT 0x0002 /* Write only file */
#define _F_BUF 0x0004 /* Malloc'ed Buffer data */
#define _F_LBUF 0x0008 /* line-buffered file */
#define _F_ERR 0x0010 /* Error indicator */
#define _F_EOF 0x0020 /* EOF indicator */
#define _F_BIN 0x0040 /* Binary file indicator */
#define _F_IN 0x0080 /* Data is incoming */
#define _F_OUT 0x0100 /* Data is outgoing */
#define _F_TERM 0x0200 /* File is a terminal */
#define EOF (-1) /* End of file indicator */
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif
#ifndef NULL
# if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
# define NULL 0
# else
# define NULL 0L
# endif
#endif
#define OPEN_MAX 20 /* Total of 20 open files */
#define SYS_OPEN 20
#define BUFSIZ 512 /* Buffer size for stdio */
#define L_ctermid 5 /* CON: plus null byte */
#define L_tmpnam 13 /* tmpnam buffer size */
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
#define TMP_MAX (26*26*26)
/* The standard i/o predefined streams are given as follows: */
extern FILE _Cdecl _streams[];
#define stdin (&_streams[0])
#define stdout (&_streams[1])
#define stderr (&_streams[2])
void _Cdecl clearerr (FILE *fp);
int _Cdecl fclose (FILE *fp);
int _Cdecl fflush (FILE *fp);
int _Cdecl fgetc (FILE *fp);
char *_Cdecl fgets (char *s, int n, FILE *fp);
FILE *_Cdecl fopen (char *filename, char *mode);
int _Cdecl fputc (char c, FILE *fp);
int _Cdecl fputs (char *s, FILE *fp);
int _Cdecl fread (void *ptr, unsigned size, unsigned n, FILE *fp);
FILE *_Cdecl freopen (char *filename, char *mode, FILE *oldfile);
int _Cdecl fseek (FILE *fp, long offset, int whence);
long _Cdecl ftell (FILE *fp);
int _Cdecl fwrite (void *ptr, unsigned size, unsigned n, FILE *fp);
char *_Cdecl gets (char *s);
void _Cdecl perror (char *s);
int _Cdecl puts (char *s);
int _Cdecl rename (char *oldname, char *newname);
void _Cdecl rewind (FILE *fp);
void _Cdecl setbuf (FILE *fp, void *buf);
int _Cdecl setvbuf (FILE *stream, void *buf, int type, unsigned size);
char *_Cdecl strerror (char *string);
int _Cdecl ungetc (int c, FILE *fp);
#if !__STDC__
int _Cdecl fcloseall(void);
FILE *_Cdecl fdopen (int handle, char *type);
int _Cdecl fgetchar (void);
int _Cdecl flushall (void);
int _Cdecl fputchar (char c);
int _Cdecl getw (FILE *fp);
int _Cdecl putw (unsigned w, FILE *fp);
#endif
int _Cdecl _fgetc (FILE *fp); /* used by getc() macro */
int _Cdecl _fputc (char c, FILE *fp); /* used by putc() macro */
#if !defined(__STDARG)
#include <stdarg.h>
#endif
int _Cdecl fprintf (FILE *fp, char *format, ...);
int _Cdecl printf (char *format, ...);
int _Cdecl sprintf (char *buffer, char *format, ...);
int _Cdecl vfprintf (FILE *fp, char *format, va_list arglist);
int _Cdecl vprintf (char *format, va_list arglist);
int _Cdecl vsprintf (char *buffer, char *format, va_list arglist);
int _Cdecl fscanf (FILE *fp, char *format, ...);
int _Cdecl scanf (char *format, ...);
int _Cdecl sscanf (char *buffer, char *format, ...);
int _Cdecl vfscanf (FILE *fp, char *format, va_list arglist);
int _Cdecl vscanf (char *format, va_list arglist);
int _Cdecl vsscanf (char *buffer, char *format, va_list arglist);
/* The following macros provide for common functions */
#define ferror(f) ((f)->flags & _F_ERR)
#define feof(f) ((f)->flags & _F_EOF)
#define fileno(f) ((f)->fd)
#define remove(filename) unlink(filename)
#define getc(f) \
((--((f)->level) >= 0) ? (unsigned char)(++(f)->curp)[-1] : _fgetc (f))
#define putc(c,f) \
((++((f)->level) < 0) ? (unsigned char)((++(f)->curp)[-1]=(c)) : \
_fputc ((c),f))
#define getchar() getc(stdin)
#define putchar(c) putc((c), stdout)
#define ungetc(c,f) ungetc((c),f) /* traditionally a macro */
#endif


View File

@ -0,0 +1,80 @@
/* stdlib.h
Definitions for common types, variables, and functions.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#if !defined(__STDLIB)
#define __STDLIB
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif
typedef void (* atexit_t)(void);
int _Cdecl atexit (atexit_t func);
int _Cdecl abs (int x);
long _Cdecl labs (long x);
double _Cdecl atof (char *s);
int _Cdecl atoi (char *s);
long _Cdecl atol (char *s);
double _Cdecl strtod (char *s, char **endptr);
long _Cdecl strtol (char *s, char **endptr, int radix);
void _Cdecl srand (unsigned seed);
int _Cdecl rand (void);
void *_Cdecl calloc (unsigned nitems, unsigned size);
void _Cdecl free (void *block);
void *_Cdecl malloc (unsigned size);
void *_Cdecl realloc(void *block, unsigned size);
void _Cdecl abort (void);
void _Cdecl exit (int status);
char *_Cdecl getenv (char *name);
int _Cdecl system (char *command);
void *_Cdecl bsearch(void *key, void *base, int nelem, int width,
int _Cdecl (*fcmp)());
void _Cdecl qsort (void *base,
unsigned nelem,
unsigned width,
int _Cdecl (*fcmp)());
#if !__STDC__
extern char *_Cdecl sys_errlist[];
extern int _Cdecl sys_nerr;
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
int __abs__(int x); /* This is an in-line function */
#define abs(x) __abs__(x)
#define atoi(s) ((int) atol (s))
char *_Cdecl itoa (int value, char *string, int radix);
char *_Cdecl ltoa (long value, char *string, int radix);
char *_Cdecl ultoa (unsigned long value, char *string, int radix);
char *_Cdecl ecvt (double value, int ndig, int *dec, int *sign);
char *_Cdecl fcvt (double value, int ndig, int *dec, int *sign);
char *_Cdecl gcvt (double value, int ndec, char *buf);
void _Cdecl _exit (int status);
int _Cdecl putenv (char *name);
void *_Cdecl lsearch(void *key, void *base, unsigned *num, int width,
int _Cdecl (*fcmp)());
void *_Cdecl lfind (void *key, void *base, unsigned *num, int width,
int _Cdecl (*fcmp)());
void _Cdecl swab (void *from, void *to, unsigned nbytes);
#endif
#endif


View File

@ -0,0 +1,60 @@
/* string.h
Definitions for memory and string functions.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned size_t;
#endif
void *_Cdecl memchr(void *s, unsigned char c, unsigned n);
int _Cdecl memcmp(void *s1, void *s2, unsigned n);
void *_Cdecl memcpy(void *dest, void *src, unsigned n);
void *_Cdecl memset(void *s, unsigned char c, unsigned n);
void *_Cdecl memccpy(void *dest, void *src, unsigned char c, unsigned n);
void *_Cdecl memmove(void *dest, void *src, unsigned n);
void _Cdecl movedata(unsigned srcseg, unsigned srcoff, unsigned dstseg,
unsigned dstoff, unsigned n);
int _Cdecl memicmp(void *s1, void *s2, unsigned n);
char *_Cdecl strcat(char *dest, char *src);
char *_Cdecl strchr(char *s, char c);
int _Cdecl strcmp(char *s1, char *s2);
int _Cdecl stricmp(char *s1, char *s2);
char *_Cdecl strcpy(char *dest, char *src);
char *_Cdecl stpcpy(char *dest, char *src);
size_t _Cdecl strlen(char *s);
char *_Cdecl strncat(char *dest, char *src, unsigned maxlen);
int _Cdecl strncmp(char *s1, char *s2, unsigned maxlen);
int _Cdecl strnicmp(char *s1, char *s2, unsigned maxlen);
char *_Cdecl strncpy(char *dest, char *src, unsigned maxlen);
char *_Cdecl strlwr(char *s);
char *_Cdecl strupr(char *s);
char *_Cdecl strdup(char *s);
char *_Cdecl strset(char *s, char ch);
char *_Cdecl strnset(char *s, char ch, unsigned n);
char *_Cdecl strrev(char *s);
size_t _Cdecl strcspn(char *s1, char *s2);
char *_Cdecl strpbrk(char *s1, char *s2);
char *_Cdecl strrchr(char *s, char c);
size_t _Cdecl strspn(char *s1, char *s2);
char *_Cdecl strtok(char *s1, char *s2);
char *_Cdecl strstr(char *s1, char *s2);
char *_Cdecl strerror(char *s);
/* compatibility with other compilers */
#define strcmpi(s1,s2) stricmp(s1,s2)
#define strncmpi(s1,s2,n) strnicmp(s1,s2,n)


BIN
Borland Turbo C v1/TC.EXE Normal file

Binary file not shown.

BIN
Borland Turbo C v1/TCC.EXE Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

47
Borland Turbo C v1/TIME.H Normal file
View File

@ -0,0 +1,47 @@
/* time.h
Struct and function declarations for dealing with time.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _TIME_T
#define _TIME_T
typedef long time_t;
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
time_t _Cdecl time(time_t *timer);
char *_Cdecl asctime(struct tm *tblock);
char *_Cdecl ctime(time_t *timer);
double _Cdecl difftime(time_t time2, time_t time1);
struct tm *_Cdecl gmtime(time_t *timer);
struct tm *_Cdecl localtime(time_t *timer);
#if !__STDC__
extern int _Cdecl daylight;
extern long _Cdecl timezone;
void _Cdecl tzset(void);
int _Cdecl stime(time_t *tp);
#endif
#endif


Binary file not shown.

Binary file not shown.

528
Borland Turbo C v1/TTT.C Normal file
View File

@ -0,0 +1,528 @@
/*
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 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*/


View File

@ -0,0 +1,51 @@
/* values.h
Symbolic names for important constants, including machine
dependencies. A System V compatible header.
Copyright (c) Borland International 1987
All Rights Reserved.
*/
#if __STDC__
#define _Cdecl
#else
#define _Cdecl cdecl
#endif
#ifndef _VALUES_H
#define _VALUES_H
#define BITSPERBYTE 8
#define MAXSHORT 0x7FFF
#define MAXINT 0x7FFF
#define MAXLONG 0x7FFFFFFFL
#define HIBITS 0x8000
#define HIBITI 0x8000
#define HIBITL 0x80000000
#define DMAXEXP 308
#define FMAXEXP 38
#define DMINEXP -307
#define FMINEXP -37
#define MAXDOUBLE 1.797693E+308
#define MAXFLOAT 3.37E+38
#define MINDOUBLE 2.225074E-308
#define MINFLOAT 8.43E-37
#define DSIGNIF 53
#define FSIGNIF 24
#define DMAXPOWTWO 0x3FF
#define FMAXPOWTWO 0x7F
#define _DEXPLEN 11
#define _FEXPLEN 8
#define _EXPBASE 2
#define _IEEE 1
#define _LENBASE 1
#define HIDDENBIT 1
#define LN_MAXDOUBLE 7.0978E+2
#define LN_MINDOUBLE -7.0840E+2
#endif


3
Borland Turbo C v1/m.bat Normal file
View File

@ -0,0 +1,3 @@
ntvdm tcc -f -mm -G -O -DDOSTIME -Z -N- %1.c
ntvdm -c -p %1