Mix Power C v1

This commit is contained in:
davidly 2024-07-01 15:26:34 -07:00
parent e875f4cae7
commit c7aad48ec8
117 changed files with 22839 additions and 0 deletions

View File

@ -0,0 +1,70 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; absread(drive, nsects, sectno, buffer)
; -------------------------------------------------------
; int drive; /* disk drive number (a=0, b=1, etc) */
; int nsects; /* number of sectors */
; int sectno; /* logical sector number */
; char *buffer; /* buffer for data */
;
; returns zero if successful, -1 on error
; -------------------------------------------------------
;
IDT absread
DEF absread
DREF errno
;
absread PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV CX,[BP][%PARM2]
MOV DX,[BP][%PARM3]
MOV BX,[BP][%PARM4]
INT >25
JB ERROR
POPF
XOR AX,AX
POP BP
RETSEG
ERROR POPF
MOV [errno],AX
MOV AX,-1
POP BP
RETSEG
END
;
; -------------------------------------------------------
; abswrite(drive, nsects, sectno, buffer)
; -------------------------------------------------------
; int drive; /* disk drive number (a=0, b=1, etc) */
; int nsects; /* number of sectors */
; int sectno; /* logical sector number */
; char *buffer; /* buffer for data */
;
; returns zero if successful, -1 on error
; -------------------------------------------------------
;
IDT abswrite
DEF abswrite
DREF errno
;
abswrite PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV CX,[BP][%PARM2]
MOV DX,[BP][%PARM3]
MOV BX,[BP][%PARM4]
INT >26
JB ERROR
POPF
XOR AX,AX
POP BP
RETSEG
ERROR POPF
MOV [errno],AX
MOV AX,-1
POP BP
RETSEG
END

47
Mix Power C v1/ALLOCMEM.C Normal file
View File

@ -0,0 +1,47 @@
/* Copyright (c) Mix Software 1988 */
int allocmem(size, seg)
unsigned size; /* size of block requested (in paragraphs) */
unsigned *seg; /* segment address of result */
{
union REGS r;
r.h.ah = 0x48;
r.x.bx = size;
intdos(&r,&r);
if (r.x.cflag) return r.x.bx;
*seg = r.x.ax;
return -1;
}
int freemem(seg)
unsigned seg; /* segment address of previously allocated block */
{
extern int errno;
union REGS r;
struct SREGS sr;
r.h.ah = 0x49;
sr.es = seg;
intdosx(&r,&r,&sr);
if (r.x.cflag == 0) return 0;
errno = ENOMEM;
return -1;
}
int setblock(seg,newsize)
unsigned seg; /* segment address of previously allocated block */
unsigned newsize; /* new size (in paragraphs) */
{
extern int errno;
extern int _doserrno;
union REGS r;
struct SREGS sr;
r.h.ah = 0x4a;
r.x.bx = newsize;
sr.es = seg;
intdosx(&r,&r,&sr);
if (r.x.cflag == 0) return -1;
_doserrno = r.x.ax;
errno = ENOMEM;
return r.x.bx;
}

460
Mix Power C v1/ARITH.C Normal file
View File

@ -0,0 +1,460 @@
/* Arithmetic functions */
/* Copyright (c) Mix Software 1988 */
abs(i)
int i;
{
return i < 0 ? -i : i;
}
/* ------------------------------------------------------------ */
double cabs(z)
struct complex z;
{ /* complex absolute value */
double sqrt();
return sqrt(z.x*z.x + z.y*z.y);
}
/* ------------------------------------------------------------ */
double acos(x)
double x;
{ /* inverse cosine */
double asin();
double value;
static double piover2 = 1.5707963267948966;
if (x > 1.0 || x < -1.0) return _domerr("acos",x,x);
value = asin(x);
return piover2 - value;
}
/* ------------------------------------------------------------ */
double asin(x)
double x;
{ /* inverse sine */
double _domerr(), fabs(), atan(), sqrt();
static double piover2 = 1.5707963267948966;
double absx = fabs(x);
double value;
if (x > 1.0 || x < -1.0) return _domerr("asin",x,x);
if (absx == 0.0) value = 0.0;
else value = piover2 - atan(sqrt(1-x*x)/absx);
if (x < 0) return -value; else return value;
}
/* ------------------------------------------------------------ */
double atan2(x,y)
double x,y;
{
/* return arc tangent of y/x
atan2 is useful when converting rectangular to polar coordinates
*/
extern double (far *$0DATN)();
static double piover2 = 1.5707963267948966;
static double pi = 3.141592653589793;
double atan(), _domerr();
double value;
if (x == 0.0) {
if (y == 0.0) return _domerr("atan2",x,y);
if (y < 0.0) return pi; else return 0.0;
}
value = $0DATN(y/x);
if (x < 0.0) return -value-piover2;
return piover2 - value;
}
/* ------------------------------------------------------------ */
double atan(x)
double x;
{ /* inverse tangent */
extern double (far *$0DATN)();
return $0DATN(x);
}
/* ------------------------------------------------------------ */
double ceil(x)
double x;
{
extern double (far *$0DFIXR)();
double r;
r = $0DFIXR(x);
if (r == x) return r;
return r + 1.0;
}
/* ------------------------------------------------------------ */
double tan(x)
double x;
{
double cos(), sin(), _domerr();
double c;
c = cos(x);
if (c == 0.0) return _domerr("tan",x,x);
return sin(x)/c;
} /* tan */
/* ------------------------------------------------------------ */
double cos(x)
double x;
{
extern double (far *$0DCOS)();
double _tloss(), _ploss(), fabs();
static char name[] = "cos";
double a;
a = fabs(x);
if (a > 6.283185307179586e10) {
if (a > 6.283185307179586e16) return _tloss(name,x,x);
_ploss(name,x,x);
return $0DCOS(x);
}
return $0DCOS(x);
} /* cos */
/* ------------------------------------------------------------ */
double cosh(x)
double x;
{
extern double exp();
return (exp(x) + exp(-x)) / 2.0;
} /* cosh */
/* ------------------------------------------------------------ */
double sinh(x)
double x;
{
extern double exp();
return (exp(x) - exp(-x)) / 2.0;
} /* sinh */
/* ------------------------------------------------------------ */
double tanh(x)
double x;
{
extern double exp();
double xplus, xminus;
xplus = exp(x);
xminus = exp(-x);
return (xplus - xminus) / (xplus + xminus);
} /* tanh */
/* ------------------------------------------------------------ */
double exp(x)
double x;
{
extern double (far *$0DEXP)();
double _rangerr();
extern double _EXPMAX, _EXPMIN, HUGE;
static char name[] = "exp";
if (x > _EXPMAX) {
_rangerr(name,x,x);
return HUGE;
}
if (x < _EXPMIN) return _rangerr(name,x,x);
return $0DEXP(x);
} /* exp */
/* ------------------------------------------------------------ */
double floor(x)
double x;
{
extern double (far *$0DFIXR)();
return $0DFIXR(x);
}
/* ------------------------------------------------------------ */
double fmod(x, y)
double x,y;
{
extern double (far *$0DFIXR)();
if (y == 0.0) return _domerr("fmod",x,y);
return x - y*$0DFIXR(x/y);
}
/* ------------------------------------------------------------ */
double hypot(x, y)
double x,y;
{
double sqrt();
return (sqrt(x*x + y*y));
}
/* ------------------------------------------------------------ */
double log10(x)
double x;
{
double log();
return log(x) / 2.3025850929940457;
}
/* ------------------------------------------------------------ */
double log(x)
double x;
{
extern double (far *$0DLN)();
double _domerr(), _singerr();
extern double HUGE;
static char name[] = "log";
if (x <= 0.0) {
if (x == 0.0) { _singerr(name,x,x); return -HUGE; }
_domerr(name,x,x); return -HUGE;
}
return $0DLN(x);
} /* log */
/* ------------------------------------------------------------ */
double pow(x,y)
double x;
double y;
{
extern double (far *$0DXTOY)();
static char name[] = "pow";
double _domerr(), modf();
double intval;
if (x > 0.0) return $0DXTOY(x,y);
if (x == 0.0) {
if (y >= 0.0) return 0.0;
return _domerr(name,x,y);
}
if (modf(x,&intval) != 0.0) return _domerr(name,x,y);
if (modf(intval/2.0,&intval) != 0) return -($0DXTOY(x,y));
return $0DXTOY(x,y);
} /* pow */
/* ------------------------------------------------------------ */
double modf(x, intptr)
double x;
double *intptr;
{
extern double (far *$0DFIXR)();
*intptr = $0DFIXR(x);
return x - (*intptr);
} /* modf */
/* ------------------------------------------------------------ */
double sin(x)
double x;
{
extern double (far *$0DSIN)();
double _tloss(), _ploss(), fabs();
static char name[] = "sin";
double a;
a = fabs(x);
if (a > 6.283185307179586e10) {
if (a > 6.283185307179586e16) return _tloss(name,x,x);
_ploss(name,x,x);
return $0DSIN(x);
}
return $0DSIN(x);
} /* sin */
/* ------------------------------------------------------------ */
double sqrt(x)
double x;
{
extern double (far *$0DSQRT)();
double _domerr();
if (x < 0.0) return _domerr("sqrt",x,x);
return $0DSQRT(x);
} /* sqrt */
double poly(x, n, c)
double x;
int n; /* highest power of x in polynomial */
double c[]; /* array of coefficients (n+1 elements) */
{
double *coef;
double value;
coef = &c[n-1];
value = c[n];
while (n--) {
value = value*x + *coef;
--coef;
}
return value;
}
/* ------------------------------------------------------------ */
/* error handling for math errors */
double _domerr(name,arg1,arg2)
char *name;
double arg1,arg2;
{ /* indicate a domain error
if matherr returns 0, the answer is 0 */
extern int errno;
extern char $$ARTERM;
extern char _mathmsg;
struct exception e;
e.type = DOMAIN;
e.name = name;
e.arg1 = arg1;
e.arg2 = arg2;
if (matherr(&e)) return e.retval;
else {
errno = EDOM;
if (_mathmsg) {
fprintf(stderr,"Domain error in %s() at %g, %g\n",name,arg1,arg2);
if ($$ARTERM) abort();
}
return 0.0;
}
} /* _domerr */
/* ------------------------------------------------------------ */
double _singerr(name,arg1,arg2)
char *name;
double arg1,arg2;
{ /* indicate a singularity
if matherr returns 0, the answer is HUGE */
extern int errno;
extern char $$ARTERM;
extern char _mathmsg;
extern double HUGE;
struct exception e;
e.type = SING;
e.name = name;
e.arg1 = arg1;
e.arg2 = arg2;
if (matherr(&e)) return e.retval;
else {
errno = EDOM;
if (_mathmsg) {
fprintf(stderr,"Singularity error in %s() at %g, %g\n",name,arg1,arg2);
if ($$ARTERM) abort();
}
return HUGE;
}
} /* _domerr */
/* ------------------------------------------------------------ */
double _tloss(name,arg1,arg2)
char *name;
double arg1,arg2;
{ /* indicate total loss of significance
if matherr returns 0, the answer is 0 */
extern int errno;
extern char $$ARTERM;
extern char _mathmsg;
struct exception e;
e.type = TLOSS;
e.name = name;
e.arg1 = arg1;
e.arg2 = arg2;
if (matherr(&e)) return e.retval;
else {
errno = ERANGE;
if (_mathmsg) {
fprintf(stderr,"Total loss of signifcance in %s() at %g, %g\n",name,arg1,arg2);
if ($$ARTERM) abort();
}
return 0.0;
}
} /* _tloss */
/* ------------------------------------------------------------ */
double _ploss(name,arg1,arg2)
char *name;
double arg1,arg2;
{ /* indicate partial loss of significance
if matherr returns 0, the answer is 0 */
extern int errno;
struct exception e;
e.type = PLOSS;
e.name = name;
e.arg1 = arg1;
e.arg2 = arg2;
if (matherr(&e)) return e.retval;
return 0.0;
} /* _ploss */
/* ------------------------------------------------------------ */
double _rangerr(name,arg1,arg2)
char *name;
double arg1,arg2;
{ /* indicate a range error - result of function
is too large or too small to be represented as a double */
extern int errno;
extern char $$ARTERM;
extern char _mathmsg;
struct exception e;
e.type = OVERFLOW;
e.name = name;
e.arg1 = arg1;
e.arg2 = arg2;
if (matherr(&e)) return e.retval;
else {
errno = ERANGE;
if (_mathmsg) {
fprintf(stderr,"Argument out of range in %s() at %g, %g\n",name,arg1,arg2);
if ($$ARTERM) abort();
}
return 0.0;
}
} /* _rangerr */
/* ------------------------------------------------------------ */
int matherr(x)
struct exception *x;
{
return 0;
}
/* ------------------------------------------------------------ */
void _fpreset()
{
_clear87();
}
/* ------------------------------------------------------------ */
unsigned int _clear87()
{
extern unsigned int (far *$0clr87)();
return $0clr87();
}
/* ------------------------------------------------------------ */
unsigned int _control87(new, mask)
unsigned int new;
unsigned int mask;
{
extern unsigned int (far *$0ctl87)();
return $0ctl87(new,mask);
}
/* ------------------------------------------------------------ */
unsigned int _status87()
{
extern unsigned int (far *$0sta87)();
return $0sta87();
}

470
Mix Power C v1/BESSEL.C Normal file
View File

@ -0,0 +1,470 @@
/* Copyright (c) Mix Software 1988 */
/* ------------------------------------------------------------ */
/* bessel functions: j0, j1, jn */
/* y0, y1, yn */
double yn(n,x)
int n;
double x;
{
double y0(), y1();
double yz, yx, y, fx;
double _domerr();
extern double HUGE;
int negative = 0;
int i;
if (n == 0) return y0(x);
if (n == 1) return y1(x);
if (n < 0) {
n = -n;
if (n & 0x0001) negative = 1;
}
if (x <= 0.0) {_domerr("yn",x,x); return HUGE;}
yz = y0(x);
yx = y1(x);
fx = 2.0/x;
i = 1;
while (i < n) {
y = fx * i * yx - yz;
yz = yx;
yx = y;
i++;
}
if (negative) return -y;
return y;
} /* yn */
double jn(n,x)
int n;
double x;
{
double j0(), j1();
double jz, jx, j, fx;
int i;
if (n == 0) return j0(x);
if (n == 1) return j1(x);
if (n < 0) return jn(-n,-x);
jz = j0(x);
jx = j1(x);
fx = 2.0/x;
i = 1;
while (i < n) {
j = fx * i * jx - jz;
jz = jx;
jx = j;
i++;
}
return j;
} /* jn */
double y0(x)
double x;
{
double xsquare, xx, x8, y0;
double p, q;
double sin(), cos(), sqrt(), log(), j0();
double _domerr();
extern double HUGE;
void _pandq0();
static double pi = 3.1415926535897932;
static double piby4 = 0.78539816339744831;
static double twobypi = 0.63661977236758134;
static struct {
int terms;
double tbl[8];
} y0P = {8,
-0.40421653126104926e19,
0.96736537146262430e19,
-0.75173702582406051e18,
0.18702004643462448e17,
-0.20430408868635631e15,
0.10869647137874908e13,
-0.27725001364628094e10,
0.27295402301235549e7
};
static struct {
int terms;
double tbl[9];
} y0Q = {9,
0.54768700204477752e20,
0.72620404690767952e18,
0.49441312329373299e16,
0.22900727639481849e14,
0.80363630456265291e11,
0.22400416108570433e9,
0.50069757439413062e6,
0.86456632023518903e3,
0.10000000000000000e1
};
extern double (far *$0DPOWER)();
if (x <= 0.0) {_domerr("y0",x,x); return HUGE;}
if (x < 8.0) {
xsquare = x*x;
y0 = $0DPOWER(xsquare,&y0P)/$0DPOWER(xsquare,&y0Q);
return y0 + twobypi*j0(x)*log(x);
}
xx = x - piby4;
x8 = 8.0/x;
_pandq0(x8,&p,&q);
return sqrt(2.0/(pi*x)) * (p*sin(xx) + q*cos(xx));
} /* y0 */
double y1(x)
double x;
{
double xsquare, xx, x8, y1;
double p, q;
double sin(), cos(), sqrt(), log(), j1();
double _domerr();
extern double HUGE;
void _pandq1();
static double pi = 3.1415926535897932;
static double piby34 = 2.35619449019234493;
static double twobypi = 0.63661977236758134;
static struct {
int terms;
double tbl[8];
} y1P = {8,
-0.29238219615329625e20,
0.77485206821868396e19,
-0.34410480630841144e18,
0.59151607604900706e16,
-0.48633169425671751e14,
0.20496966737456622e12,
-0.42894719688552488e9,
0.35569240098305261e6
};
static struct {
int terms;
double tbl[9];
} y1Q = {9,
0.14913115113029204e21,
0.18186628417061350e19,
0.11316393826988845e17,
0.47551735888881377e14,
0.15002216991567090e12,
0.37166607986219303e9,
0.72691473071988846e6,
0.10726961437789255e4,
0.10000000000000000e1
};
extern double (far *$0DPOWER)();
if (x <= 0.0) {_domerr("y1",x,x); return HUGE;}
if (x < 8.0) {
xsquare = x*x;
y1 = x*$0DPOWER(xsquare,&y1P)/$0DPOWER(xsquare,&y1Q);
return y1 + twobypi*(j1(x)*log(x)-1.0/x);
}
xx = x - piby34;
x8 = 8.0/x;
_pandq1(x8,&p,&q);
return sqrt(2.0/(pi*x)) * (p*sin(xx) + q*cos(xx));
} /* y1 */
double j0(x)
double x;
{
double xsquare, xx, x8;
double p, q;
double sin(), cos(), sqrt(), fabs();
void _pandq0();
static double pi = 3.1415926535897932;
static double piby4 = 0.78539816339744831;
static struct {
int terms;
double tbl[12];
} j0P = {12,
0.18108389921416431e9,
-0.44464759561502412e8,
0.26292976097233912e7,
-0.66351202963350577e5,
0.90000108663859700e3,
-0.74117799951193489e1,
0.39771954892980604e-1,
-0.14463518634545936e-3,
0.36127859495623837e-6,
-0.60893587508087894e-9,
0.64247367849791009e-12,
-0.33133602728361709e-15
};
static struct {
int terms;
double tbl[4];
} j0Q = {4,
0.18108389921416430e9,
0.80621524203869792e6,
0.14154950117074173e4,
0.10000000000000000e1
};
static struct {
int terms;
double tbl[5];
} j0pP = {5,
0.21807736478830516e7,
0.30343163608475270e7,
0.11035444210405852e7,
0.11252515255664381e6,
0.22399036697750965e4
};
static struct {
int terms;
double tbl[6];
} j0pQ = {6,
0.21807736478830516e7,
0.30367122303337213e7,
0.11068209412295708e7,
0.11366275712613906e6,
0.23403140106394541e4,
0.10000000000000000e1
};
static struct {
int terms;
double tbl[5];
} j0qP = {5,
-0.17665456233082465e4,
-0.28720316121456664e4,
-0.12598828601325539e4,
-0.16263421062270593e3,
-0.44237584856933353e1
};
static struct {
int terms;
double tbl[6];
} j0qQ = {6,
0.11305891989633582e6,
0.18484510850351025e6,
0.82274660980144657e5,
0.11085805836751487e5,
0.35655140058576331e3,
0.10000000000000000e1
};
extern double (far *$0DPOWER)();
x = fabs(x);
if (x < 8.0) {
xsquare = x*x;
return $0DPOWER(xsquare,&j0P)/$0DPOWER(xsquare,&j0Q);
}
xx = x - piby4;
x8 = 8.0/x;
_pandq0(x8,&p,&q);
/*
xsquare = x8*x8;
p = $0DPOWER(xsquare,&j0pP)/$0DPOWER(xsquare,&j0pQ);
q = x8*$0DPOWER(xsquare,&j0qP)/$0DPOWER(xsquare,&j0qQ);
*/
return sqrt(2.0/(pi*x)) * (p*cos(xx) - q*sin(xx));
} /* j0 */
double j1(x)
double x;
{
double xsquare, xx, x8, value;
double p, q;
int negative = 0;
double sin(), cos(), sqrt();
void _pandq1();
static double pi = 3.1415926535897932;
static double piby34 = 2.35619449019234493;
extern double (far *$0DPOWER)();
static struct {
int terms;
double tbl[8];
} j1P = {8,
0.22148878804219631e18,
-0.25123742147032128e17,
0.84824207447812727e15,
-0.12498203672620249e14,
0.93165652967246732e11,
-0.36866689870229816e9,
0.74370238171199964e6,
-0.60795301796074136e3
};
static struct {
int terms;
double tbl[8];
} j1Q = {8,
0.44297757608439262e18,
0.51247127164848721e16,
0.29898363077254872e14,
0.11581921274668893e12,
0.32819403445341964e9,
0.69885861844850757e6,
0.10777412894333044e4,
0.10000000000000000e1
};
/* static struct {
int terms;
double tbl[5];
} j1pP = {5,
-0.17469576694409286e7,
-0.23669439140521428e7,
-0.82850363738723775e6,
-0.79574568713505959e5,
-0.14279066288270981e4
};
static struct {
int terms;
double tbl[6];
} j1pQ = {6,
-0.17469576694409286e7,
-0.23637451390226540e7,
-0.82423699065628189e6,
-0.78144050089391111e5,
-0.13084529833390797e4,
0.10000000000000000e1
};
static struct {
int terms;
double tbl[5];
} j1qP = {5,
0.14465282874995209e3,
0.17442916890924259e3,
0.51736532818365916e2,
0.37994453796980673e1,
0.36363466476034711e-1
};
static struct {
int terms;
double tbl[5];
} j1qQ = {5,
0.30859270133323172e4,
0.37343401060163018e4,
0.11191098527047487e4,
0.85223920643413404e2,
0.10000000000000000e1
};
*/
if (x < 0.0) {
negative = 1;
x = -x;
}
if (x < 8.0) {
xsquare = x*x;
value = x*$0DPOWER(xsquare,&j1P)/$0DPOWER(xsquare,&j1Q);
if (negative) return -value; else return value;
}
xx = x - piby34;
x8 = 8.0/x;
/*
xsquare = x8*x8;
p = $0DPOWER(xsquare,&j1pP)/$0DPOWER(xsquare,&j1pQ);
q = x8*$0DPOWER(xsquare,&j1qP)/$0DPOWER(xsquare,&j1qQ);
*/
_pandq1(x8,&p,&q);
value = sqrt(2.0/(pi*x)) * (p*cos(xx) - q*sin(xx));
if (negative) return -value; else return value;
} /* j1 */
void _pandq0(x, pptr, qptr)
double x;
double *pptr;
double *qptr;
{
double xsquare;
static struct {
int terms;
double tbl[5];
} P0p = {5,
0.21807736478830516e7,
0.30343163608475270e7,
0.11035444210405852e7,
0.11252515255664381e6,
0.22399036697750965e4
};
static struct {
int terms;
double tbl[6];
} P0q = {6,
0.21807736478830516e7,
0.30367122303337213e7,
0.11068209412295708e7,
0.11366275712613906e6,
0.23403140106394541e4,
0.10000000000000000e1
};
static struct {
int terms;
double tbl[5];
} Q0p = {5,
-0.17665456233082465e4,
-0.28720316121456664e4,
-0.12598828601325539e4,
-0.16263421062270593e3,
-0.44237584856933353e1
};
static struct {
int terms;
double tbl[6];
} Q0q = {6,
0.11305891989633582e6,
0.18484510850351025e6,
0.82274660980144657e5,
0.11085805836751487e5,
0.35655140058576331e3,
0.10000000000000000e1
};
extern double (far *$0DPOWER)();
xsquare = x*x;
*pptr = $0DPOWER(xsquare,&P0p)/$0DPOWER(xsquare,&P0q);
*qptr = x*$0DPOWER(xsquare,&Q0p)/$0DPOWER(xsquare,&Q0q);
}
void _pandq1(x, pptr, qptr)
double x;
double *pptr;
double *qptr;
{
double xsquare;
static struct {
int terms;
double tbl[5];
} P1p = {5,
-0.17469576694409286e7,
-0.23669439140521428e7,
-0.82850363738723775e6,
-0.79574568713505959e5,
-0.14279066288270981e4
};
static struct {
int terms;
double tbl[6];
} P1q = {6,
-0.17469576694409286e7,
-0.23637451390226540e7,
-0.82423699065628189e6,
-0.78144050089391111e5,
-0.13084529833390797e4,
0.10000000000000000e1
};
static struct {
int terms;
double tbl[5];
} Q1p = {5,
0.14465282874995209e3,
0.17442916890924259e3,
0.51736532818365916e2,
0.37994453796980673e1,
0.36363466476034711e-1
};
static struct {
int terms;
double tbl[5];
} Q1q = {5,
0.30859270133323172e4,
0.37343401060163018e4,
0.11191098527047487e4,
0.85223920643413404e2,
0.10000000000000000e1
};
extern double (far *$0DPOWER)();
xsquare = x*x;
*pptr = $0DPOWER(xsquare,&P1p)/$0DPOWER(xsquare,&P1q);
*qptr = x*$0DPOWER(xsquare,&Q1p)/$0DPOWER(xsquare,&Q1q);
}

204
Mix Power C v1/BIOS.C Normal file
View File

@ -0,0 +1,204 @@
/* IBM PC BIOS Functions */
/* Copyright (c) Mix Software 1988 */
cursblk()
{
_setcurs(0, _graphic() ? 7 : 13);
}
/* ------------------------------------------------------------ */
curslin()
{
int start;
_setcurs((start = _graphic() ? 7 : 13), start);
}
/* ------------------------------------------------------------ */
_graphic() /* returns 1 if graphics display, 0 if monochrome */
{
union REGS reg;
int display;
bios(0x11, &reg); /* get display type (bits 4 and 5 of ax) */
if ((reg.x.ax & 0x30) < 0x30) return 1; /* graphics */
else return 0; /* monochrome */
}
/* ------------------------------------------------------------ */
curson() /* set bit 5 of start scan line to 0 : IBM PC */
{ /* set bit 6 of start scan line to 0 : Tandy 2000
use & 0x00BF */
unsigned cursor, _getcurs();
cursor = _getcurs();
_setcurs((cursor >> 8) & 0x00DF, cursor & 0x00FF);
}
/* ------------------------------------------------------------ */
cursoff() /* set bit 5 of start scan line to 1 : IBM PC */
{ /* set bit 6 of start scan line to 1 : Tandy 2000
use | 0x0040 */
unsigned cursor, _getcurs();
cursor = _getcurs();
_setcurs((cursor >> 8) | 0x0020, cursor & 0x00FF);
}
/* ------------------------------------------------------------ */
unsigned _getcurs()
{
extern int _vapage;
union REGS reg;
reg.h.ah = 3;
reg.h.bh = _vapage;
bios(0x10, &reg);
return reg.x.cx;
}
/* ------------------------------------------------------------ */
_setcurs(start, stop)
int start, stop;
{
union REGS reg;
reg.h.ah = 1;
reg.h.ch = start;
reg.h.cl = stop;
bios(0x10, &reg);
}
/* ------------------------------------------------------------ */
clrscrn()
{
extern int _vattr;
clrscrn2(_vattr);
}
/* ------------------------------------------------------------ */
setcolor(background, palette)
int background, palette;
{
union REGS reg;
reg.h.ah = 11;
reg.h.bh = 0;
reg.h.bl = background;
bios(0x10, &reg);
reg.h.bh = 1;
reg.h.bl = palette;
bios(0x10, &reg);
}
/* ------------------------------------------------------------ */
int readch()
{ /* read character at current cursor position */
extern int _vapage;
union REGS reg;
reg.h.ah = 8;
reg.h.bh = _vapage;
bios(0x10, &reg);
return reg.h.al;
}
/* ------------------------------------------------------------ */
int readattr()
{ /* read attribute of character at current cursor position */
extern int _vapage;
union REGS reg;
reg.h.ah = 8;
reg.h.bh = _vapage;
bios(0x10, &reg);
return reg.h.ah;
}
/* ------------------------------------------------------------ */
#ifndef V_ASM
clrscrn2(attribute)
unsigned int attribute;
{
union REGS reg;
extern int _vattr;
_vattr = attribute;
reg.h.ah = 6;
reg.h.al = reg.h.ch = reg.h.cl = 0;
reg.h.dh = 24; reg.h.dl = 79;
reg.h.bh = attribute;
bios(0x10, &reg);
poscurs(0,0);
}
curscol()
{
extern int _vapage;
union REGS reg;
reg.h.ah = 3;
reg.h.bh = _vapage;
bios(0x10, &reg);
return reg.h.dl;
}
cursrow()
{
extern int _vapage;
union REGS reg;
reg.h.ah = 3;
reg.h.bh = _vapage;
bios(0x10, &reg);
return reg.h.dh;
}
poscurs(row, col)
int row,col;
{
union REGS reg;
extern int _vapage;
reg.h.ah = 2;
reg.h.bh = _vapage;
reg.h.dh = row;
reg.h.dl = col;
bios(0x10, &reg);
}
writechs(ch, attr, n)
int ch; /* character to write */
int attr; /* attribute */
int n; /* number of copies*/
{
union REGS reg;
extern int _vapage;
reg.h.ah = 9;
reg.h.bh = _vapage;
reg.h.bl = attr;
reg.x.cx = n;
bios(0x10, &reg);
}
getvmode()
{
union REGS reg;
reg.h.ah = 15;
bios(0x10, &reg);
return reg.h.al;
}
setvmode(mode)
int mode;
{
union REGS reg;
reg.h.ah = 0;
reg.h.al = mode;
bios(0x10, &reg);
}
int _vapage = 0; /* current crt page number */
int _vattr = 7; /* default attribute for scroll functions */
#endif

166
Mix Power C v1/BIOSFN.ASM Normal file
View File

@ -0,0 +1,166 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; bioscom(cmd, byte, port)
; -------------------------------------------------------
; int cmd; /* action to take 0..3 */
; char byte; /* character to send */
; int port; /* port number (0 = COM1 etc.) */
;
; return: upper 8 bits are port status
; lower 8 bits are character or value
; -------------------------------------------------------
;
IDT bioscom
DEF bioscom
;
bioscom PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MOV AH,AL
MOV CX,[BP][%PARM2]
MOV AL,CL
MOV DX,[BP][%PARM3]
INT >14
POP BP
RETFAR
END
;
; -------------------------------------------------------
; biosdisk(cmd, drive, head, track, sector, nsects, buffer)
; -------------------------------------------------------
; int cmd; /* action to take 0..5 */
; int drive; /* disk drive number 0.. */
; int head; /* head number */
; int track; /* physical track number */
; int sector; /* starting sector */
; int nsects; /* number of sectors (1..9) */
; char *buffer; /* address of buffer */
;
; return: status word
; -------------------------------------------------------
;
IDT biosdisk
DEF biosdisk
;
biosdisk PUSH BP
MOV BP,SP
MOV AH,[BP][%PARM1]
MOV AL,[BP][%PARM4+4] ; # of sectors
MOV BX,[BP][%PARM4+6] ; buffer
MOV CX,DS
MOV ES,CX
MOV CH,[BP][%PARM4] ; track number
MOV CL,[BP][%PARM4+2] ; sector number
MOV DH,[BP][%PARM3] ; head number
MOV DL,[BP][%PARM2] ; drive number
INT >13
XOR AH,AH
XCHG AL,AH
POP BP
RETFAR
END
;
; -------------------------------------------------------
; biosequip()
; -------------------------------------------------------
; return: word describing the equipment connected
; -------------------------------------------------------
;
IDT biosequi
IF LONGNAME
LDEF biosequip
ENDIF
IF SHORTNAM
DEF biosequi
ENDIF
;
biosequi INT >11
RETFAR
END
;
; -------------------------------------------------------
; bioskey(cmd)
; -------------------------------------------------------
; int cmd; /* action to take 0..2 */
; return: key value or status
; -------------------------------------------------------
;
IDT bioskey
DEF bioskey
;
bioskey MOV BX,SP
MOV AH,[BX][%PARM1-2]
INT >16
RETFAR
END
;
; -------------------------------------------------------
; biosmemory()
; -------------------------------------------------------
; return: number of 1k blocks of physical memory
; -------------------------------------------------------
;
IDT biosmemo
IF LONGNAME
LDEF biosmemory
ENDIF
IF SHORTNAM
DEF biosmemo
ENDIF
;
biosmemo INT >12
RETFAR
END
;
; -------------------------------------------------------
; long biosprint(cmd, byte, port)
; -------------------------------------------------------
; int cmd; /* action to take 0..5 */
; int byte; /* value of character */
; int port; /* printer number */
; -------------------------------------------------------
;
IDT biosprin
IF LONGNAME
LDEF biosprint
ENDIF
IF SHORTNAM
DEF biosprin
ENDIF
;
biosprin PUSH BP
MOV BP,SP
MOV AH,[BP][%PARM1]
MOV AL,[BP][%PARM2]
MOV DX,[BP][%PARM3]
INT >17
MOV AL,AH
XOR AH,AH
POP BP
RETFAR
END
;
; -------------------------------------------------------
; long biostime(cmd, newtime)
; -------------------------------------------------------
; int cmd; /* action to take 0..5 */
; int newtime; /* new value of time (if cmd=1)
; return: current timer count
; -------------------------------------------------------
;
IDT biostime
DEF biostime
;
biostime PUSH BP
MOV BP,SP
MOV AH,[BP][%PARM1]
MOV DX,[BP][%PARM2]
MOV CX,[BP][%PARM2+2]
INT >1A
MOV AX,DX
MOV DX,CX
POP BP
RETFAR
END

304
Mix Power C v1/CHAIN.C Normal file
View File

@ -0,0 +1,304 @@
/******************* Program chaining functions ********************/
/* Copyright (c) Mix Software 1988 */
system(cmd)
char *cmd;
{
extern int errno;
static char option[] = "/C";
char cmdline[130];
char *comspec;
int _spawn();
int len;
comspec = getenv("COMSPEC=");
if (comspec == NULL) { errno = ENOENT; return -1; }
if ((cmd == NULL) || (*cmd == '\0')) strcpy(cmdline,"\x00\x0d");
else {
len = strlen(cmd);
if (len > 124) {errno = E2BIG; return -1; }
strcpy(cmdline," /C ");
strcat(cmdline,cmd);
cmdline[0] = len+3;
cmdline[len+4] = '\x0d';
}
return _spawn(comspec,cmdline,_copyenv(NULL));
} /* system */
int execl(pathname, arg0)
char *pathname;
char *arg0;
{
return _spawn1(P_OVERLAY,pathname,&arg0,NULL,0);
}
int execle(pathname, arg0)
char *pathname;
char *arg0;
{
char **argptr = &arg0;
while (*argptr != NULL) ++argptr;
return _spawn1(P_OVERLAY,pathname,&arg0,*++argptr,0);
}
int execlp(pathname, arg0)
char *pathname;
char *arg0;
{
return _spawn1(P_OVERLAY,pathname,&arg0,NULL,1);
}
int execlpe(pathname, arg0)
char *pathname;
char *arg0;
{
char **argptr = &arg0;
while (*argptr != NULL) ++argptr;
return _spawn1(P_OVERLAY,pathname,&arg0,*++argptr,1);
}
int execv(pathname, argv)
char *pathname;
char **argv;
{
return _spawn1(P_OVERLAY,pathname,argv,NULL,0);
}
int execve(pathname, argv, envp)
char *pathname;
char *argv[];
char *envp[];
{
return _spawn1(P_OVERLAY,pathname,argv,envp,0);
}
int execvp(pathname, argv)
char *pathname;
char *argv[];
{
return _spawn1(P_OVERLAY,pathname,argv,NULL,1);
}
int execvpe(pathname, argv, envp)
char *pathname;
char *argv[];
char *envp[];
{
return _spawn1(P_OVERLAY,pathname,argv,envp,1);
}
int spawnl(modeflag, pathname, arg0)
int modeflag;
char *pathname;
char *arg0;
{
return _spawn1(modeflag,pathname,&arg0,NULL,0);
}
int spawnle(modeflag, pathname, arg0)
int modeflag;
char *pathname;
char *arg0;
{
char **argptr = &arg0;
while (*argptr != NULL) ++argptr;
return _spawn1(modeflag,pathname,&arg0,*++argptr,0);
}
int spawnlp(modeflag, pathname, arg0)
int modeflag;
char *pathname;
char *arg0;
{
return _spawn1(modeflag,pathname,&arg0,NULL,1);
}
int spawnlpe(modeflag, pathname, arg0)
int modeflag;
char *pathname;
char *arg0;
{
char **argptr = &arg0;
while (*argptr != NULL) ++argptr;
return _spawn1(modeflag,pathname,&arg0,*++argptr,1);
}
int spawnv(modeflag, pathname, argv)
int modeflag;
char *pathname;
char *argv[];
{
return _spawn1(modeflag,pathname,argv,NULL,0);
}
int spawnve(modeflag, pathname, argv, envp)
int modeflag;
char *pathname;
char *argv[];
char *envp[];
{
return _spawn1(modeflag,pathname,argv,envp,0);
}
int spawnvp(modeflag, pathname, argv)
int modeflag;
char *pathname;
char *argv[];
{
return _spawn1(modeflag,pathname,argv,NULL,1);
}
int spawnvpe(modeflag, pathname, argv, envp)
int modeflag;
char *pathname;
char *argv[];
char *envp[];
{
return _spawn1(modeflag,pathname,argv,envp,1);
}
/*
spawn and exec driver.
*/
int _spawn1(modeflag, pathname, argv, envp, pathflag)
int modeflag; /* P_WAIT, P_NOWAIT or P_OVERLAY */
char *pathname; /* name of command or exe file */
char *argv[]; /* list of arguments */
char *envp[]; /* pointer to environment */
int pathflag; /* search path environment string */
{
extern int $$ENVALT;
extern unsigned $$ENVIR;
extern char **environ;
extern int errno;
extern int (*_p_chain)();
extern int (*_p_chenv)();
char cmdline[128], path[128];
char *p;
char *pathenv;
int len, handle, status;
if (modeflag == P_NOWAIT) { errno = EINVAL; return -1;}
if (envp == NULL) { /* no environment, use current program's */
if ($$ENVALT != 0) envp = environ;
}
else if (envp == environ) { /* caller has passed current environment */
if ($$ENVALT == 0) envp = NULL;
}
/* envp is null if the original environment will be passed */
if (argv != NULL) { /* make command line from argument list */
if (*argv != NULL) {
*cmdline = ' ';
p = &cmdline[1];
*p = '\0';
len = 1;
while (*++argv != NULL) {
len += strlen(*argv)+1;
if (len > 127) { errno = E2BIG; return -1; }
strcat(cmdline,*argv);
strcat(cmdline," ");
}
cmdline[0] = len-1;
if (len < 127) cmdline[len] = 0x0d;
}
}
/* search for the command or exe file */
if (pathflag != 0) pathenv = getenv("PATH="); else pathenv = 0;
handle = _openfind(pathname,pathenv,".COM;.EXE",0,1,path);
if (handle == -1) { errno = ENOENT; return -1; }
/* execute task */
if (modeflag == P_WAIT) { /* execute and wait for completion */
_sys_ab(0x3e00,handle,&status);
if (envp == NULL) envp = $$ENVIR; else envp = _copyenv(envp);
status = _spawn(path,cmdline,envp);
if (envp != $$ENVIR) free(envp);
return(status);
}
else { /* overlay current program */
if (_p_chain == NULL) {errno = EINVAL; return -1; }
if (envp == NULL) status = (*_p_chain)(handle,cmdline);
else {
envp = _copyenv(envp);
_sys_ab(0x3e00,handle,&status);
status = (*_p_chenv)(path,cmdline,envp);
if (envp != $$ENVIR) free(envp);
}
return status;
}
} /* _spawn1 */
/* Open a file by searching. Name is the basic file name, envir is
a list of possible prefixes and extlist is a list of possible
extensions. Extensions are tried only if the file does not
already have an extension. If the file is succesfully opened,
a file handle is returned, otherwise -1 is returned.
Extensions are tried first, followed by directories.
*/
int _openfind(name, envir, extlist, pathfirst, nonull, newname)
int pathfirst; /* search environment before default directory */
int nonull; /* do not try file without extension */
char *extlist; /* list of extensions to try (if none supplied) */
char *envir; /* list of prefixes to search for file */
char *name; /* base name of file */
char *newname; /* return buffer for name found by the search */
{
int status;
char *p, *q;
char *extptr, *extloc, *final;
char nul = '\0';
int tryit;
strcpy(newname,name);
if (extlist == NULL) extlist = &nul;
else {
p = name+strlen(name);
do { /* search for extension */
if (*p == '.') break; /* found */
if (*p == '\\') break; /* stop on directory name */
if (*p == ':') break; /* stop on disk name */
--p;
} while (p != name);
if (*p == '.') extlist = &nul; /* extension supplied */
}
if (pathfirst == 0) {
if ((nonull == 0) || (extlist == &nul)) {
if (_sys_acd(0x3d00,0,newname,&status) == 0) return status;
}
final = &nul;
}
else final = ";"; /* to try default directory last */
if (envir == NULL) q = &nul; else q = envir;
if (pathfirst == 0) extptr = extlist; else extptr = &nul;
extloc = newname+strlen(newname);
do { /* try all combinations */
if (*extptr != '\0') { /* try next extension */
p = extloc;
while ((*extptr != ';') && (*extptr != '\0')) *p++ = *extptr++;
*p = '\0';
if (*extptr == ';') ++extptr;
tryit = 1;
}
else { /* try next prefix */
p = newname;
while ((*q != ';') && (*q != '\0')) *p++ = *q++;
if (*q == ';') ++q;
if (p != newname) if (*(p-1) != '\\') *p++ = '\\';
*p = '\0';
strcat(p,name);
extptr = extlist;
extloc = newname+strlen(newname);
if ((nonull == 0) || (extlist == &nul)) tryit = 1; else tryit = 0;
}
if (tryit) { /* try to open file with this path */
if (_sys_acd(0x3d00,0,newname,&status) == 0) return status;
}
if (*q == '\0') { /* try default directory (if not tried already) */
q = final;
final = &nul;
}
} while ((*q != '\0') || (*extptr != '\0'));
return -1; /* not found */
} /* _openfind */

101
Mix Power C v1/CLOSE.C Normal file
View File

@ -0,0 +1,101 @@
/* Close files */
/* Copyright (c) Mix Software 1988 */
fcloseall() {
int fd;
int count = 0;
for (fd = 5; fd < MAXFILES; fd++) {
if (_iob[fd] != NULL) {
if (close(fd) == 0) count++;
}
}
return count;
}
/* ------------------------------------------------------------ */
fclose(fp)
FILE *fp;
{
int fd;
int x;
extern int _dupcnt_;
if (fp == NULL) return EOF;
fd = fp->fd;
if (_dupcnt_ != 0) {
for (x = fd+1; x < MAXFILES; x++) {
if (_iob[x] == fp) fd = x;
}
}
return close(fd);
}
/* ------------------------------------------------------------ */
close(fd)
int fd;
{
int _fflush(), _sys_ab(), _sysabcd();
int status = 0;
int i;
FILE *fp;
extern int (*_fileerr)();
extern int errno;
extern int _dupcnt_;
extern FILE _STDFL1, _STDFL5;
fp = _iob[fd];
if (fp == NULL) {
if (_sys_ab(0x3e00,fd,&status) == 0) return 0;
errno = EBADF;
return -1;
}
if (fp->file.dirty & fdwrite) status = _fflush(fp);
if (fp->file.flags & fdctlz) {
if (fp->file.mode == O_WRONLY) {
if (status==0) {
if (_sysabcd(0x4000,fp->file.handle,1,"\032",&status)==0)
status = 0;
}
}
}
if (fp->file.device == 0) {
if (_sys_ab(0x3e00,fd,&status)==0) status = 0;
}
if (status) {
(*_fileerr)(status,fp);
return -1;
}
_iob[fd] = NULL;
if (_dupcnt_ != 0) {
for (i = MAXFILES-1; i > 4; i--) {
if (_iob[i] == fp) {
fp = NULL;
i = 0;
--_dupcnt_;
}
}
}
if (fp->file.flag2 & fd2temp) _sys_ad(0x4100,fp->file.pathnm,&status);
if (fp != NULL) {
if ((fp > &_STDFL1) || (fp < &_STDFL5)) {
if ((fp->file.flags & fdsetbuf) == 0) free(fp->file.bufr);
free(fp->file.pathnm);
free(fp);
}
}
return 0;
}
/* ------------------------------------------------------------ */
_stdclose(fp)
FILE *fp;
{
return 0;
}
int _dupcnt_ = 0;

224
Mix Power C v1/CONVERT.C Normal file
View File

@ -0,0 +1,224 @@
/* Numeric conversions. */
/* Copyright (c) Mix Software 1988 */
/* ------------------------------------------------------------ */
/* convert a string to an integer */
atoi(s) /* decode an integer */
char *s; /* pointer to integer string */
{
int sflag = 1, value = 0;
while (isspace(*s)) ++s;
if (*s == '+' || *s == '-')
if (*s++ == '-') sflag = -1;
while (*s > 47 && *s < 58) value = 10 * value + (*s++ - 48);
return value * sflag;
}
/* ------------------------------------------------------------ */
/* convert a string to a long integer */
long atol(s) /* decode a long integer */
char *s; /* pointer to integer string */
{
int sflag = 1;
long value = 0, base = 10;
while (isspace(*s)) ++s;
if (*s == '+' || *s == '-')
if (*s++ == '-') sflag = -1;
while (*s > 47 && *s < 58) value = base * value + (*s++ - 48);
return value * sflag;
}
/* ------------------------------------------------------------ */
/* convert a string to a long integer */
long strtol(nptr, endptr, base) /* convert a string to a long */
char *nptr; /* pointer to string */
char **endptr;
int base;
{
int sflag = 0;
long value = 0;
long strtoul();
int c, v;
while (isspace(*nptr)) ++nptr; /* skip white space */
if (*nptr == '+' || *nptr == '-')
if (*nptr++ == '-') sflag = -1;
value = strtoul(nptr, endptr, base);
if (sflag) return -value; else return value;
}
/* ------------------------------------------------------------ */
/* convert a string to an unsigned long integer */
long strtoul(nptr, endptr, base) /* convert a string to a long */
char *nptr; /* pointer to string */
char **endptr;
int base;
{
unsigned long value = 0;
int c, v;
while (isspace(*nptr)) ++nptr; /* skip white space */
if (*nptr == '0') {
if (toupper(c=*++nptr) == 'X') {
base = 16;
++nptr;
}
else {
if (base == 0) {
if (c >= '1' && c <= '7') base = 8;
else base = 10;
}
}
}
else if (base == 0) base = 10;
do {
if (isalnum(c = *nptr++)) {
if (isdigit(c)) v = c - 48; else v = toupper(c) - 55;
if (v < base) value = base * value + v; else v = -1;
}
else v = -1;
}
while (v >= 0);
if (endptr) *endptr = nptr-1;
return value;
}
/* ------------------------------------------------------------ */
/* convert a string to a double */
double strtod(nptr, endptr)
char *nptr;
char **endptr;
{
char bufr[50];
char *p, *q;
int c;
double atof();
p = bufr;
q = p + sizeof(bufr) - 4;
while (isspace(*nptr)) ++nptr;
if (*nptr == '+' || *nptr == '-') *p++ = *nptr++;
while (isdigit(*nptr) && (p < q)) *p++ = *nptr++;
if (*nptr == '.') {
*p++ = *nptr++;
while (isdigit(*nptr) && (p < q)) *p++ = *nptr++;
}
if ((c = toupper(*nptr)) == 'D' || c == 'E') {
*p++ = *nptr++;
if (*nptr == '+' || *nptr == '-') *p++ = *nptr++;
while (isdigit(*nptr) && (p < q)) *p++ = *nptr++;
}
*p = 0;
if (endptr != 0) *endptr = nptr;
return atof(bufr);
}
/* ------------------------------------------------------------ */
/* convert an integer to a string */
char *itoa(value, string, radix)
int value;
char *string;
int radix;
{
char *ptr;
char *utoa();
int flag = 0;
if (radix == 10) {
if (value < 0) {
if (value == 0x8000) return strcpy(string, "-32768");
flag = '-';
value = -value;
}
ptr = string;
do {
*(ptr++) = value % 10 + 48;
} while ((value /= 10) != 0);
*ptr++ = flag;
*ptr = 0;
return strrev(string);
}
else return utoa(value,string,radix);
}
/* ------------------------------------------------------------ */
/* convert an unsigned integer to a string */
utoa(value, string, radix)
unsigned value;
char *string;
int radix;
{
char *ptr, c;
extern int _hexcaseA;
ptr = string;
do {
c = value % radix;
if (c > 9) c += _hexcaseA; else c += 48;
*(ptr++) = c;
} while ((value /= radix) != 0);
*ptr = '\0';
return strrev(string);
}
/* ------------------------------------------------------------ */
/* convert a long integer to a string */
char *ltoa(value, string, radix)
long value;
char *string;
int radix;
{
char *ptr;
char *ultoa();
int flag = 0;
if (radix == 10) {
if (value < 0) {
if (value == -2147483648) return strcpy(string, "-2147483648");
flag = '-';
value = -value;
}
ptr = string;
do {
*(ptr++) = value % 10 + 48;
} while ((value /= 10) != 0);
*ptr++ = flag;
*ptr = 0;
return strrev(string);
}
else return ultoa(value,string,radix);
}
/* ------------------------------------------------------------ */
/* convert an unsigned long integer to a string */
ultoa(value, string, radix)
unsigned long value;
char *string;
int radix;
{
char *ptr, c;
extern int _hexcaseA;
ptr = string;
do {
c = value % radix;
if (c > 9) c += _hexcaseA; else c += 48;
*(ptr++) = c;
} while ((value /= radix) != 0);
*ptr = '\0';
return strrev(string);
}
_atoi(ptr) /* decode an integer */
char **ptr; /* pointer to addr of 1st digit */
{
int n = 0;
while (*(*ptr) > 47 && *(*ptr) < 58) n = 10 * n + *(*ptr)++ - 48;
return n;
}
int _hexcaseA = 'a'-10; /* character value of the digit 10 */

154
Mix Power C v1/DISABLE.ASM Normal file
View File

@ -0,0 +1,154 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; disable() - disable interrupts
; -------------------------------------------------------
;
IDT disable
DEF disable
;
disable CLI
RETFAR
END
;
; -------------------------------------------------------
; enable() - enable interrupts
; -------------------------------------------------------
;
IDT enable
DEF enable
;
enable STI
RETFAR
END
;
; -------------------------------------------------------
; geninterrupt(intr_num)
; -------------------------------------------------------
; int intr_num - interrupt number
; -------------------------------------------------------
;
IDT geninter
IF LONGNAME
LDEF geninterrupt
ENDIF
IF SHORTNAM
DEF geninter
ENDIF
DREF _AX
DREF _BX
DREF _CX
DREF _DX
DREF _SP
DREF _BP
DREF _DI
DREF _SI
DREF _CS
DREF _DS
DREF _ES
DREF _SS
;
geninter PUSH BP
SUB SP,INSTRSZ
MOV BP,SP
MOV SI,INSTRINT
MOV DI,BP
MOV AX,SS
MOV ES,AX
MOV CX,INSTRSZ
CLD
REP
MOVSB
MOV AX,[BP][%PARM1+INSTRSZ]
MOV [BP][%1],AL
MOV AX,CS
PUSH AX
CALL DOINT
SEGSS
MOV [_AX],AX
SEGSS
MOV [_DS],DS
MOV AX,SS
MOV DS,AX
MOV [_BX],BX
MOV [_CX],CX
MOV [_DX],DX
MOV [_SP],SP
MOV [_BP],BP
MOV [_DI],DI
MOV [_SI],SI
MOV [_CS],CS
MOV [_ES],ES
MOV [_SS],SS
ADD SP,INSTRSZ
POP BP
RETFAR
DOINT MOV AX,SS
PUSH AX
PUSH BP
MOV AX,[_AX]
MOV BX,[_BX]
MOV CX,[_CX]
MOV DX,[_DX]
MOV BP,[_BP]
MOV DI,[_DI]
MOV SI,[_SI]
MOV ES,[_ES]
CMP [_DS],-1
JZ DOIT
MOV DS,[_DS]
DOIT RETFAR
DORG 0
INSTRINT INT >21
INSTRRET RETSEG
DORG 2*(($+1)/2)
INSTRSZ EQU $-INSTRINT
END
;
; global register variables for geninter
;
IDT _AX
DDEF _AX
DDEF _BX
DDEF _CX
DDEF _DX
DDEF _SP
DDEF _BP
DDEF _DI
DDEF _SI
DDEF _CS
DDEF _DS
DDEF _ES
DDEF _SS
DDEF _AL
DDEF _AH
DDEF _BL
DDEF _BH
DDEF _CL
DDEF _CH
DDEF _DL
DDEF _DH
;
DORG 0
_AX
_AL DB 0-0
_AH DB 0-0
_BX
_BL DB 0-0
_BH DB 0-0
_CX
_CL DB 0-0
_CH DB 0-0
_DX
_DL DB 0-0
_DH DB 0-0
_SP DW 0-0
_BP DW 0-0
_DI DW 0-0
_SI DW 0-0
_CS DW 0-0
_DS DW -1
_ES DW 0-0
_SS DW 0-0
END

35
Mix Power C v1/DIV.ASM Normal file
View File

@ -0,0 +1,35 @@
;
; Copyright (c) Mix Software 1988
;
; ---------------------------------------
; div - divide and return both
; quotient and reamainder
; ---------------------------------------
; typedef struct {
; int quot; /* quotient */
; int rem; /* remainder */
; } div_t;
;
; div_t div(int numer, int denom)
; {
; div_t s;
; s.quot = numer/denom;
; s.rem = numer%denom;
; return s;
; }
;
IDT div
DEF div
NUMER EQU PARM1+4-2
DENOM EQU PARM2+4-2
STRUC EQU PARM1+2-2
div MOV BX,SP
MOV AX,[BX][%NUMER] ; numerator
CWD
IDIV [BX][%DENOM]
MOV SI,[BX][%STRUC]
MOV [SI],AX
MOV [SI][%2],DX
MOV AX,SI
RETFAR
END

236
Mix Power C v1/DOS.H Normal file
View File

@ -0,0 +1,236 @@
/*$no list*//*$no trace <<< dos.h >>> */
/* Copyright (c) Mix Software 1988 */
#define time_t long
extern int _doserrno;
extern unsigned char _osmajor;
extern unsigned char _osminor;
extern unsigned int _psp;
extern unsigned int _version;
extern int _AX;
extern signed char _AH;
extern signed char _AL;
extern int _BX;
extern signed char _BH;
extern signed char _BL;
extern int _CX;
extern signed char _CH;
extern signed char _CL;
extern int _DX;
extern signed char _DH;
extern signed char _DL;
extern int _SI;
extern int _DI;
extern int _BP;
extern int _CS;
extern int _DS;
extern int _ES;
#define FP_SEG(farptr) (*((unsigned *)&(farptr) + 1))
#define FP_OFF(farptr) (*((unsigned *)&(farptr)))
#define MK_FP(seg,off) ((char far *)(((long)(seg) << 16) | (off)))
#define FA_NORMAL 0x0000
#define FA_RDONLY 0x0001
#define FA_HIDDEN 0x0002
#define FA_SYSTEM 0x0004
#define FA_LABEL 0x0008
#define FA_DIREC 0x0010
#define FA_ARCH 0x0020
#if !defined(WORDREGS)
struct WORDREGS {
unsigned int ax;
unsigned int bx;
unsigned int cx;
unsigned int dx;
unsigned int si;
unsigned int di;
unsigned int cflag;
};
#endif
#if !defined(BYTEREGS)
struct BYTEREGS {
unsigned char al, ah;
unsigned char bl, bh;
unsigned char cl, ch;
unsigned char dl, dh;
};
#endif
#if !defined(REGS)
union REGS {
struct WORDREGS x;
struct BYTEREGS h;
struct WORDREGS word;
struct BYTEREGS byte;
};
#endif
#if !defined(SREGS)
struct SREGS {
unsigned int es;
unsigned int cs;
unsigned int ss;
unsigned int ds;
};
#endif
#if !defined(REGPACK)
struct REGPACK {
unsigned r_ax, r_bx, r_cx, r_dx;
unsigned r_bp, r_si, r_di;
unsigned r_ds, r_es, r_flags;
};
#endif
#if !defined(DOSERROR)
struct DOSERROR {
int exterror;
char class;
char action;
char locus;
};
#endif
#if !defined(date)
struct date {
int da_year;
char da_day;
char da_mon;
};
#endif
#if !defined(time)
struct time {
unsigned char ti_min;
unsigned char ti_hour;
unsigned char ti_hund;
unsigned char ti_sec;
};
#endif
#if !defined(dfree)
struct dfree {
unsigned df_avail; /* available clusters */
unsigned df_total; /* total clusters */
unsigned df_bsec; /* bytes per sector */
unsigned df_sclus; /* sectors per cluster */
};
#endif
#if !defined(fatinfo)
struct fatinfo {
char fi_sclus; /* Sectors per cluster */
char fi_fatid; /* identification byte */
int fi_nclus; /* number of clusters */
int fi_bysec; /* bytes per sector */
};
#endif
#if !defined(ftime)
struct ftime {
unsigned ft_tsec : 5; /* two seconds */
unsigned ft_min : 6; /* minutes */
unsigned ft_hour : 5; /* hours */
unsigned ft_day : 5; /* day of month */
unsigned ft_month: 4; /* month */
unsigned ft_year : 7; /* year - 1980 */
};
#endif
#if !defined(fcb)
struct fcb {
char fcb_drive; /* drive number */
char fcb_name[8]; /* file name */
char fcb_ext[3]; /* file extension */
int fcb_curblk; /* block number */
int fcb_recsize; /* logical record size */
long fcb_filsize; /* file size */
int fcb_date; /* Date file was last written */
char fcb_resv[10]; /* Reserved for DOS */
char fcb_currec; /* record in block */
long fcb_random; /* random record number */
};
#endif
#if !defined(country)
struct country {
int co_date; /* date format */
char co_curr[5]; /* currency symbol string */
char co_thsep[2]; /* thousands separator character */
char co_desep[2]; /* decimal separator character */
char co_dtsep[2]; /* date separator character */
char co_tmsep[2]; /* time separator character */
char co_currstyle; /* currency format */
char co_digits; /* number digits after decimal */
char co_timestyle; /* time format */
int (far *co_case)(); /* case map call address */
char co_dasep; /* data-list separator */
char co_fill[11]; /* reserved */
}
#endif
int absread(int drive, int nsects, int sector, void *buffer);
int abswrite(int drive, int nsects, int sector, void *buffer);
int allocmem(unsigned size, unsigned *seg);
int asm(void *codeptr, void *dataptr);
int bdosptr(int fn, void *address, unsigned al);
struct country *country(int code, struct country *info);
void ctrlbrk(int (*handler)(void));
void disable(void);
int dosexterr(struct DOSERROR *errinfo);
time_t dostounix(struct date dosdate, struct time dostime);
void enable(void);
int freemem(unsigned seg);
void geninterrupt(int intno);
int getcbrk(void);
int getcseg(void);
void getdate(struct date *datebuf);
void getdfree(int drive, struct dfree *diskdata);
int getdseg(void);
char far *getdta(void);
void getfat(int drive, struct fatinfo *fat);
void getfatd(struct fatinfo *fat);
unsigned getpsp(void);
void gettime(struct time *timebuf);
void interrupt (far *getvect(int intno))();
int getverify(void);
void harderr(int (*handler)(int error, int ax, int bp, int si));
void hardresume(int cmd);
void hardretn(int error);
int inp(unsigned port);
int inport(int port);
int inportb(int port);
int int86(int interrupt, union REGS *inregs, union REGS *outregs);
int int86x(int interrupt, union REGS *inregs, union REGS *outregs,
struct SREGS *segregs);
int intdos(union REGS *inregs, union REGS *outregs);
int intdosx(union REGS *inregs, union REGS *outregs,
struct SREGS *segregs);
void intr(int interrupt, struct REGPACK *regs);
void keep(int status, int size);
int outp(unsigned port, int c);
void outport(unsigned port, int word);
void outportb(int port, char c);
char *parsfnm(char *filename, struct fcb *buffer, int option);
int peek(unsigned segment, unsigned offset);
int peekb(unsigned segment, unsigned offset);
void poke(unsigned segment, unsigned offset, int value);
void pokeb(unsigned segment, unsigned offset, char value);
void segread(struct SREGS *sregs);
int setblock(unsigned seg, unsigned size);
int setcbrk(int flag);
void setdate(struct date *datebuf);
void setdta(char far *address);
void settime(struct time *timebuf);
void setvect(int intno, void interrupt (far *handler)());
void setverify(int flag);
void sleep(unsigned seconds);
void unixtodos(time_t timer, struct date *dosdate, struct time *dostime);
/*$list*//*$trace <<< dos.h >>> */

237
Mix Power C v1/DOSETC.C Normal file
View File

@ -0,0 +1,237 @@
/* Copyright (c) Mix Software 1988 */
int _chmod(filename, func, attrib)
char *filename;
int func;
int attrib;
{
extern int errno, _doserrno;
int status;
if (_sysacdc(0x4300+(func & 0x0001),attrib,filename,&status) == 0)
return status;
errno = _doserrno;
return -1;
}
int getcbrk()
{
int dxval;
_sys_add(0x3300,0,&dxval);
return dxval & 0x00ff;
}
int setcbrk(value)
int value;
{
int dxval;
_sys_add(0x3301,value,&dxval);
return value;
}
getcurdir(drive, direc) /* get default directory */
int drive; /* drive (0=default, 1=a, 2=b, etc) */
char *direc; /* buffer for result */
{
int status;
if (_sysdxsi(0x4700,drive,direc,&status) == 0) return 0;
return -1;
}
void getdfree(drive, dfreep)
int drive;
struct dfree *dfreep;
{
union REGS r;
r.h.ah = 0x36;
r.x.dx = drive;
intdos(&r,&r);
dfreep->df_avail = r.x.bx;
dfreep->df_total = r.x.dx;
dfreep->df_bsec = r.x.cx;
dfreep->df_sclus = r.x.ax;
}
int getdisk()
{
return _sys_al(0x1900);
}
int setdisk(drive)
int drive;
{
int result;
_sys_ad(0x0e00,drive,&result);
return result & 0x00ff;
}
int getftime(handle, ftimep)
int handle;
struct ftime *ftimep;
{
extern int errno;
struct {
int time;
int date;
} *cvt;
union REGS r;
r.x.ax = 0x5700;
r.x.bx = handle;
intdos(&r,&r);
if (r.x.cflag != 0) {
errno = r.x.ax;
return -1;
}
cvt = ftimep;
cvt->time = r.x.cx;
cvt->date = r.x.dx;
return 0;
}
int setftime(handle, ftimep)
int handle;
struct ftime *ftimep;
{
extern int errno;
struct {
int time;
int date;
} *cvt;
union REGS r;
r.x.ax = 0x5701;
r.x.bx = handle;
cvt = ftimep;
r.x.cx = cvt->time;
r.x.dx = cvt->date;
intdos(&r,&r);
if (r.x.cflag != 0) {
errno = r.x.ax;
return -1;
}
return 0;
}
unsigned getpsp()
{
union REGS r;
r.x.ax = 0x6200;
intdos(&r,&r);
return r.x.bx;
}
int getverify()
{
return _sys_al(0x5400);
}
void setverify(value)
int value;
{
_sys_ad(0x2e00+(value & 0x0001),0);
}
int ioctl(handle,cmd,argdx,argcx)
int handle;
int cmd;
int *argdx;
int argcx;
{
extern int errno, _doserrno;
union REGS r;
r.h.ah = 0x44;
r.h.al = cmd;
r.x.bx = handle;
r.x.cx = argcx;
r.x.dx = *argdx;
if (cmd == 1) r.h.dh = 0;
intdos(&r,&r);
if (r.x.cflag) { errno = _doserrno; return -1; }
if (cmd < 2) return r.x.dx;
return r.x.ax;
}
void keep(status,size) /* terminate and stay resident */
int status; /* status code to return to caller */
int size; /* total size of memory to retain (in paragraphs) */
{
int st;
_sys_ad(0x3100+(status & 0x00ff),size,&st);
}
struct fcb {
char fcb_drive; /* drive number */
char fcb_name[8]; /* file name */
char fcb_ext[3]; /* file extension */
int fcb_curblk; /* block number */
int fcb_recsize; /* logical record size */
long fcb_filsize; /* file size */
int fcb_date; /* Date file was last written */
char fcb_resv[10]; /* Reserved for DOS */
char fcb_currec; /* record in block */
long fcb_random; /* random record number */
};
char *parsfnm(cmdline, fcbptr, option)
char *cmdline;
struct fcb *fcbptr;
int option;
{
union REGS r;
struct SREGS s;
void segread();
r.h.ah = 0x29;
r.h.al = option;
r.x.si = cmdline;
r.x.di = fcbptr;
segread(&s);
s.es = s.ds;
intdosx(&r,&r,&s);
if (r.h.al != 0) return 0;
return r.x.si;
}
int randbrd(fcbptr, reccnt)
struct fcb *fcbptr;
int reccnt;
{ /* random block read */
int status;
_sys_acd(0x2700,reccnt,fcbptr,&status);
return status&0xff;
}
int randbwr(fcbptr, reccnt)
struct fcb *fcbptr;
int reccnt;
{ /* random block read */
int status;
_sys_acd(0x2800,reccnt,fcbptr,&status);
return status&0xff;
}
struct country {
int co_date; /* date format 0=mdy, 1=dmy, 2=ymd */
char co_curr[5]; /* currency symbol */
char co_thsep[2]; /* thousands separator character */
char co_desep[2]; /* decimal separator character */
char co_dtsep[2]; /* date separator character */
char co_tmsep[2]; /* time separator character */
char co_curstyle; /* currency format */
char co_digits; /* number of significant digits in currency */
char co_timestyle; /* time format, 0=12 hour, 1=24 hour clock */
int (far *co_case)(); /* case conversion function */
char co_fill[10]; /* fill to 34 bytes */
}
struct country *country(countrycode, countryp)
int countrycode;
struct country *countryp;
{
int opcode = 0x3800;
int bx = 0;
if (countrycode > 254) {
opcode = 0x38ff;
bx = countrycode;
}
else opcode |= countrycode;
_sysabcd(opcode,bx,0,countryp,&bx);
return countryp;
}

27
Mix Power C v1/DSTRING.C Normal file
View File

@ -0,0 +1,27 @@
/* Dynamic string conversion */
/* Copyright (c) Mix Software 1988 */
STRING *stods(s) /* convert string to dynamic string */
char *s; /* s is a normal C string */
{
int length;
STRING *ptr;
STRING *calloc();
int strlen(); /* get length of string */
length = strlen(s);
ptr = malloc(sizeof(int) + length);
if (ptr != NULL) {
ptr->length = length;
movmem(s, ptr->string, length);
}
return ptr;
}
dstos(ptr,s) /* convert dynamic string into normal C string */
STRING *ptr; /* pointer to dynamic string */
char *s; /* normal string */
{
movmem(ptr->string, s, ptr->length);
*(s + ptr->length) = '\0';
}

89
Mix Power C v1/DTAFAT.ASM Normal file
View File

@ -0,0 +1,89 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; getdta - return disk transfer address
; char far *getdta()
; -------------------------------------------------------
;
IDT getdta
DEF getdta
;
getdta MOV AH,>2F
INT >21
MOV DX,ES
MOV AX,BX
RETSEG
END
;
; -------------------------------------------------------
; setdta - return disk transfer address
; char far *getdta()
; -------------------------------------------------------
;
IDT setdta
DEF setdta
;
setdta PUSH BP
MOV BP,SP
PUSH DS
MOV DX,[BP][%PARM1]
MOV DS,[BP][%PARM2]
MOV AH,>1A
INT >21
POP AX
MOV DS,AX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; getfat - return file allocation table information
; void getfat(int drive, struct fatinfo *fatblkp);
; -------------------------------------------------------
;
IDT getfat
DEF getfat
;
getfat PUSH BP
MOV BP,SP
PUSH DS
MOV DX,[BP][%PARM1]
MOV AH,>1C
INT >21
MOV AH,[BX]
POP BX
MOV DS,BX
MOV BX,[BP][%PARM2]
MOV [BX],AL
MOV [BX][%1],AH
MOV [BX][%2],DX
MOV [BX][%4],CX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; getfatd - return file allocation table information
; void getfat(struct fatinfo *fatblkp);
; -------------------------------------------------------
;
IDT getfatd
DEF getfatd
;
getfatd PUSH BP
MOV BP,SP
PUSH DS
MOV AH,>1B
INT >21
MOV AH,[BX]
POP BX
MOV DS,BX
MOV BX,[BP][%PARM1]
MOV [BX],AL
MOV [BX][%1],AH
MOV [BX][%2],DX
MOV [BX][%4],CX
POP BP
RETSEG
END

51
Mix Power C v1/DUP.C Normal file
View File

@ -0,0 +1,51 @@
/* Duplicate file handle */
/* Copyright (c) Mix Software 1988 */
int dup(fd)
int fd;
{ /* duplicate a file descriptor - both descriptors use the
same file pointer. */
extern int errno, _doserrno;
extern int _dupcnt_;
int handle;
if (fd < 0 || fd > MAXFILES || _iob[fd] == NULL) {
errno = EBADF;
return -1;
}
if (_sys_ab(0x4500,_iob[fd]->file.handle,&handle) != 0) {
errno = _doserrno;
return -1;
}
if (_iob[handle] != NULL) {
errno = EMFILE;
return -1;
}
_iob[handle] = _iob[fd];
_dupcnt_++;
return handle;
} /* dup */
int dup2(fd1, fd2)
int fd1, fd2;
{ /* duplicate a file descriptor - both descriptors use the
same file pointer. */
extern int errno, _doserrno;
extern int _dupcnt_;
int handle;
if (fd1 < 0 || fd1 > MAXFILES || _iob[fd1] == NULL ||
fd2 < 0 || fd2 > MAXFILES) {
errno = EBADF;
return -1;
}
if (_iob[fd2] != NULL) {
if (close(fd2) != 0) { errno = EBADF; return -1; }
}
if (_sysabcd(0x4600,fd1,fd2,0,&handle) != 0) {
errno = _doserrno;
return -1;
}
_iob[fd2] = _iob[fd1];
_dupcnt_++;
return 0;
} /* dup2 */

328
Mix Power C v1/DYSTRING.C Normal file
View File

@ -0,0 +1,328 @@
#define NULL 0
#define st_alloc(size) malloc((size)+2)
#if !defined(STRING)
typedef struct {
int length;
char string[80];
} STRING;
#endif
enum COMPVALUE {LESS, EQUAL, GREATER};
STRING *bldstr(s,len)
char *s;
int len;
{
STRING *ss;
ss = st_alloc(len);
if (ss != NULL) {
ss->length = len;
memcpy(ss->string,s,len);
}
return ss;
}
void getstr(str, arr, len)
STRING *str;
char *arr;
int len;
{
int size;
if (str == NULL) memset(arr,' ',len);
else {
if (str->length > len) size = len; else size = str->length;
memcpy(arr,str->string,size);
if (size < len) memset(&arr[size],' ',len-size);
}
}
int len(str)
STRING *str;
{
return str->length;
}
STRING *left$(str, position)
STRING *str;
int position;
{
int size;
STRING *s;
if ((str == NULL) || (position < 0)) size = 0;
else {
if (position < str->length) size = position;
else size = str->length;
}
s = st_alloc(size);
if (s != NULL) {
s->length = size;
memcpy(s->string,str->string,size);
}
return s;
}
STRING *right$(str, position)
STRING *str;
int position;
{
int size;
STRING *s;
if (str == NULL) size = 0;
else {
if (position <= 0 || position > str->length) size = 0;
else size = str->length-position+1;
}
s = st_alloc(size);
if (s != NULL) {
s->length = size;
memcpy(s->string,&str->string[position-1],size);
}
return s;
}
STRING *mid$(str, position, length)
STRING *str;
int position;
int length;
{
int size;
STRING *s;
if (str == NULL) size = 0;
else {
if (position <= 0) size = str->length;
else if (position > str->length) size = 0;
else size = str->length - position + 1;
}
if (length < size) size = length;
s = st_alloc(size);
if (s != NULL) {
s->length = size;
memcpy(s->string,&str->string[position-1],size);
}
return s;
}
STRING *str$(length, ch)
int length;
int ch;
{
STRING *s;
s = st_alloc(length);
if (s != NULL) {
s->length = length;
memset(s->string,ch,length);
}
return s;
}
char character(s, position)
STRING *s;
int position;
{
if (s == NULL) return '\r';
if ((s->length <= 0) || (position <= 0) || (position > s->length))
return '\r';
return s->string[position-1];
}
enum COMPVALUE cmpstr(s1, s2)
STRING *s1;
STRING *s2;
{
int len;
int cmp;
if (s1 == s2) return EQUAL;
if (s1 == NULL) return LESS;
if (s2 == NULL) return GREATER;
len = s1->length;
if (s2->length < len) len = s2->length;
cmp = memcmp(s1->string,s2->string,len);
if (cmp < 0) return LESS;
if (cmp > 0) return GREATER;
if (s1->length > s2->length) return GREATER;
if (s1->length < s2->length) return LESS;
return EQUAL;
}
STRING *conc(s1,s2)
STRING *s1;
STRING *s2;
{
STRING *s;
int size1, size2;
if (s1 == NULL) size1 = 0; else size1 = s1->length;
if (s2 == NULL) size2 = 0; else size2 = s2->length;
s = st_alloc(size1+size2);
if (s != NULL) {
s->length = size1+size2;
if (size1) memcpy(s->string,s1->string,size1);
if (size2) memcpy(&s->string[size1],s2->string,size2);
}
return s;
}
STRING *insert(substring, s, position)
STRING *substring;
STRING *s;
int position;
{
STRING *st;
int size1, size2, pos;
if (s == NULL) size1 = 0; else size1 = s->length;
if (substring == NULL) size2 = 0; else size2 = substring->length;
pos = position;
if (pos <= 0) pos = 1;
if (pos > size1) pos = size1+1;
st = st_alloc(size1+size2);
if (st != NULL) {
st->length = size1+size2;
memcpy(st->string,s->string,pos-1);
memcpy(&st->string[pos-1],substring->string,size2);
memcpy(&st->string[pos-1+size2],&s->string[pos-1],size1+1-pos);
}
return st;
}
STRING *delete(str, position, length)
STRING *str;
int position;
int length;
{
STRING *st;
int size;
int pos = position;
if (pos <= 0) {
length = length-pos-1;
pos = 1;
}
if (length < 0) length = 0;
if (str == NULL) size = 0;
else {
if (pos > str->length) size = str->length;
else if (pos+length > str->length) size = pos-1;
else size = str->length-length;
}
st = st_alloc(size);
if (st != NULL) {
st->length = size;
if (pos) memcpy(st->string,str->string,pos-1);
if (size+1-pos)
memcpy(&st->string[pos-1],&str->string[length+pos-1],size+1-pos);
}
return st;
}
STRING *replace(oldstring, newstring, s)
STRING *oldstring;
STRING *newstring;
STRING *s;
{
STRING *st;
int loc, size;
int oldsz, newsz;
loc = find(oldstring,s);
if (loc == 0) return cpystr(s);
oldsz = oldstring->length;
newsz = newstring->length;
size = s->length+newsz-oldsz;
st = st_alloc(size);
if (st != NULL) {
st->length = size;
memcpy(st->string,s->string,loc-1);
memcpy(&st->string[loc-1],newstring->string,newsz);
memcpy(&st->string[loc-1+newsz],&s->string[loc-1+oldsz],size-newsz-loc+1);
}
}
int find(substring, s)
STRING *substring;
STRING *s;
{
int limit, at, size;
if (s == NULL) return 0;
if (substring == NULL) return (s->length > 0) ? 1 : 0;
if (s->length == 0) return 0;
if (substring->length == 0) return 1;
limit = s->length - substring->length;
at = 0;
size = substring->length;
while (at <= limit) {
if (memcmp(&s->string[at],substring->string,size) == 0)
return at+1;
++at;
}
return 0;
}
STRING *cpystr(str)
STRING *str;
{
STRING *s;
int size;
if (str == NULL) size = 0; else size = str->length;
s = st_alloc(size);
if (s != NULL) {
s->length = size;
memcpy(s->string,str->string,size);
}
return s;
}
int decodei(str)
STRING *str;
{
int sflag = 1, value = 0;
int len;
char c, *p;
if (str == NULL) return 0;
len = str->length;
p = str->string;
while (isspace(*p) && len != 0) ++p, --len;
if (len == 0) return 0;
if (*p == '+' || *p == '-') {
if (*p == '-') sflag = -1;
++p;
--len;
}
while (len--) {
if (*p > 47 && *p < 58) value = 10*value+(*p++ - 48);
else len = 0;
}
return value * sflag;
}
STRING *encodei(value)
int value;
{
STRING *st;
char *p;
char sign = ' ';
int i;
st = st_alloc(6);
if (st == NULL) return NULL;
st->length = 6;
if (value < 0) {
if (value == -32768) {
memcpy(st->string,"-32768",6);
return st;
}
sign = '-';
value = -value;
}
p = &st->string[5];
*p = (value % 10) + 48;
value /= 10;
for (i = 0; i < 5; ++i) {
if (value == 0) {
*--p = sign;
sign = ' ';
}
else {
*--p = (value % 10) + 48;
value /= 10;
}
}
return st;
}

30
Mix Power C v1/E.C Normal file
View File

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

147
Mix Power C v1/ENVIR.ASM Normal file
View File

@ -0,0 +1,147 @@
;
; Copyright (c) Mix Software 1988
;
IF 0
;
; getenv - return a pointer to an entry in the environment
;
; char *getenv(varname)
;
; varname is the name of the variable (eg "PATH=")
;
IDT GETENV
DEF GETENV
DEF getenv
DREF environ
FREF _moveenv
;
getenv EQU $
GETENV PUSH BP
MOV BP,SP
CMP [environ],0
JNZ INITDONE
CALLFAR _moveenv
JZ NOFIND
INITDONE MOV BX,environ
MOV CX,-1
MOV AX,DS
MOV ES,AX
CLD
SRCH MOV DI,[BX]
ADD BX,%2
TEST DI,DI ; End of table?
JZ NOFIND
MOV SI,[BP][%PARM1]
MOV CX,>7FFF
REPZ ; Compare values
CMPSB
TEST %[SI][%-1],%>FF ; Equal to end of string mark?
JNZ SRCH
DEC DI
MOV AX,DI
POP BP
RETSEG
NOFIND XOR AX,AX
POP BP
RETSEG
END
;
ENDIF
;
;
; _moveenv - copy environment to the data segment
; $$ENVIR has the segment pointer to the environment
; environ is created to hold an array of pointers to the
; environment strings.
;
IDT _moveenv
DEF _moveenv
DREF environ
DREF $$ENVIR
DREF $$ENVPX
FREF malloc
PEXTRA EQU 4 ; Number of extra pointer slots
;
_moveenv XOR DX,DX ; Counter for number of strings
MOV ES,[$$ENVIR]
XOR DI,DI
MOV AL,%0
MOV CX,-1
CLD
FINDLEN INC DX ; Count this string
SEGES
CMP %[DI],%0 ; end of table?
JZ ENDENV
REPNZ
SCASB
JMPS FINDLEN
ENDENV NOT CX ; CX is size of the environment
INC CX ; Make size even
AND CX,>FFFE
PUSH DX ; Save number of pointers
PUSH CX
CALLFAR malloc
POP CX
POP DX
TEST AX,AX
JZ NOSPACE
MOV DI,AX
PUSH DI
MOV AX,DS
MOV ES,AX
MOV DS,[$$ENVIR]
SHR CX,1
XOR SI,SI
REP ; Copy environment to heap
MOVSW
MOV AX,ES
MOV DS,AX
MOV CX,DX
ADD CX,CX ; Memory required for array of pointers
ADD CX,PEXTRA*2 ; Space for extra pointers
PUSH DX
PUSH CX
CALLFAR malloc
POP CX
POP DX
POP DI ; Address of environment block
TEST AX,AX
JZ NOSPACE
MOV BX,AX ; Address of pointer array
MOV [environ],AX
MOV AX,DS
MOV ES,AX
MOV CX,-1
MOV AL,%0
COPYPTR DEC DX
JZ DONE
MOV [BX],DI
ADD BX,%2
REPNZ
SCASB
JMPS COPYPTR
DONE MOV CX,PEXTRA+1
FILL MOV [BX],0
ADD BX,%2
LOOP FILL
MOV [$$ENVPX],PEXTRA
MOV AX,[environ]
RETSEG
NOSPACE XOR AX,AX
RETSEG
END
;
; char *(*environ)[];
; int $$ENVPX;
; int $$ENVALT = 0;
;
IDT environ
DDEF environ
DDEF $$ENVPX
DDEF $$ENVALT
DORG 0
environ dw 0
$$ENVPX dw 0
$$ENVALT dw 0
END
;

130
Mix Power C v1/ENVIR.C Normal file
View File

@ -0,0 +1,130 @@
/* Environment functions */
/* Copyright (c) Mix Software 1988 */
char *getenvp(varname) /* get a copy of an environment variable */
char *varname;
{
char *getenv();
char *strsave();
char *s;
s = getenv(varname);
if (s == NULL) return NULL;
return strsave(s);
} /* getenvp */
/* ------------------------------------------------------------ */
char *getenv(varname)
char *varname;
{
extern char *(*environ)[];
char *_moveenv();
int strlen(), memcmp();
char **p;
int len;
if (environ == NULL) {
if (_moveenv() == NULL) return NULL;
}
len = strlen(varname);
if (*(varname+len-1) == '=') len--;
p = *environ;
while (*p != 0) {
if (memcmp(*p,varname,len) == 0) {
if (*((*p)+len) == '=') return (*p+len+1);
}
++p;
}
return NULL;
} /* getenv */
/* ------------------------------------------------------------ */
int *putenv(envstring)
char *envstring;
{
extern char **environ;
extern int $$ENVPX, $$ENVALT;
char *_moveenv(), *strchr(), *malloc();
int strlen(), memcmp();
char **p, **q;
char *sp;
int len;
if (environ == NULL) {
if (_moveenv() == NULL) return NULL;
}
if ((sp = strchr(envstring,'=')) == NULL) return -1;
sp++; /* pass the '=' */
$$ENVALT = 1;
len = sp - envstring;
p = environ;
while (*p != 0) {
if (memcmp(*p,envstring,len) == 0) break;
++p;
}
if (*p != 0) { /* replace existing string */
if (len == strlen(envstring)) { /* value is null, delete from table */
q = p+1;
while (*p != NULL) *p++ = *q++;
++$$ENVPX;
}
else *p = envstring;
return 0;
}
if ($$ENVPX == 0) { /* no slot available in table */
len = (p - environ);
q = malloc(sizeof(char *)*(len + 5));
if (q == NULL) return -1;
memcpy(q,environ,sizeof(char *)*len);
memset((q + len),0,5*sizeof(char *));
free(environ);
environ = q;
$$ENVPX = 4;
p = q+len;
}
*p = envstring;
--$$ENVPX;
return 0;
} /* putenv */
/* ------------------------------------------------------------ */
unsigned _copyenv(envp)
char **envp;
{ /* copy environment into a single block of memory on a paragraph
boundary. Returns a segment pointer to the block. If the
environment has not been altered, the environment pointer from
the parent is returned.
*/
extern char *(*environ)[];
extern unsigned $$ENVIR;
extern int $$ENVALT;
unsigned getdseg();
char **p, *q, **ev;
unsigned paragraph;
int len = 0;
if (envp == NULL) {
if (environ == NULL) return $$ENVIR;
if ($$ENVALT == 0) return $$ENVIR;
ev = environ;
}
else ev = envp;
p = ev;
while (*p != NULL) {
len += strlen(*p)+1;
++p;
}
q = malloc(len+16);
if (q == NULL) return NULL;
q = ((unsigned)q + 15) & 0xfff0; /* paragraph boundary */
paragraph = ((unsigned)q >> 4) + getdseg();
p = ev;
while (*p != NULL) {
strcpy(q,*p);
q += strlen(*p)+1;
++p;
}
return paragraph;
} /* _copyenv */

53
Mix Power C v1/ERROR.C Normal file
View File

@ -0,0 +1,53 @@
/* Low level error processing functions. */
/* Copyright (c) Mix Software 1988 */
extern int _ferror0();
int (*_fileerr)() = _ferror0; /* set to _ferror1 for full error msg */
int _ferror0(syserror,fp) /* error detected during file operation */
int syserror; /* set error codes and terminate or */
FILE *fp; /* continue (depending on $$IOTERM) */
{
extern char $$IOTERM;
extern FILE *$$LIOERR;
extern int errno;
void $_FATAL();
if (syserror) {
fp->file.error = syserror;
errno = FILEERR;
$$LIOERR = fp;
if ($$IOTERM) $_FATAL(errno);
}
return syserror;
}
int _ferror1(syserror,fp) /* error detected during file operation */
int syserror; /* set error codes and terminate with */
FILE *fp; /* full message. */
{
extern int errno;
extern char $$IOTERM;
extern FILE *$$LIOERR;
extern char *sys_errlist[];
extern int sys_nerr;
void _exit();
if (syserror) {
fp->file.error = syserror;
errno = FILEERR;
$$LIOERR = fp;
if ($$IOTERM) {
_errmsg("File IO error\r\l");
if (syserror <= sys_nerr) _errmsg(sys_errlist[syserror]);
_exit(errno);
}
}
return syserror;
}
_errmsg(s)
char *s;
{
int ss;
_sysabcd(0x4000,2,strlen(s),s,&ss);
}

4
Mix Power C v1/ERRORS.C Normal file
View File

@ -0,0 +1,4 @@
/* Copyright (c) Mix Software 1988 */
#include "std_lib.h"
#include "error.c"

128
Mix Power C v1/ETC.C Normal file
View File

@ -0,0 +1,128 @@
/* Copyright (c) Mix Software 1988 */
void ctrlbrk(fptr)
int (*fptr)();
{
_signal_(SIGINT,fptr);
}
void fnmerge(path, drive, dir, name, ext)
char *path; /* buffer to constuct file name */
char *drive; /* disk drive name */
char *dir; /* directory name */
char *name; /* file name */
char *ext; /* file extension */
{
if (drive != NULL) strcpy(path,drive);
else *path = '\0';
if (dir != NULL) strcat(path,dir);
if (name != NULL) strcat(path,name);
if (ext != NULL) strcat(path,ext);
}
/* flags for fnsplit */
#define WILDCARDS 0x0001
#define EXTENSION 0x0002
#define FILENAME 0x0004
#define DIRECTORY 0x0008
#define DRIVE 0x0010
void fnsplit(path, drive, dir, name, ext)
char *path; /* buffer containing file name */
char *drive; /* disk drive name (with ':') */
char *dir; /* directory name (with '\') */
char *name; /* file name */
char *ext; /* file extension (with '.') */
{
char *p, *q;
int result = 0;
p = strchr(path,':');
if (p != NULL) {
if (drive != NULL) memcpy(drive,path,(++p)-path);
result += DRIVE;
}
else p = path;
if (drive != NULL) *(drive+(p-path)) = '\0';
q = strrchr(path,'\\');
if (q != NULL) {
if (dir != NULL) {
memcpy(dir,p,q-p+1);
*(dir+(q-p)+1) = '\0';
}
p = q+1;
result += DIRECTORY;
}
else if (dir != NULL) *dir = '\0';
q = strchr(p,'.');
if (q != NULL) {
if (ext != NULL) strcpy(ext,q);
if (name != NULL) {
memcpy(name,p,q-p);
*(name+(q-p)) = '\0';
if (p != q) result += FILENAME;
}
result += EXTENSION;
}
else {
if (ext != NULL) *ext = '\0';
if (name != NULL) strcpy(name,p);
if (*p != '\0') result += FILENAME;
}
if (strchr(path,'*')) result += WILDCARD;
else if (strchr(path,'?')) result += WILDCARD;
return result;
}
char *getpass(prompt)
char *prompt;
{
static char password[9];
int count = 0;
int c;
while (*prompt != '\0') putch(*prompt++);
do {
c = getch();
if (c == '\b') {
if (count > 0) --count;
}
else if (!iscntrl(c)) password[count++] = c;
} while ((c != '\r') && (c != '\l') && (count < 8));
password[count] = '\0';
return &password;
}
char *searchpath(filename)
char *filename; /* name of file */
{
void _searchenv();
static char fname[80];
_searchenv(filename,"PATH=",fname);
if (fname[0] != '\0') return fname; else return NULL;
} /* searchpath */
void _searchenv(name, env_var, path)
char *name; /* name to search for */
char *env_var; /* name of environment variable */
char *path; /* buffer to hold result */
{
char *getenv();
char *envptr, *p;
int status;
strcpy(path,name);
/* check default directory */
if (_sys_acd(0x4300,0,path,&status) == 0) return;
envptr = getenv(env_var);
if (envptr == NULL) {*path = '\0'; return; }
do { /* try all directorys in envptr */
p = path;
while ((*envptr != ';') && (*envptr != '\0')) *p++ = *envptr++;
if (*envptr == ';') ++envptr;
if (p != path) if (*(p-1) != '\\') *p++ = '\\';
*p = '\0';
strcat(p,name);
if (_sys_acd(0x4300,0,path,&status) == 0) return;
} while (*envptr != '\0');
*path = '\0';
return; /* not found */
} /* searchenv */

692
Mix Power C v1/EXEC.ASM Normal file
View File

@ -0,0 +1,692 @@
;
; Copyright (c) Mix Software 1988
;
;
; Call a program & return to caller
;
; _spawn(progpath,command,envp);
;
; progpath is the address of the program's path name
; command is the command line to pass
; envp is the pointer to the environment
;
IDT _SPAWN
DEF _SPAWN
DEF _spawn
DREF $$PSP
DREF $$TOPSEG
FREF _FMAX
;PARM1 EQU 6
;PARM2 EQU PARM1+2
;PARM3 EQU PARM2+2
;
_spawn equ $
_SPAWN PUSH BP
MOV BP,SP
CALLFAR _FMAX ; find top of usable memory
MOV BX,AX
SUB BX,[$$PSP] ; Size in use
MOV ES,[$$PSP] ; Shrink memory
MOV AX,>4A00
INT >21
MOV AX,DS
MOV ES,AX
MOV DI,EXEBLK
MOV AX,[BP][%PARM3]
STOSW
MOV AX,[BP][%PARM2]
STOSW
MOV AX,DS
STOSW
MOV AX,>5C
STOSW
MOV AX,[$$PSP]
STOSW
MOV AX,>6C
STOSW
MOV AX,[$$PSP]
STOSW
PUSH DS
MOV AX,SS
SEGCS
MOV [SAVESS],AX
MOV AX,SP
SEGCS
MOV [SAVESP],AX
MOV BX,EXEBLK
MOV DX,[BP][%PARM1]
MOV AX,>4B00
INT >21
SEGCS
MOV CX,[SAVESS]
SEGCS
MOV DX,[SAVESP]
MOV SS,CX
MOV SP,DX
POP CX
MOV DS,CX
POP BP
JB EXIT
XOR AX,AX
EXIT PUSH AX
MOV ES,[$$PSP] ; Restore memory to original size
SEGES
MOV BX,[$$TOPSEG]
SUB BX,[$$PSP] ; original size
MOV AX,>4A00
INT >21
POP AX
RETSEG
SAVESS DW 0-0
SAVESP DW 0-0
;
DORG 0
EXEBLK DW 0 ; Segment of environment
DW >80 ; Command tail
DW 0 ; Command tail segment
DW >5C ; First FCB
DW 0 ; FCB segment
DW >6C ; Second FCB
DW 0 ; FCB segment
END
;
; included if _p_overlay is used
;
IDT _p_chn1
DDEF _p_chain
DDEF _p_chenv
LDDEF _p_overlay
REF _chain
REF _chainev
DORG 0
_p_overlay DW 2
_p_chain DW _chain
_p_chenv DW _chainev
END
;
; included if _p_overlay is not used
;
IDT _p_chain
DDEF _p_chain
DDEF _p_chenv
DORG 0
_p_chain DW 0
_p_chenv DW 0
END
;
; Chain routines for C compiler
;
; _chain(handle,cmdline);
;
; handle is the file handle of the .com or .exe file
; cmdline is the command line to pass to the program
;
IDT _CHAIN
DEF _CHAIN
DEF _chain
FREF _EXELDR
DREF $$PSP
DREF $$ENVIR
;PARM1 EQU 6
;PARM2 EQU PARM1+2
;PARM3 EQU PARM2+2
;PARM4 EQU PARM3+2
_chain equ $
_CHAIN PUSH BP
MOV BP,SP
MOV ES,[$$PSP]
CMP [BP][%PARM2],0
JZ NOCMD
MOV SI,[BP][%PARM2]
MOV DI,>80
MOV CX,128/2
CLD
REP
MOVSW
MOV DI,>100
JMPS LOAD
NOCMD SEGES
MOV [>80],>0D00
LOAD MOV DI,>0010
ADD DI,[$$PSP]
MOV BX,[BP][%PARM1]
MOV ES,[$$PSP]
CALLFAR _EXELDR
EXIT MOV AX,-1
POP BP
RETSEG
END
;
; Chain routines for C compiler
;
; _chainev(handle,cmdline,envir);
;
; handle is the file handle of the .com or .exe file
; cmdline is the command line to pass to the program
; envir is the segment address of the environment
;
IDT _CHAINEV
DEF _CHAINEV
DEF _chainev
FREF _EXELDR
DREF $$PSP
DREF $$ENVIR
;PARM1 EQU 6
;PARM2 EQU PARM1+2
;PARM3 EQU PARM2+2
;PARM4 EQU PARM3+2
FCBSIZE EQU 38
_chainev equ $
_CHAINEV PUSH BP
MOV BP,SP
MOV ES,[$$PSP]
CMP [BP][%PARM2],0
JZ NOCMD
MOV SI,[BP][%PARM2]
MOV CX,128/2
MOV DI,>80
CLD
REP
MOVSW
MOV DI,>100
JMPS ENVIR
NOCMD SEGES
MOV [>80],>0D00
ENVIR MOV SI,[BP][%PARM3]
TEST SI,SI
JZ NOENVIR
CMP SI,[$$ENVIR]
JZ NOENVIR
MOV ES,SI
XOR DI,DI
MOV AL,%0
MOV CX,-1
CLD
FINDLEN SEGES
CMP %[DI],%0 ; end of table?
JZ ENDENV
REPNZ
SCASB
JMPS FINDLEN
ENDENV NOT CX ; CX is size of the environment
ADD CX,%2 ; Terminating zero & round up
AND CX,>FFFE ; Make size even
SHR CX,1 ; Size in words
MOV ES,[$$PSP]
MOV DS,[BP][%PARM3]
XOR SI,SI
MOV DI,>100+XBLKSIZE+XCODESZ
ADD DI,15
AND DI,>FFF0
PUSH DI ; Environment origin
REP
MOVSW
MOV AX,SS
MOV DS,AX
POP DX
MOV CL,4
SHR DX,CL
ADD DX,[$$PSP]
JMPS LOAD
NOENVIR MOV DX,[$$ENVIR]
MOV DI,>100+XBLKSIZE+XCODESZ
LOAD PUSH DI
PUSH DX
MOV DS,[$$PSP]
MOV ES,[$$PSP]
MOV DI,>5C ; Parse default fcb
MOV SI,>81
MOV AX,>2900
INT >21
SUB SP,FCBSIZE ; Parse 2nd fcb
MOV DI,SP ; use stack for buffer
MOV AX,SS
MOV ES,AX
MOV AX,>2900
INT >21
MOV AX,SS
MOV DS,AX
MOV SI,SP
MOV DI,>6C ; Copy 2nd fcb
MOV ES,[$$PSP]
MOV CX,>80->6C
REP
MOVSB
ADD SP,%FCBSIZE
;
MOV SI,XCODE ; Code to shrink memory & exe
MOV DI,>100
MOV AX,CS
MOV DS,AX
MOV CX,XCODESZ+XBLKSIZE
REP
MOVSB
SEGES ; Set segments in parameter block
MOV [>100+CMDSEG],ES
SEGES
MOV [>100+FCB1SEG],ES
SEGES
MOV [>100+FCB2SEG],ES
POP DX
SEGES
MOV [>100+ENVSEG],DX
POP DI ; End of retained memory
ADD DI,>000F ; round to segment for release
MOV CL,4
SHR DI,CL
MOV BX,DI
PUSH ES
MOV AX,XCODE1-XCODE+>100
PUSH AX
MOV AX,>4A00
RETSEG
;
XCODE DW 0 ; Segment of environment
DW >80 ; Command tail
DW 0 ; Command tail segment
DW >5C ; First FCB
DW 0 ; FCB segment
DW >6C ; Second FCB
DW 0 ; FCB segment
XBLKSIZE EQU $-XCODE
ENVSEG EQU >0
CMDSEG EQU >4
FCB1SEG EQU >8
FCB2SEG EQU >C
;
;
; Address independent code to shrink memory and
; execute the program.
;
; BX = size of memory block
;
XCODE0 EQU $
ERR MOV DX,ERRMSG
MOV AX,CS
MOV DS,AX
MOV AH,>09
INT >21
MOV AX,>4C01
INT >21
ERRMSG DB >0D,>0A,'Load error',>0D,>0A,'$'
XCODE1 INT >21
JB ERR
MOV DX,[BP][%PARM1] ; File name
MOV AX,SS
MOV DS,AX
MOV AX,CS
MOV ES,AX
MOV BX,>100
MOV AX,>4B00
INT >21 ; Load and execute program
XCODE2 JB ERR ; Unable to load
MOV AX,CS
MOV SS,AX
MOV SP,XCODE2-XCODE+>100
MOV AX,>4D00 ; Get return code
INT >21
MOV AH,>4C
INT >21 ; Back to DOS
XCODESZ EQU $-XCODE0
END
;
; exe and com file loader
;
; BX = file handle for the file
; DI = segment address for load
; ES = segment address of psp
;
HDRSIZE EQU >1A
FCBSIZE EQU 38
BUFSZ EQU 512
HANDLE EQU 0
PSP EQU 2
ORG EQU 4
LOADORG EQU 6
STACKRES EQU HDRSIZE+8
EXESIG EQU 8
EXELENM EQU EXESIG+>2 ; Size of file mod 512
EXELEN EQU EXESIG+>4 ; Size of file div 512
EXERELCT EQU EXESIG+>6 ; Count of relocation items
EXEHDRSZ EQU EXESIG+>8 ; Size of header in paragraphs
EXEMIN EQU EXESIG+>A ; Minimum paragraphs needed
EXEMAX EQU EXESIG+>C ; Maximum paragraphs desired
EXESS EQU EXESIG+>E ; Stack segment
EXESP EQU EXESIG+>10 ; Stack pointer
EXECKSUM EQU EXESIG+>12 ; Word checksum
EXEIP EQU EXESIG+>14 ; Starting ip value
EXECS EQU EXESIG+>16 ; Starting code segment
EXEREL EQU EXESIG+>18 ; Offset of first relocation item
;
IDT _EXELDR
DEF _EXELDR
_EXELDR PUSH BP
SUB SP,STACKRES
MOV BP,SP
MOV [BP][%HANDLE],BX
MOV [BP][%ORG],DI
MOV [BP][%PSP],ES
MOV AX,ES
MOV DS,AX
MOV DI,>5C ; Parse default fcb
MOV SI,>81
MOV AX,>2900
INT >21
SUB SP,FCBSIZE ; Parse 2nd fcb
MOV DI,SP ; use stack for buffer
MOV AX,SS
MOV ES,AX
MOV AX,>2900
INT >21
MOV AX,SS
MOV DS,AX
MOV SI,SP
MOV DI,>6C ; Copy 2nd fcb
MOV ES,[BP][%PSP]
MOV CX,>80->6C
REP
MOVSB
ADD SP,%FCBSIZE
MOV CX,HDRSIZE
LEA DX,[BP][%EXESIG]
MOV AX,>3F00
INT >21 ; Read initial header
CMP [BP][%EXESIG],>5A4D ; test for .exe signature
JZ LOADEXE
;
; Load .com file
;
LOADCOM MOV DI,[BP][%ORG] ; Load address
SUB DI,>10
CMP DI,[BP][%PSP]
JNZ LDERR ; com file must load at >100
MOV AX,CS
MOV DS,AX ; Copy header for .COM file
MOV SI,COMEXE
MOV AX,SS
MOV ES,AX
LEA DI,[BP][%EXELENM]
MOV CX,(EXECS-EXELENM)/2
REP
MOVSW
MOV AX,[BP][%PSP]
MOV [BP][%EXESS],AX
MOV [BP][%EXECS],AX
JMPS LOADEXE
; ; mock exe header for .com files
COMEXE DW >100 ; size mod 512
DW >80 ; size in blocks
DW 0 ; relocation count
DW 0 ; header size
DW 1 ; min paragraphs
DW -1 ; max paragraphs
DW 0-0 ; stack segment
DW >FFFE ; stack pointer
DW 0 ; checksum
DW >100 ; instruction pointer
LDERR MOV AX,-1
LDEXIT LEA SP,[BP][%STACKRES]
POP BP
RETSEG
MEMERR MOV AX,-2
JMPS LDEXIT
;
; .exe file loader
; SS:BP points to the parameters
;
LOADEXE MOV DX,[BP][%EXELEN] ; Length of file
MOV AX,[BP][%EXELENM]
CMP AX,0 ; Full page?
JZ FULLPAGE
DEC DX
FULLPAGE MOV CL,5
SHL DX,CL ; Convert to paragraphs
DEC CL
SHR AX,CL
ADD DX,AX ; DX = size in paragraphs
SUB DX,[BP][%EXEHDRSZ] ; - size of header
AND [BP][%EXELENM],>000F ; fraction
JZ EVEN01
INC DX
EVEN01 MOV [BP][%EXELEN],DX ; code size in paragraphs
MOV ES,[BP][%PSP]
MOV BX,[BP][%EXEMAX]
CMP BX,LOADSZP ; minimum needed for loader
JAE USEMAX
MOV BX,LOADSZP
USEMAX ADD BX,DX
JNB SETMEM
MOV BX,-1
SETMEM MOV AH,>4A ; set memory size
PUSH BX
INT >21
JB TRYMAX
POP BX
JMPS MEMSET
TRYMAX POP AX
MOV AH,>4A ; Get maximum available
PUSH BX
INT >21
POP BX
JB HAVEMEM ; Try what we already have
MEMSET ADD BX,[BP][%PSP]
SEGES
MOV [2],BX
HAVEMEM MOV AX,[BP][%EXELEN]
ADD AX,[BP][%ORG]
MOV [BP][%LOADORG],AX ; Segment address for loader
MOV DX,[BP][%EXEMIN] ; Minimum memory above code
CMP DX,LOADSZP
JAE USEMIN
MOV DX,LOADSZP
USEMIN ADD AX,DX ; Minimum memory to load
SEGES
CMP AX,[2]
JA MEMERR ; Not enough memory
;
; Move the loader code and branch to it
; Copies the control point and argument block to the
; program's target address before moving the loader. This
; protects against the loader's target conflicting with
; the stack space or code space for the executing program.
;
; SS:BP = location of argument block
;
;
MOVEGO MOV SI,FINAL ; Final move instructions
MOV ES,[BP][%ORG]
XOR DI,DI
MOV AX,CS
MOV DS,AX
MOV CX,EFINAL-FINAL
CLD
REP
MOVSB
MOV SI,BP ; Data block
MOV BP,DI
MOV AX,SS
MOV DS,AX
MOV CX,STACKRES
REP
MOVSB
ADD DI,>100 ; Temporary stack space for
MOV DX,ES ; move routine
MOV SS,DX
MOV SP,DI ; Relocate stack
PUSH [BP][%LOADORG] ; Address of final target
XOR AX,AX
PUSH AX
PUSH DX ; Return to move routine
PUSH AX
MOV DX,CS
MOV DS,DX
MOV SI,EXELOAD
MOV CX,LOADRSZ
MOV DX,DI
REP ; Move loader to low memory
MOVSB
MOV SI,DX
MOV AX,ES
MOV DS,AX
MOV ES,[BP][%LOADORG]
XOR DI,DI
MOV CX,LOADRSZ
RETSEG ; Branch & move loader high
FINAL REP
MOVSB ; Move loader above program
RETSEG ; Transfer to loader
EFINAL EQU $
;
;
; Relocatable .EXE file loader
; BP points to argument block
;
EXELOAD MOV AX,SS ; Copy stack to local storage
MOV DS,AX
MOV SI,BP
MOV AX,CS
MOV ES,AX
MOV DI,EXESTK-EXELOAD
MOV BP,DI
MOV CX,STACKRES
CLD
REP
MOVSB
MOV DX,EXESTK+256
MOV SS,AX
MOV SP,DX
MOV BX,[BP][%HANDLE]
MOV DS,[BP][%PSP]
MOV DX,[BP][%EXEHDRSZ] ; Seek file past header
XOR AX,AX
MOV CX,4
HDRSZ SHL DX,1
RCL AX,1
LOOP HDRSZ
MOV CX,AX
MOV BX,[BP][%HANDLE]
MOV AX,>4200
INT >21 ; Seek to beginning of file
JB EXEERR1
MOV DS,[BP][%ORG]
READEXE MOV CX,[BP][%EXELEN]
JCXZ DONEREAD
CMP CX,>7FF
JBE ONEREAD
MOV CX,>7FF0
SUB [BP][%EXELEN],>7FF
JMPS READ1
ONEREAD CMP [BP][%EXELENM],0
JZ EVEN02
DEC CX
EVEN02 MOV AX,CX
MOV CL,4
SHL AX,CL
ADD AX,[BP][%EXELENM]
MOV CX,AX
MOV [BP][%EXELEN],0
READ1 MOV AX,>3F00
XOR DX,DX
INT >21
JB EXEERR1
CMP AX,CX
JNZ EXEEND
MOV AX,DS
ADD AX,>7FF
MOV DS,AX
JMPS READEXE
EXEEND CMP [BP][%EXESIG],>5A4D
JNZ EXEERR1 ; EXE file too short
GOCOM1 JMP GOCOM ; .COM file
EXEERR1 JMP EXEERR
;
; Seek to relocation table
; Read relocation data into buffer & apply
;
DONEREAD CMP [BP][%EXESIG],>5A4D
JNZ GOCOM1
CMP [BP][%EXERELCT],0
JZ GOEXE
MOV DX,[BP][%EXEREL]
XOR CX,CX ; Seek to relocation table
MOV BX,[BP][%HANDLE]
MOV AX,>4200
INT >21
JB EXEERR1
READTBL MOV CX,[BP][%EXERELCT]
JCXZ GOEXE ; End of relocation table
CMP CX,BUFSZ/4
JBE ONEBLOCK
MOV CX,BUFSZ/4
ONEBLOCK SUB [BP][%EXERELCT],CX
SHL CX,1
SHL CX,1
MOV BX,[BP][%HANDLE]
MOV AX,SS
MOV DS,AX
MOV AH,>3F
LEA DX,[BP][%EXEREL+2]
INT >21 ; Read a block of relocations
JB EXEERR1
CMP AX,CX
JNZ EXEERR
SHR CX,1
SHR CX,1
LEA SI,[BP][%EXEREL+2]
MOV DX,[BP][%ORG]
RELOC MOV DI,[SI] ; Apply relocations
MOV AX,[SI][%2]
ADD AX,DX
MOV ES,AX
SEGES
ADD [DI],DX
ADD SI,%4
LOOP RELOC
JMPS READTBL
;
; Load registers from header & transfer to program
;
GOEXE MOV BX,[BP][%HANDLE]
MOV AH,>3E
INT >21
MOV AX,[BP][%PSP]
MOV DS,AX
MOV ES,AX
MOV AX,[BP][%ORG]
MOV DX,AX
ADD AX,[BP][%EXESS]
ADD DX,[BP][%EXECS]
MOV BX,[BP][%EXESP]
MOV CX,[BP][%EXEIP]
MOV SS,AX
MOV SP,BX
PUSH DX
PUSH CX
RETSEG
;
GOCOM MOV BX,[BP][%HANDLE]
MOV AH,>3E
INT >21
MOV AX,[BP][%PSP]
MOV DS,AX
MOV ES,AX
MOV BX,>FFFE
MOV [BX],0
MOV SS,AX
MOV SP,BX
PUSH AX
MOV AX,>100
PUSH AX
RETSEG
;
;
EXEERR MOV DX,ERRMSG
MOV AH,>09
INT >21
MOV AX,>4C01
INT >21
ERRMSG DB >0D,>0A,'Load error',>0D,>0A,'$'
LOADRSZ EQU $-EXELOAD
LOADSZP EQU (LOADRSZ+BUFSZ+256)/16
EXESTK EQU $
END

72
Mix Power C v1/EXIT.C Normal file
View File

@ -0,0 +1,72 @@
/* Exit from program */
/* Copyright (c) Mix Software 1988 */
void abort()
{
raise(SIGABRT);
_errmsg("Abnormal program terminations\x0d\x0a");
_exit(3);
}
/* ------------------------------------------------------------ */
exit(status)
int status;
{
int i;
int _exit();
extern int (*_fclose)();
extern onexit_t _on_exit_tbl[32];
extern int _on_index;
while (_on_index--) (*(_on_exit_tbl[_on_index]))();
i = 0;
while (i < MAXFILES) {
if (_iob[i] != NULL) (*_fclose)(_iob[i]);
i++;
}
_exit(status);
}
/* ------------------------------------------------------------ */
onexit_t onexit(func)
onexit_t func;
{
extern int _on_index;
extern onexit_t _on_exit_tbl[32];
if (_on_index > 31) return NULL;
_on_exit_tbl[_on_index] = func;
_on_index++;
return func;
}
/* ------------------------------------------------------------ */
atexit_t atexit(func)
atexit_t func;
{
extern int _on_index;
extern onexit_t _on_exit_tbl[32];
if (_on_index > 31) return NULL;
_on_exit_tbl[_on_index] = func;
_on_index++;
return func;
}
/* ------------------------------------------------------------ */
_exit(status)
int status;
{
extern int $$EXSTAT;
extern void (*$$EXITPT)();
$$EXSTAT = status;
(*$$EXITPT)();
}
onexit_t _on_exit_tbl[32];
int _on_index = 0;

227
Mix Power C v1/FAR.ASM Normal file
View File

@ -0,0 +1,227 @@
;
; Copyright (c) Mix Software 1988
;
; --------------------------------------------------------
; FARSTI8 - Store an 8 byte value via far pointer
; --------------------------------------------------------
; STACK CONTAINS: value (8 bytes)
; DESTINATION (LONG)
;
IDT $_FARST8
DEF $_FARST8
$_FARST8 PUSH BP
MOV BP,SP
LEA SI,[BP][%PARM1]
MOV DI,[BP][%PARM1+8]
MOV ES,[BP][%PARM1+10]
MOV CX,4
REP
MOVSW
POP BP
RETSEG
END
;
; --------------------------------------------------------
; FARMOVE - MOVE A BLOCK OF MEMORY
; --------------------------------------------------------
; STACK CONTAINS: BYTE COUNT
; DESTINATION (LONG)
; SOURCE (LONG)
;
IDT $_FARMOV
DEF $_FARMOV
$_FARMOV PUSH BP
MOV BP,SP
MOV CX,[BP][%PARM1] ; GET COUNT
JCXZ SMOVEEX
MOV DI,[BP][%PARM2] ; DESTINATION
MOV ES,[BP][%PARM3]
MOV SI,[BP][%PARM4] ; GET SOURCE
MOV AX,[BP][%PARM5]
PUSH DS ; SAVE DATA SEGMENT
MOV DS,AX
REP
MOVSB
SMOVEEX POP AX
MOV DS,AX
POP BP
RETSEG
END
;
; --------------------------------------------------------
; FARMOVER - MOVE A BLOCK OF MEMORY
; --------------------------------------------------------
; STACK CONTAINS: BYTE COUNT
; SOURCE (LONG)
; DESTINATION (LONG)
;
IDT $_FARMVR
DEF $_FARMVR
$_FARMVR PUSH BP
MOV BP,SP
MOV CX,[BP][%PARM1] ; GET COUNT
JCXZ SMOVEEX
MOV SI,[BP][%PARM2] ; SOURCE
MOV AX,[BP][%PARM3]
PUSH DS ; SAVE DATA SEGMENT
MOV DS,AX
MOV DI,[BP][%PARM4] ; GET DESTINATION
MOV AX,[BP][%PARM5]
MOV ES,AX
REP
MOVSB
SMOVEEX POP AX
MOV DS,AX
POP BP
RETSEG
END
;
; --------------------------------------------------------
; FAR2LONG - CONVERT FAR ADDRESS TO LONG INTEGER
; --------------------------------------------------------
; STACK CONTAINS: FAR POINTER
;
IDT fartol
DEF fartol
IF UPPER
DEF FARTOL
ENDIF
fartol equ $
FARTOL MOV SI,SP
MOV BX,[SI][%PARM1-2] ; GET OFFSET
MOV DX,[SI][%PARM2-2] ; GET SEGMENT
MOV AX,DX
MOV CL,%12
SHR DX,CL
MOV CL,%4
SHL AX,CL
ADD AX,BX
ADC DX,%0
RETSEG
END
;
; --------------------------------------------------------
; LONG2FAR - CONVERT LONG INTEGER TO FAR ADDRESS
; --------------------------------------------------------
; STACK CONTAINS: FAR POINTER
;
IDT ltofar
DEF ltofar
IF UPPER
DEF LTOFAR
ENDIF
ltofar EQU $
LTOFAR MOV SI,SP
MOV BX,[SI][%PARM1-2] ; GET LOWER
MOV DX,[SI][%PARM2-2] ; GET UPPER
MOV CL,%12
SHL DX,CL
MOV AX,BX
MOV CL,%4
SHR BX,CL
ADD DX,BX
AND AX,>000F
RETSEG
END
;
; --------------------------------------------------------
; BITSET - SET A BIT FIELD
; --------------------------------------------------------
; STACK CONTAINS: SHIFT COUNT
; BIT MASK
; VALUE OF FIELD
; ADDRESS OF WORD CONTAINING FIELD
;
IDT $_BITSET
DEF $_BITSET
$_BITSET MOV SI,SP
MOV CX,[SI][%PARM1-2]
MOV DX,[SI][%PARM2-2]
MOV AX,[SI][%PARM3-2]
JCXZ NOSHIFT
SHL AX,CL
NOSHIFT AND AX,DX
MOV BX,[SI][%PARM4-2]
MOV CX,[BX]
NOT DX
AND CX,DX
OR AX,CX
MOV [BX],AX
RETSEG
END
;
;
; --------------------------------------------------------
; FBITSET - SET A BIT FIELD
; --------------------------------------------------------
; STACK CONTAINS: SHIFT COUNT
; BIT MASK
; VALUE OF FIELD
; ADDRESS OF WORD CONTAINING FIELD
;
IDT $_FBITS
DEF $_FBITS
$_FBITS MOV SI,SP
MOV CX,[SI][%PARM1-2]
MOV DX,[SI][%PARM2-2]
MOV AX,[SI][%PARM3-2]
JCXZ NOSHIFT
SHL AX,CL
NOSHIFT AND AX,DX
MOV BX,[SI][%PARM5-2]
MOV ES,BX
MOV BX,[SI][%PARM4-2]
SEGES
MOV CX,[BX]
NOT DX
AND CX,DX
OR AX,CX
SEGES
MOV [BX],AX
RETSEG
END
;
;
; --------------------------------------------------------
; FARCMP - COMPARE FAR POINTERS
; --------------------------------------------------------
; STACK CONTAINS: TWO FAR POINTERS
;
IDT $_FARCMP
DEF $_FARCMP
$_FARCMP MOV SI,SP
MOV DX,[SI][%PARM1-2]
MOV CX,[SI][%PARM2-2]
MOV BX,[SI][%PARM3-2]
MOV AX,[SI][%PARM4-2]
CMP AX,CX
JZ SEGNE
CMPOFF CMP BX,DX
JZ EQUAL
JL LESS
GREATER MOV AL,1 ; GREATER THAN
JMPS DONE
LESS MOV AL,>FF ; LESS THAN
JMPS DONE
EQUAL XOR AX,AX
DONE RETSEG
; Segments unequal, normalize
SEGNE PUSH DX
PUSH CX
MOV CL,4
PUSH BX
SHR BX,CL
ADD AX,BX
POP BX
AND BX,>FFF
SHR DX,CL
POP CX
ADD CX,DX
POP DX
AND DX,>FFF
CMP AX,CX
JL LESS
JG GREATER
JMPS CMPOFF
END
;

1212
Mix Power C v1/FARHEAP.ASM Normal file

File diff suppressed because it is too large Load Diff

374
Mix Power C v1/FARMEM.ASM Normal file
View File

@ -0,0 +1,374 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; farrepmem(address,data,datasize, copies)
; fill memory with copies of a template
; -------------------------------------------------------
;
IDT farrepmem
IF LONGNAME
LDEF farrepmem
ENDIF
IF SHORTNAME
DEF Frepmem
ENDIF
;
farrepmem equ $
Frepmem PUSH BP
MOV BP,SP
MOV DX,[BP][%PARM6] ; number of copies
TEST DX,DX
JZ DONE
MOV CX,[BP][%PARM5] ; size of block
JCXZ DONE
MOV DI,[BP][%PARM1] ; address of data
MOV ES,[BP][%PARM2]
CLD
PUSH DS
MOV DS,[BP][%PARM4]
FILL MOV SI,[BP][%PARM3] ; pattern data
MOV CX,[BP][%PARM5] ; size of block
REP
MOVSB
DEC DX
JNZ FILL
POP CX
MOV DS,CX
DONE POP BP
RETSEG
END
;
; -------------------------------------------------------
; farmemcpy(destination, source, n) - move block of memory
; does not test for overlapping blocks
; size is limited to 64k
; does not check for segment wrap arround
; -------------------------------------------------------
;
IDT farmemcpy
IF LONGNAME
LDEF farmemcpy
ENDIF
IF SHORTNAME
DEF Fmemcpy
ENDIF
farmemcpy equ $
Fmemcpy PUSH BP
MOV BP,SP
MOV CX,[BP][%PARM5]
JCXZ DONE
MOV DI,[BP][%PARM1]
MOV ES,[BP][%PARM2]
PUSH DS
MOV SI,[BP][%PARM3]
MOV DS,[BP][%PARM4]
CLD
REP
MOVSB
POP AX
MOV DS,AX
DONE MOV AX,[BP][%PARM1] ; Result is ptr to dest
MOV DX,[BP][%PARM2]
POP BP
RETSEG
END
;
; -------------------------------------------------------
; farmemmove(destination, source, n) - move block of memory
; checks for overlapping blocks
; size is limited to 64k
; -------------------------------------------------------
;
IDT farmemmove
IF LONGNAME
LDEF farmemmove
ENDIF
IF SHORTNAME
DEF Fmemmove
ENDIF
farmemmove equ $
Fmemmove PUSH BP
MOV BP,SP
MOV CX,[BP][%PARM5]
JCXZ DONE
MOV DI,[BP][%PARM2] ; dest segment
MOV SI,[BP][%PARM4] ; src segment
XOR AX,AX
XOR DX,DX
MOV CX,4 ; convert to 20 bit
SHIFT1 SHL DI,1
RCL DX,1
SHL SI,1
RCL AX,1
LOOP SHIFT1
ADD DI,[BP][%PARM1] ; dest offset
ADC DX,0
ADD SI,[BP][%PARM3] ; src offset
ADC AX,0
CMP DX,AX
JB DSTLOWER
JA SRCLOWER
CMP DI,SI
JB DSTLOWER
JA SRCLOWER
DONE MOV AX,[BP][%PARM1] ; Result is ptr to dest
MOV DX,[BP][%PARM2]
POP BP
RETFAR
DSTLOWER CLD
MOV CX,[BP][%PARM5]
XOR BX,BX
JMPS MOVE
SRCLOWER STD
MOV CX,[BP][%PARM5]
MOV BX,CX
DEC BX ; length - 1
MOVE PUSH SI
PUSH DI
MOV CX,4
SHIFT2 SHR DX,1 ; Normalize pointers
RCR DI,1
SHR AX,1
RCR SI,1
LOOP SHIFT2
MOV DX,DI
MOV AX,SI
POP DI
AND DI,>F
POP SI
AND SI,>F
ADD DI,BX
ADC DX,0
ADD SI,BX
ADC AX,0
MOV ES,DX
PUSH DS
MOV DS,AX
MOV CX,[BP][%PARM5]
REP
MOVSB
POP AX
MOV DS,AX
CLD
JMPS DONE
END
;
; -------------------------------------------------------
; farmemswap(addr1, addr2, n) - swap two blocks of memory
; -------------------------------------------------------
;
IDT farmemswap
IF LONGNAME
LDEF farmemswap
ENDIF
IF SHORTNAME
DEF Fmemswap
ENDIF
;
farmemswap equ $
Fmemswap MOV BX,SP
PUSH DS
MOV SI,[BX][%PARM1-2]
MOV DS,[BX][%PARM2-2]
MOV DI,[BX][%PARM3-2]
MOV ES,[BX][%PARM4-2]
MOV CX,[BX][%PARM5-2]
JCXZ DONE
CLD
SWAP SEGES
MOV AL,[DI]
XCHG AL,[SI]
STOSB
INC SI
LOOP SWAP
DONE POP AX
MOV DS,AX
RETSEG
END
;
; -------------------------------------------------------
; farmemset(addr, value, count) - fill a block with character
; -------------------------------------------------------
;
IDT farmemset
IF LONGNAME
LDEF farmemset
ENDIF
IF SHORTNAME
DEF Fmemset
ENDIF
;
farmemset equ $
Fmemset MOV BX,SP
MOV DI,[BX][%PARM1-2]
MOV ES,[BX][%PARM2-2]
MOV AX,[BX][%PARM3-2]
MOV CX,[BX][%PARM4-2]
JCXZ DONE
CLD
REP
STOSB
DONE RETSEG
END
;
; -------------------------------------------------------
; farmemccpy(dest, src, c, cnt) - copy up to & including c
; -------------------------------------------------------
;
IDT farmemccpy
IF LONGNAME
LDEF farmemccpy
ENDIF
IF SHORTNAME
DEF Fmemccpy
ENDIF
;
farmemccpy equ $
Fmemccpy PUSH BP
MOV BP,SP
PUSH DS
MOV DI,[BP][%PARM1]
MOV ES,[BP][%PARM2]
MOV SI,[BP][%PARM3]
MOV DS,[BP][%PARM4]
MOV DX,[BP][%PARM5]
MOV CX,[BP][%PARM6]
JCXZ ENDCOUNT
CLD
COPY LODSB
STOSB
CMP AL,DL
JZ FOUND
LOOP COPY
ENDCOUNT XOR AX,AX ; Return null if c not copied
EXIT POP CX
MOV DS,CX
POP BP
RETSEG
FOUND MOV AX,DI ; return address of next after c
JMPS EXIT
END
;
; -------------------------------------------------------
; farmemchr(buf, c, cnt) - search for c in buffer
; -------------------------------------------------------
;
IDT farmemchr
IF LONGNAME
LDEF farmemchr
ENDIF
IF SHORTNAME
DEF Fmemchr
ENDIF
;
farmemchr equ $
Fmemchr PUSH BP
MOV BP,SP
MOV DI,[BP][%PARM1]
MOV ES,[BP][%PARM2]
MOV AX,[BP][%PARM3]
MOV CX,[BP][%PARM4]
CLD
REPNZ
SCASB
JNZ NOFIND
DEC DI
MOV AX,DI ; Return pointer to c in buf
POP BP
RETSEG
NOFIND XOR AX,AX ; Return null if not found
POP BP
RETSEG
END
;
; -------------------------------------------------------
; farmemcmp(buf1, buf2, cnt) - compare memory
; -------------------------------------------------------
;
IDT farmemcmp
IF LONGNAME
LDEF farmemcmp
ENDIF
IF SHORTNAME
DEF Fmemcmp
ENDIF
;
farmemcmp equ $
Fmemcmp PUSH BP
MOV BP,SP
PUSH DS
MOV SI,[BP][%PARM1]
MOV DS,[BP][%PARM2]
MOV DI,[BP][%PARM3]
MOV ES,[BP][%PARM4]
MOV CX,[BP][%PARM5]
COMPARE JCXZ EQUAL
CLD
REPZ
CMPSB
JZ EQUAL
MOV AL,[SI][%-1]
SEGES
SUB AL,[DI][%-1]
CBW
EXIT POP CX
MOV DS,CX
POP BP
RETSEG
EQUAL XOR AX,AX ; Return 0 if buffers are equal
JMPS EXIT
END
;
; -------------------------------------------------------
; farmemicmp(buf1, buf2, cnt) - compare memory
; -------------------------------------------------------
;
IDT farmemicmp
IF LONGNAME
LDEF farmemicmp
ENDIF
IF SHORTNAME
DEF Fmemicmp
ENDIF
;
farmemicmp equ $
Fmemicmp PUSH BP
MOV BP,SP
PUSH DS
MOV SI,[BP][%PARM1]
MOV DS,[BP][%PARM2]
MOV DI,[BP][%PARM3]
MOV ES,[BP][%PARM4]
MOV CX,[BP][%PARM5]
JCXZ EQUAL
CLD
MATCH REPZ
CMPSB
JZ EQUAL
MOV AL,[SI][%-1]
SEGES
MOV AH,[DI][%-1]
CMP AL,'a'
JB X1
CMP AL,'z'
JA X1
SUB AL,>20
X1 CMP AH,'a'
JB X2
CMP AH,'z'
JA X2
SUB AH,>20
X2 CMP AL,AH
JZ MATCH
MOV AL,[SI][%-1]
SEGES
SUB AL,[DI][%-1]
CBW
EXIT POP CX
MOV DS,CX
POP BP
RETSEG
EQUAL XOR AX,AX
JMPS EXIT
END

1045
Mix Power C v1/FARSTR.ASM Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,97 @@
;
; Copyright (c) Mix Software 1988
;
; ------------------------------------------------------------
IDT _fmemcpy
DEF _fmemcpy
IF UPPER
DEF _FMEMCPY
ENDIF
; ------------------------------------------------------------
;
; char far *_fmemcpy(dest, source, n)
; char far *dest, far *source;
; unsigned n;
;
; Purpose: Copies n characters from source to dest
; Returns: dest
;
; TOS --> RETURN ADDR. OFFSET
; RETURN ADDR. SEGMENT
; SIZE SIZE (UNSIGNED)
; SOURCE SOURCE (FAR *)
; DEST DEST (FAR *)
;
DESTOFF EQU 4+2
DESTSEG EQU DESTOFF+2
SRCOFF EQU DESTSEG+2
SRCSEG EQU SRCOFF+2
SIZE EQU SRCSEG+2
SETCPU 8086
_fmemcpy
_FMEMCPY PUSH BP
MOV BP,SP
MOV CX,[BP][%SIZE]
JCXZ DONE
PUSH DS
MOV AX,[BP][%SRCSEG]
MOV BX,[BP][%DESTSEG]
MOV SI,[BP][%SRCOFF]
MOV DI,[BP][%DESTOFF]
CMP AX,BX
JNE SKIP
CMP SI,DI
JGE SKIP
ADD SI,CX
DEC SI
ADD DI,CX
DEC DI
STD
SKIP: MOV DS,AX
MOV ES,BX
REP
MOVSB
CLD
POP AX
MOV DS,AX
DONE: MOV DX,[BP][%DESTSEG]
MOV AX,[BP][%DESTOFF]
POP BP
RETSEG
END
;
; ------------------------------------------------------------
IDT _fstrlen ;RETURN LENGTH OF FAR STRING
DEF _fstrlen
IF UPPER
DEF _FSTRLEN
ENDIF
; ------------------------------------------------------------
;
; int _fstrlen(s)
; char far *s;
;
; Purpose: Find length of string s
; Returns: length of string s
;
; TOS --> RETURN (far *)
; S (far *)
;
SOFFSET EQU 4
SSEGMENT EQU SOFFSET+2
;
SETCPU 8086
_fstrlen
_FSTRLEN MOV BX,SP
MOV DI,[BX][%SOFFSET]
MOV ES,[BX][%SSEGMENT]
MOV CX,-1
XOR AL,AL
CLD
REPNZ ; get length of string2
SCASB
NOT CX
DEC CX
MOV AX,CX
RETSEG
END

47
Mix Power C v1/FATAL.ASM Normal file
View File

@ -0,0 +1,47 @@
;
; Fatal error processor
; Copyright (c) Mix Software 1988
;
; Generates a message to stderr and terminates.
;
IDT $_FATAL
DEF $_FATAL
FREF _exit
DREF errno
$_FATAL PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1] ; fetch error code
MOV DX,AX
AND AX,>000F
CMP AL,9
JLE DIGIT
ADD AL,7
DIGIT ADD AL,'0'
MOV %[DIG0],AL
MOV CL,4
SHR DL,CL
AND DL,>0F
CMP DL,9
JLE DIGIT2
ADD DL,7
DIGIT2 ADD DL,'0'
MOV %[DIG1],DL
MOV DX,ERRMSG
MOV AX,>4000
MOV BX,2
MOV CX,MSGLEN
INT >21
PUSH [errno]
CALLFAR _exit
POP DX
POP BP
RETFAR
;
DORG 0
ERRMSG DB 'Fatal error #'
DIG1 DB '0'
DIG0 DB '0'
DB >0D,>0A
MSGLEN EQU $-ERRMSG
;
END

15
Mix Power C v1/FCNTL.H Normal file
View File

@ -0,0 +1,15 @@
/*$no list*//*$no trace <<< fcntl.h >>> */
/* Copyright (c) Mix Software 1988 */
#define O_RDONLY 0x0000
#define O_WRONLY 0x0001
#define O_RDWR 0x0002
#define O_APPEND 0x0008
#define O_CREAT 0x0100
#define O_TRUNC 0x0200
#define O_EXCL 0x0400
#define O_TEXT 0x4000
#define O_BINARY 0x8000
#define O_MODEMASK 0x00F3
/*$list*//*$trace <<< fcntl.h >>> */

33
Mix Power C v1/FDB.H Normal file
View File

@ -0,0 +1,33 @@
typedef struct {
char init; /* initialized flag */
char openflg; /* file open */
int handle; /* file handle */
char *bufr; /* start of buffer */
char *ptr; /* address of next character */
int count; /* number of characters left in bufr */
int bufsize; /* size of buffer */
int reclen; /* record length */
char device; /* device code */
char eofflag; /* end of file detected */
char mode; /* read, write or read/write */
char dirty; /* buffer written to */
char error; /* error code */
char flags; /* control flags */
char column; /* column (text files */
char ungetch; /* character from ungetc (unbuffered files) */
char *gpbufr; /* buffer used by get & put */
char *pathnm; /* name of file */
char flag2; /* more flags */
char fill2[5];
} fdb;
#define fdbinary 0x02
#define fdctlz 0x04
#define fdfilter 0x08
#define fdecho 0x10
#define fdunbufr 0x20
#define fdappend 0x40
#define fdsetbuf 0x80
#define fdwrite 0x01
#define fdread 0x02
#define fd2temp 0x01

344
Mix Power C v1/FILE.C Normal file
View File

@ -0,0 +1,344 @@
/* File manipulation */
/* Copyright (c) Mix Software 1988 */
int access(pathname, mode) /* can file be accessed in this mode */
char *pathname; /* name of file */
int mode; /* mode 02 = write, 04 = read, 06 = r/w, 00 = exists */
{
extern int errno;
int curmode;
if (_sysacdc(0x4300, 0, pathname, &curmode) == 0) {
if (curmode & 0x0001) { /* file is read only */
if ((mode & 0x0002) == 0) return 0;
errno = EACCES;
return -1;
}
return 0;
}
errno = ENOENT;
return -1;
}
/* ------------------------------------------------------------ */
int chmod(pathname, pmode)
char *pathname;
int pmode;
{
extern int errno;
int mode = 0;
if (pmode & S_IWRITE) mode = 1;
if (_sys_acd(0x4300, 0, pathname, &mode) == 0) return 0;
errno = ENOENT;
return -1;
}
/* ------------------------------------------------------------ */
int eof(fd)
int fd;
{
extern int errno;
if ((fd < 0) || (fd >= MAXFILES)) { errno = EBADF; return -1; }
return feof(_iob[fd]);
}
/* ------------------------------------------------------------ */
int feof(fp)
FILE *fp;
{
int c;
extern int errno;
if (fp == NULL) { errno = EBADF; return -1; }
if (fp->file.eofflag) return 1;
c = _getc(fp);
ungetc(c,fp);
if ((fp->file.flags & fdctlz)) {
if (c == CTLZ) return 1;
}
if (c == EOF) {
if ((fp->file.flags & fdfilter) || fp->file.eofflag) return 1;
}
return 0;
}
/* ------------------------------------------------------------ */
getchar() { return fgetc(stdin); }
fgetchar() { return fgetc(stdin); }
/* ------------------------------------------------------------ */
getc(fp)
FILE *fp;
{ return fgetc(fp); }
/* ------------------------------------------------------------ */
putchar(c) int c; { return fputc(c,stdout); }
fputchar(c) int c; { return fputc(c,stdout); }
/* ------------------------------------------------------------ */
putc(c,fp)
int c;
FILE *fp;
{
return fputc(c,fp);
}
/* ------------------------------------------------------------ */
write(fd, bufptr, n)
int n;
int fd;
char *bufptr;
{
return _write(_iob[fd],bufptr,n);
}
/* ------------------------------------------------------------ */
fflush(fp)
FILE *fp;
{
int fseek();
return fseek(fp, 0L, 1);
}
/* ------------------------------------------------------------ */
flushall() {
int fd;
int count = 0;
int fseek();
for (fd = 5; fd < MAXFILES; fd++) {
if (_iob[fd] != NULL) {
if (fseek(_iob[fd],0L,1) == 0) count++;
}
}
return count;
}
/* ------------------------------------------------------------ */
rewind(fp)
FILE *fp;
{
clearerr(fp);
return fseek(fp, 0L, 0);
}
/* ------------------------------------------------------------ */
int chsize(fd, size)
int fd;
long size;
{
extern int errno, _doserrno;
long lseek();
long cursize, clear, here;
int st, writesize;
int zero[256];
int handle = _iob[fd]->file.handle;
if (fd < 0 || fd > MAXFILES) {
errno = EBADF;
return -1L;
}
here = lseek(fd,0l,1);
cursize = lseek(fd,0l,2);
if (cursize > size) { /* truncate to requested length */
lseek(fd,size,0);
if (_sysabcd(0x4000,handle,0,0,&st) != 0) {
errno = _doserrno;
return -1;
}
}
else { /* extend file by filling with zero */
memset(zero,0,sizeof(zero));
clear = size-cursize;
while (clear != 0) {
writesize = (clear > sizeof(zero)) ? sizeof(zero) : clear;
if (_sysabcd(0x4000,handle,writesize,zero,&st) != 0) {
errno = _doserrno;
return -1;
}
if (st != writesize) {
errno = ENOSPC;
return -1;
}
clear -= writesize;
}
}
lseek(fd,here,0);
return 0;
}
/* ------------------------------------------------------------ */
long filelength(fd)
int fd;
{
long _fseek();
long here, len;
extern int errno;
if (fd < 0 || fd > MAXFILES) {
errno = EBADF;
return -1L;
}
here = _fseek(_iob[fd],0L,1);
if (here == -1L) {
errno = EBADF;
return -1L;
}
len = _fseek(_iob[fd],0L,2);
_fseek(_iob[fd],here,0);
return len;
}
/* ------------------------------------------------------------ */
long lseek(fd, offset, origin)
int fd;
long offset;
int origin;
{
long _fseek();
return _fseek(_iob[fd],offset,origin);
}
/* ------------------------------------------------------------ */
clearerr(fp)
FILE *fp;
{
union REGS r;
fp->file.error = '\0';
fp->file.eofflag = '\0';
r.x.ax = 0x4400;
r.x.bx = fp->file.handle;
r.x.dx = 0;
intdos(&r,&r);
if (r.x.cflag) return;
if ((r.x.dx & 0x80) != 0) {
/* clear eof flag for character device */
r.h.dh = 0;
r.h.dl |= 0x40;
r.x.ax = 0x4401;
intdos(&r,&r);
}
}
/* ------------------------------------------------------------ */
ferror(fp)
FILE *fp;
{
return fp->file.error;
}
/* ------------------------------------------------------------ */
fileno(fp)
FILE *fp;
{
return fp->fd;
}
/* ------------------------------------------------------------ */
long tell(fd)
int fd;
{
extern int errno;
long ftell();
if ((fd < 0) || (fd >= MAXFILES) || (_iob[fd] == NULL))
{ errno = EBADF; return -1; }
return ftell(_iob[fd]);
}
/* ------------------------------------------------------------ */
int fgetpos(fp, pos)
FILE *fp;
long *pos;
{
long ftell(), position;
position = ftell(fp);
if (position == -1) return -1;
*pos = position;
return 0;
}
/* ------------------------------------------------------------ */
int fsetpos(fp,pos)
FILE *fp;
long *pos;
{
int fseek();
return fseek(fp, *pos, 0);
}
/* ------------------------------------------------------------ */
int setmode(fd, mode)
int fd;
int mode;
{
FILE *fp;
int oldmode;
extern int errno;
if ((fd < 0) || (fd >= MAXFILES) || (_iob[fd] == NULL))
{ errno = EBADF; return -1; }
fp = _iob[fd];
oldmode = fp->file.flags;
if (mode == O_TEXT) fp->file.flags = oldmode | fdfilter;
else if (mode == O_BINARY) fp->file.flags = oldmode & (~fdfilter);
else { errno = EINVAL; return -1; }
if (oldmode & fdfilter) return O_TEXT; else return O_BINARY;
}
/* ------------------------------------------------------------ */
int getw(fp)
FILE *fp;
{
struct twobyte {
unsigned char lower;
unsigned char upper;
};
union {
int word;
struct twobyte bytes;
} value;
int c;
if ((c = fgetc(fp)) == EOF) return EOF;
value.bytes.lower = c;
if ((c = fgetc(fp)) == EOF) return EOF;
value.bytes.upper = c;
return value.word;
}
/* ------------------------------------------------------------ */
int putw(binint,fp)
int binint;
FILE *fp;
{
struct twobyte {
unsigned char lower;
unsigned char upper;
};
union {
int word;
struct twobyte bytes;
} value;
value.word = binint;
if (fputc(value.bytes.lower,fp) == EOF) return EOF;
if (fputc(value.bytes.upper,fp) == EOF) return EOF;
return binint;
}

519
Mix Power C v1/FILLM.ASM Normal file
View File

@ -0,0 +1,519 @@
;
; Copyright (c) Mix Software 1988
;
; void _fill_pm(border_color)
; fill a region with a pattern.
; Uses direct access to the screen memory.
; For cga modes 4, 5, and 6 and (hercules monochrome).
; _vxcurs, _vycurs = current coordinate.
; Fill pattern is described by _vf_pat, _vf_wid and _vf_hgt.
;
idt _fill_pm
def _fill_pm
dref _vapage ; active page
dref _vmaxh ; window limits
dref _vminh
dref _vmode
dref _vmaxv
dref _vminv
dref _v_color ; pen color
dref _vxcurs ; current cursor column
dref _vycurs ; current cursor row
dref _vf_pat ; address of fill pattern
dref _vf_wid ; width of fill pattern
dref _vf_hgt ; height of fill pattern
dref $$MAXS
fref $_STKCHK
fref getvmode
fref crt_lock
lfref crt_unlock
CGAHIGH equ 6
CGALOW equ 4
CGALOWBW equ 5
;
; local variables
;
chain equ >0 ; state structure for next level
cy equ 0 ; offsets at next level
cminx equ 2
cmaxx equ 4
cnext equ 6
chainy equ chain+cy ; current y coordinate
minx equ chain+cminx ; minimum x coordinate
maxx equ chain+cmaxx ; minimum x coordinate
lastptr equ chain+cnext ; address of previous frame
local equ lastptr+2
;
; parameters
;
x equ 4+local
y equ 6+local
previous equ 8+local
bordcol equ 4
;
;
_fill_pm callfar crt_lock
mov bx,sp
mov ax,[bx][%bordcol]
mov [border],ax ; save border color
mov [bits],1 ; bits per pixel
mov [fill],l1fill ; fill for 1 bit per pixel
callfar getvmode
cmp ax,HERCMODE
jnz notherc
mov [where],whereh ; pointer to address calculation
mov dx,>b000 ; set base address to active page
cmp %[_vapage],0
jz pageset
mov dx,>b800 ; page 1
pageset mov es,dx
jmps callfill
notherc mov dx,>b800 ; memory base for cga
mov es,dx
cmp ax,CGAHIGH
jnz nothigh
mov [where],where6 ; address calculation for mode 6
jmps callfill
nothigh cmp ax,CGALOW
jz lowres
cmp ax,CGALOWBW
jnz badmode
lowres mov [where],where4 ; address calculation function
mov [bits],2 ; 2 bits per pixel
mov [fill],l2fill ; multi-bit fill function
callfill xor ax,ax
push ax ; null previous block list
push [_vycurs] ; starting position
push [_vxcurs]
call fill_m
callfar crt_unlock
add sp,%6
xor ax,ax
retfar
badmode callfar crt_unlock
mov ax,-1
retfar
;
fill_m push bp
sub sp,local
cmp sp,[$$MAXS] ; check for stack overflow
jnb noflo
callfar $_STKCHK
noflo mov bp,sp
mov ax,[bp][%y]
xor dx,dx
div [_vf_hgt] ; dx = y mod _vf_hgt
mov ax,dx
mul [_vf_wid] ; ax = offset to row of pattern
add ax,[_vf_pat]
mov [xstart],ax ; start of pattern row
mov bx,ax
add ax,[_vf_wid]
mov [xlimit],ax ; end of pattern row
mov ax,[bp][%x]
xor dx,dx
div [_vf_wid] ; dx = x mod _vf_wid
add bx,dx ; bx = initial pattern pointer
mov [patptr],bx
;
; compute memory address and bit mask for (x,y)
;
call [where]
mov [memaddr],si
mov [bitmask],ax
mov dx,[bp][%x]
mov bx,[patptr]
call [fill]
;
mov ax,[bp][%y] ; values for use by next level
mov [bp][%chainy],ax
mov ax,[bp][%previous]
mov [bp][%lastptr],ax
;
; scan lines above and below for unfilled areas
;
dec [bp][%y]
call scan
add [bp][%y],%2
call scan
mov ax,[bp][%maxx]
lea sp,[bp][%local]
pop bp
ret
;
; scan a line from (minx+1,y) to (maxx-1,y)
; for any group with a non-border pixel
; check whether visited before and if not, make
; recursive call to fill the line.
;
scan mov ax,[bp][%y]
cmp ax,[_vminv] ; check y for boundary
jb scandone
cmp ax,[_vmaxv]
ja scandone
mov dx,[bp][%minx]
inc dx
mov [bp][%x],dx
call [where] ; get screen memory address
mov dx,[bp][%x]
scannxt cmp dx,[bp][%maxx]
jae scandone
seges
mov ch,%[si] ; read group of pixels
and ch,ah ; select one
cmp ch,al ; compare to border color
jz scaninc ; border color, skip
; ; search for previously visited
mov cx,[bp][%y]
mov bx,[bp][%previous]
srch test bx,bx
jz nextline ; not done before
cmp cx,[bx] ; same value of y?
jnz nextsrch
cmp dx,[bx][%cminx]
jle nextsrch ; not in range
cmp dx,[bx][%cmaxx]
jge nextsrch
mov dx,[bx][%cmaxx] ; skip this region
dec dx
mov [bp][%x],dx
call [where]
mov dx,[bp][%x]
jmps scaninc
nextsrch mov bx,[bx][%cnext]
jmps srch
nextline lea ax,[bp][%chain] ; call for next line
push ax ; link record
push [bp][%y]
push dx
call fill_m
add sp,%6
mov dx,ax
mov [bp][%x],dx
call [where]
mov dx,[bp][%x]
scaninc inc dx ; next x
mov cl,[bits]
ror al,cl
ror ah,cl ; move to next pixel
jnc nocarry3
inc si ; first pixel in next byte
nocarry3 jmp scannxt ; find next region
scandone ret
;
; fill dots to the left until boundary or window edge
; Special version for 1 bit per pixel
; bx is the pattern pointer
; dx is the value of x
; es:si is the screen address
; ah is the bit mask
; al is the border color
;
; sets minx and maxx to the edges of the area
;
l1fill cmp dx,[_vminh]
jl l1done
seges
mov ch,[si] ; read 8 dots
mov cl,ch
and cl,ah
cmp cl,al
jz l1done
mov cl,%[bx] ; color of pattern
cmp cl,TRANSPAR ; if transparent, do not set
jz l1next
cmp cl,PENCOLOR ; use pen color
jnz l1set2
mov cl,%[_v_color]
l1set2 test cl,%1
jz l1clr
or ch,ah ; set the pixel to 1
jmps l1put
l1clr not ah
and ch,ah ; set the pixel to 0
not ah
l1put seges
mov %[si],ch
l1next dec dx ; decrease x coordinate
rol al,1 ; border color to next bit
rol ah,1 ; move to next bit
jnc l1nc
dec si ; last bit in previous byte
l1nc dec bx ; move back one in pattern
cmp bx,[xstart]
jae l1fill
mov bx,[xlimit] ; move to end of pattern
dec bx
jmps l1fill
l1done mov [bp][%minx],dx
;
mov dx,[bp][%x]
mov si,[memaddr]
mov ax,[bitmask]
mov bx,[patptr]
jmps r1next
;
r1fill cmp dx,[_vmaxh]
ja r1done
seges
mov ch,[si] ; read 8 dots
mov cl,ch
and cl,ah
cmp cl,al
jz r1done
mov cl,%[bx] ; color of pattern
cmp cl,TRANSPAR ; if transparent, do not set
jz r1next
cmp cl,PENCOLOR ; use pen color
jnz r1set2
mov cl,%[_v_color]
r1set2 test cl,%1
jz r1clr
or ch,ah ; set the pixel to 1
jmps r1put
r1clr not ah
and ch,ah ; set the pixel to 0
not ah
r1put seges
mov %[si],ch
r1next inc dx ; increase x coordinate
ror al,1
ror ah,1 ; move to next bit
jnc r1nc
inc si ; first bit in next byte
r1nc inc bx ; move forward one in pattern
cmp bx,[xlimit]
jnz r1fill
mov bx,[xstart] ; move to end of pattern
jmps r1fill
r1done mov [bp][%maxx],dx
ret
;
; fill dots to the left until boundary or window edge
; Each pixel is 2 bits
; bx is the pattern pointer
; dx is the value of x
; es:si is the screen address
; ah is the bit mask
; al is the border color
;
; sets minx and maxx to the edges of the area
;
l2fill mov di,bx
l2fill0 cmp dx,[_vminh]
jl l2done
seges
mov ch,[si] ; read 4 dots
mov cl,ch
and cl,ah ; isolate this pixel
cmp cl,al
jz l2done ; border color
mov bl,%[di] ; color of pattern
cmp bl,TRANSPAR ; if transparent, do not set
jz l2next
cmp bl,PENCOLOR ; use pen color
jnz l2set2
mov bl,%[_v_color]
l2set2 and bl,3
mov cl,dl ; x coordinate
and cl,%3 ; mask bit number
neg cl
add cl,3
jz l2noshf
add cl,cl ; number of shifts needed
shl bl,cl ; shift color into position
l2noshf not ah
and ch,ah ; mask previous contents
not ah
or ch,bl ; load new color value
seges
mov %[si],ch
l2next dec dx ; decrease x coordinate
rol al,1 ; border color to next position
rol al,1
rol ah,1 ; move to next pixel
rol ah,1
jnc l2nc
dec si ; last bit in previous byte
l2nc dec di ; move back one in pattern
cmp di,[xstart]
jae l2fill0
mov di,[xlimit] ; move to end of pattern
dec di
jmps l2fill0
l2done mov [bp][%minx],dx
;
mov dx,[bp][%x]
mov si,[memaddr]
mov ax,[bitmask]
mov di,[patptr]
jmps r2next
;
r2fill cmp dx,[_vmaxh]
ja r2done
seges
mov ch,[si] ; read 4 dots
mov cl,ch
and cl,ah
cmp cl,al
jz r2done
mov bl,%[di] ; color of pattern
cmp bl,TRANSPAR ; if transparent, do not set
jz r2next
cmp bl,PENCOLOR ; use pen color
jnz r2set2
mov bl,%[_v_color]
r2set2 and bl,3
mov cl,dl ; x coordinate
and cl,3 ; mask bit number
neg cl
add cl,3
jz r2noshf
add cl,cl ; number of shifts needed
shl bl,cl ; shift color into position
r2noshf not ah
and ch,ah ; mask previous contents
not ah
or ch,bl ; load new color value
seges
mov %[si],ch
r2next inc dx ; increase x coordinate
ror al,1
ror al,1
ror ah,1 ; move to next bit
ror ah,1
jnc r2nc
inc si ; first pixel in next byte
r2nc inc di ; move forward one in pattern
cmp di,[xlimit]
jnz r2fill
mov di,[xstart] ; move to end of pattern
jmps r2fill
r2done mov [bp][%maxx],dx
ret
;
; compute address and bit mask for a pixel (Hercules)
; inputs:
; [bp][y] = y coordinate
; [bp][x] = x coordinate
; outputs:
; si = memory address
; ah = bit mask
; al = border color
; cx, dx are altered
;
whereh mov ax,[bp][%y]
mov si,ax
and si,>0003
mov cl,13
shl si,cl ; (y % 4) * 0x2000
mov cl,2
shr ax,cl ; y/4
shl ax,1 ; (y/4) * 0x02
add si,ax
shl ax,cl ; (y/4) * 0x08
add si,ax
shl ax,1 ; (y/4) * 0x10
add si,ax
shl ax,cl ; (y/4) * 0x40
add si,ax
mov ax,[bp][%x]
mov cx,ax
shr ax,1 ; x/8
shr ax,1
shr ax,1
add si,ax
and cx,>0007 ; x % 8
mov ah,>80
mov al,[border]
ror al,1
jcxz noshifth
shr ax,cl
noshifth ret
;
; compute address and bit mask for a pixel (cga mode 6)
; inputs:
; [bp][y] = y coordinate
; [bp][x] = x coordinate
; outputs:
; si = memory address
; ah = bit mask
; al = border color
; cx is altered
;
where6 mov ax,[bp][%y]
mov si,ax
and si,>0001
mov cl,13
shl si,cl ; (y % 2) * 0x2000
shr ax,1 ; y/2
mov cl,4
shl ax,cl ; (y/2) * 0x10
add si,ax
shl ax,1
shl ax,1 ; ax = (y/2) * 0x40
add si,ax
mov ax,[bp][%x]
mov cx,ax
shr ax,1 ; x/8
shr ax,1
shr ax,1
add si,ax
and cx,>0007 ; x % 8
mov ah,>80
mov al,[border]
ror al,1
jcxz noshift6
shr ax,cl
noshift6 ret
;
; compute address and bit mask for a pixel (cga mode 4 or 5)
; inputs:
; [bp][y] = y coordinate
; [bp][x] = x coordinate
; outputs:
; si = memory address
; ah = bit mask
; al = border color
; cx is altered
;
where4 mov ax,[bp][%y]
mov si,ax
and si,>0001
mov cl,13
shl si,cl ; (y % 2) * 0x2000
shr ax,1 ; y/2
mov cl,4
shl ax,cl ; (y/2) * 0x10
add si,ax
shl ax,1
shl ax,1 ; ax = (y/2) * 0x40
add si,ax
mov ax,[bp][%x]
mov cx,ax
shr ax,1 ; x/4
shr ax,1
add si,ax
and cx,>0003 ; x % 4
mov ah,>C0
mov al,[border]
ror al,1
ror al,1
jcxz noshift4
shr ax,cl
shr ax,cl
noshift4 ret
;
; local static variables
;
dorg 0
xstart dw 0-0 ; beginning of line of fill pattern
xlimit dw 0-0 ; end of line of fill pattern
memaddr dw 0-0 ; address of pixel in memory
bitmask dw 0-0 ; bit position of pixel
patptr dw 0-0 ; initial fill pattern pointer
border dw 0-0 ; border color
bits dw 0-0 ; number of bits per pixel
where dw 0-0 ; address calculation function
fill dw 0-0 ; fill current line function
end

38
Mix Power C v1/FINDFIRS.C Normal file
View File

@ -0,0 +1,38 @@
/* Directory searching functions */
/* Copyright (c) Mix Software 1988 */
struct ffblk {
char ff_reserved[21]; /* used by dos */
char ff_attrib; /* attributes of the file */
int ff_ftime; /* time file last modified */
int ff_fdate; /* date file last modified */
long ff_fsize; /* size of file */
char ff_name[13]; /* name of file (xxxxxxxx.yyy) */
};
int findfirst(pathname, ffblk, attrib)
char *pathname;
struct ffblk *ffblk;
int attrib;
{
extern int errno;
extern int _doserrno;
int stat;
_sys_ad(0x1a00,ffblk,&stat); /* set dma address */
if (_sys_acd(0x4e00,attrib,pathname,&stat) == 0) return 0;
errno = _doserrno;
return -1;
}
int findnext(ffblk)
struct ffblk *ffblk;
{
extern int errno;
extern int _doserrno;
int stat;
_sys_ad(0x1a00,ffblk,&stat); /* set dma address */
if (_sys_ad(0x4f00,0,&stat) == 0) return 0;
errno = _doserrno;
return -1;
}

104
Mix Power C v1/FLAGS.C Normal file
View File

@ -0,0 +1,104 @@
/* Flag setting functions */
/* Copyright (c) Mix Software 1988 */
conbuf(flag)
int flag;
{
int oldflag;
extern char $$UBCON;
oldflag = $$UBCON;
$$UBCON = flag;
return oldflag;
}
mathtrap(flag)
int flag;
{
int oldflag;
extern char $$ARTERM;
extern char _mathmsg;
oldflag = $$ARTERM;
$$ARTERM = flag;
_mathmsg = flag;
return oldflag;
}
char _mathmsg = 0;
filetrap(flag)
int flag;
{
int oldflag;
extern char $$IOTERM;
oldflag = $$IOTERM;
$$IOTERM = flag;
return oldflag;
}
heaptrap(flag)
int flag;
{
int oldflag;
extern char $$HPTERM;
oldflag = $$HPTERM;
$$HPTERM = flag;
return oldflag;
}
iofilter(linefeed, ctrlz)
int linefeed, ctrlz;
{
extern char $$CLFEED;
extern char $$CCTLZ;
$$CLFEED = linefeed;
$$CCTLZ = ctrlz;
}
exitmsg()
{
extern void (*$$EXITPT)();
void _exitmsg();
extern void (*_exitptr)();
if (_exitptr == NULL) {
_exitptr = $$EXITPT;
$$EXITPT = _exitmsg;
}
}
void _exitmsg()
{
extern void (*_exitptr)();
extern unsigned $$BOTTOM, $$MAXS, $$LIMIT, $$MAXH, $$HMAX, $$HMIN;
static char msg[]
= "xxxxx bytes of heap space used, xxxxx bytes free\r\l$";
static char stk[]
= "xxxxx bytes of stack used, xxxxx bytes free\r\l$";
char *stkptr;
int x;
stkptr = (char *) $$LIMIT;
while (*stkptr == 0) ++stkptr;
_utoa($$BOTTOM - (unsigned) stkptr,&stk[0]);
_utoa((unsigned) stkptr - $$LIMIT,&stk[27]);
_sys_ad(0x0900,stk,&x);
_utoa($$MAXH,&msg[0]);
_utoa($$HMAX-$$HMIN-$$MAXH,&msg[32]);
_sys_ad(0x0900,msg,&x);
(*_exitptr)();
}
void (*_exitptr)() = NULL;
_utoa(n, s) /* convert unsigned int to fixed size string */
unsigned n; /* result is 5 characters, right justified */
char *s; /* with leading zeros suppressed */
{
char *ptr;
setmem(s,5,' ');
ptr = s+4;
do {
*(ptr--) = n % 10 + 0x30;
} while ((n /= 10) > 0);
return s;
}

140
Mix Power C v1/FLUSH.ASM Normal file
View File

@ -0,0 +1,140 @@
;
; Copyright (c) Mix Software 1988
;
; flush output buffer
;
; _fflush(fp) /* write any remaining data from buffer to file */
; fdb *fp;
;
IDT _fflush
DEF _fflush
FREF _seekend
REF _fileerr
_fflush MOV BX,SP
MOV SI,[BX][%PARM1-2]
TEST %[SI][%FD$DIRTY],%FL$WRITE
JNZ DOWRITE
XOR AX,AX
RETSEG
;
; fp->dirty = 0;
; count = fp->bufsize - fp->count;
;
DOWRITE AND %[SI][%FD$DIRTY],%>FF-FL$WRITE
MOV CX,[SI][%FD$BUFSZ]
SUB CX,[SI][%FD$COUNT]
;
; if (count > 0) {
;
JCXZ DONE
;
; if (_sysabcd(0x4000,fp->handle,count,fp->bufr,&status) != 0)
; (*_fileerr)(status,fp);
;
; Seek to end of file if append mode
TEST [SI][%FD$FLAGS],FL$APPEN
JZ W1
PUSH DI
PUSH CX
PUSH SI
CALLFAR _seekend
POP SI
POP CX
POP DI
W1 MOV AX,>4000
MOV BX,[SI][%FD$HNDL]
MOV DX,[SI][%FD$BUFR]
PUSH CX
INT >21
POP CX
JNB OK
FILEERR PUSH SI
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%4
MOV AL,[SI][%FD$ERR]
XOR AH,AH
RETSEG
;
; else {
; if (status != count) (*_fileerr)(0x9a,fp);
; else fp->error = 0;
;
OK CMP AX,CX
JNZ DISKFULL
MOV [SI][%FD$COUNT],0
DONE MOV AX,[SI][%FD$BUFR]
MOV [SI][%FD$PTR],AX
XOR AX,AX
RETSEG
;
DISKFULL MOV AX,E$NOSPAC
JMPS FILEERR
END
;
;
; _rflush(fp) /* postion a read file for writing */
; FILE *fp;
;
IDT _rflush
DEF _rflush
REF _fileerr
_rflush MOV BX,SP
MOV SI,[BX][%PARM1-2]
TEST %[SI][%FD$DIRTY],%FL$READ
JNZ DOREAD
XOR AX,AX
RETSEG
;
; fp->dirty = 0;
; count = fp->ptr - fp->bufr;
;
DOREAD AND %[SI][%FD$DIRTY],%>FF-FL$READ
MOV CX,[SI][%FD$PTR]
SUB CX,[SI][%FD$BUFR]
MOV [SI][%FD$COUNT],0
;
; if (count > 0) {
;
JCXZ DONE
;
; if (_sysabcd(0x4201,handle,0,count,&status) != 0)
; return (*_fileerr)(status,fp); }
; return 0;
;
MOV AX,>4201
MOV BX,[SI][%FD$HNDL]
MOV DX,CX
XOR CX,CX
INT >21
JB FILEERR
DONE MOV AX,[SI][%FD$BUFR]
MOV [SI][%FD$PTR],AX
XOR AX,AX
RETSEG
FILEERR PUSH SI
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%4
RETSEG
END
;
; Seek to end of file
; _seekend(fdbptr)
;
IDT _seekend
DEF _seekend
;
_seekend PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM1]
MOV AX,>4202
XOR CX,CX
XOR DX,DX
MOV BX,[SI][%FD$HNDL]
INT >21
POP BP
RETSEG
END

219
Mix Power C v1/FREE.ASM Normal file
View File

@ -0,0 +1,219 @@
;
; --------------------------------------------------
; free - release a block of heap
; --------------------------------------------------
;
IDT cfree
DEF cfree
DEF free
DEF _nfree
IF UPPER
DEF CFREE
DEF FREE
ENDIF
FREF $$FREE$$
;
; free(ptr) - release a block of heap
;
cfree equ $
CFREE EQU $
free equ $
_nfree equ $
FREE MOV SI,SP
MOV BX,[SI][%PARM1-2]
CALLFAR $$FREE$$
XOR AX,AX
RETSEG
END
;
; $_FREE(ptr);
; ptr is address of a pointer
; block is released and pointer set to nil
;
IDT $_free
DEF $_FREE
FREF $$FREE$$
$_FREE PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1] ; pointer address
MOV BX,[BX] ; value of pointer
CALLFAR $$FREE$$
MOV BX,[BP][%PARM1] ; pointer address
MOV [BX],0
POP BP
RETSEG
END
;
; ------------------------------------------------------------
;
; FREE$$
; RELEASE A HEAP PACKET
; INPUTS:
; BX - POINTER TO THE PACKET BEGIN RETURNED
; OUTPUTS:
; NONE
; REGISTERS USED:
; DI, SI, BP ARE PRESERVED
;
;
IDT $$FREE$$
DEF $$FREE$$
REF $$HPTERM
FREF $_FATAL
REF $$HMIN
REF $$HMAX
REF $$CURH
REF $$FREE
REF errno
;
; CHECK FOR SIZE, NIL POINTER
;
$$FREE$$ TEST BX,BX
JNZ FREE01
RETSEG ; NIL - EXIT
FREE01 SUB BX,%2 ; POINT TO LENGTH FIELD
;
; CHECK POINTER AGAINST LOWER BOUND OF HEAP - ERROR IF LESS
;
CMP BX,[$$HMIN]
JB INVPKT
;
; GET LENGTH OF THE PACKET
;
FR01 MOV CX,[BX]
TEST CL,%1 ; CHECK ALLOCATED FLAG
JZ INVPKT ; NOT ALLOCATED
AND CL,%>FE ; RESET ALLOCATION FLAG
MOV AX,BX
ADD AX,CX ; AX POINTS TO NEXT PACKET
;
; CHECK PTR + SIZE OF PACKET AGAINST HEAP UPPER BOUND
;
CMP AX,[$$HMAX]
JA INVPKT
;
; BX = ADDRESS OF RELEASED PACKET
; CX = SIZE OF RELEASED PACKET
; AX = ADDRESS OF NEXT PACKET
;
; PACKET IS VALID, RELEASE IT
;
FR02 SUB [$$CURH],CX ; SUBTRACT FROM CURRENT
;
; IS NEXT PACKET ALLOCATED?
;
MOV DX,BX
MOV BX,AX
TEST [BX],%1 ; CHECK ALLOCATION FLAG
JNZ FR03 ; ALLOCATED
;
; NEXT PACKET IS AVAILABLE, MERGE CURRENT AND NEXT PACKETS
;
MOV AX,[BX] ; GET SIZE OF NEXT PACKET
TEST AX,AX ; CHECK FOR ZERO
JZ FR03 ; DON'T MERGE WITH ANCHOR
ADD CX,AX ; CX = SIZE OF COMBINATION
;
; ASSIGN FREELIST TO NEW PACKET
;
MOV [$$FREE],DX
;
; FIND THE PREVIOUS PACKET THAT IS FREE AND CLOSEST
; TO THE PACKET BEING RELEASED
;
MOV AX,[BX][2] ; GET NEXT FIELD FOR CURRENT
MOV BX,[BX][4] ; PREV LINK OF NEXT FREE PKT
;
; AT THIS POINT:
; DX = CURRENT PACKET
; AX = NEXT PACKET
; BX = PREVIOUS PACKET
; CX = LENGTH OF CURRENT
;
JMPS FR05 ; CHECK FOR LAST PACKET FREE
;
; NEXT PACKET IS NOT AVAILABLE
; FIND THE NEXT PACKET THAT IS AVAILABLE TO GET
; ITS LAST PACKET POINTER
; BX = NEXT PACKET
; CX = PACKET SIZE
; DX = CURRENT PACKET
;
FR03 MOV AX,[BX] ; GET SIZE OF NEXT PACKET
AND AL,%>FE ; REMOVE ALLOCATION FLAG
ADD BX,AX ; POINT TO FOLLOWING
TEST [BX],%1 ; CHECK NEXT PACKET ALLOCATION
JNZ FR03 ; LOOP UNTIL FREE
;
; BX NOW POINTS TO THE NEXT FREE PACKET
; GET THE LAST POINTER FROM THE NEXT PACKET
;
MOV AX,BX
MOV BX,[BX][4] ; GET PREV POINTER
;
; AT THIS POINT:
; AX = NEXT PACKET
; CX = PACKET LENGTH
; DX = CURRENT PACKET
; BX = LAST PACKET
;
;
; CHECK LAST PACKET. IF THE LAST FREE PACKET IS CONTIGUOUS
; WITH THE CURRENT PACKET, THEY CAN BE MERGED INTO A SINGLE
; PACKET.
;
FR05 PUSH AX ; SAVE
MOV AX,[BX] ; LENGTH OF PREVIOUS PKT
ADD AX,BX ; AX <-- LAST+SIZE(LAST)
CMP AX,DX
JNZ FR06 ; CAN NOT JOIN
;
; THE LAST PACKET IS CONTIGUOUS WITH THE CURRENT PACKET,
; MERGE THEM.
;
ADD CX,[BX] ; ADD LENGTHS
MOV [BX],CX ; SET TOTAL LENGTH
POP AX
MOV [BX][2],AX ; SET NEXT PKT POINTER
XCHG BX,AX
MOV [BX][4],AX ; SET NEXT@.LAST TO MERGED PKT
;
; SET FREE LIST TO MERGED PACKET
;
MOV [$$FREE],AX
RETSEG ; DONE
;
;
; THE LAST PACKET IS NOT CONTIGUOUS WITH THE CURRENT PACKET
; A NEW PACKET IS CREATED FOR THE PACKET BEING RELEASED.
;
; TOS = NEXT
; DX = CURRENT
; BX = PREVIOUS
; CX = LENGTH
;
FR06 XCHG BX,DX
MOV [BX],CX ; SET SIZE
POP AX
MOV [BX][2],AX ; SET NEXT POINTER
MOV [BX][4],DX ; SET PREVIOUS
XCHG BX,DX
MOV [BX][2],DX ; SET PREV@.NEXT
MOV BX,AX
MOV [BX][4],DX ; SET NEXT@.LAST
;
; DONE
;
FREEX RETSEG
;
; INVALID PACKET POINTER
;
INVPKT MOV AX,E$PACKET
MOV %[errno],AL
TEST %[$$HPTERM],%>FF
JZ FREEX
PUSH AX
CALLFAR $_FATAL
POP AX
RETSEG
END

80
Mix Power C v1/FSTAT.C Normal file
View File

@ -0,0 +1,80 @@
/* File status functions */
/* Copyright (c) Mix Software 1988 */
int fstat(fd, buffer)
int fd;
struct statstr *buffer;
{
union REGS r;
extern errno;
int stat();
if ((fd < 0) || (fd >= MAXFILES) || (_iob[fd] == NULL))
{ errno = EBADF; return -1; }
r.x.ax = 0x4400;
r.x.bx = fd;
r.x.cx = 0;
r.x.dx = 0;
intdos(&r,&r);
if (r.x.cflag != 0) {errno = EBADF; return -1;}
if (r.x.ax & 0x80) { /* character device */
buffer->st_mode = S_IFCHR;
buffer->st_nlink = 1;
buffer->st_dev = fd;
buffer->st_rdev = fd;
return 0;
}
if (stat(_iob[fd]->file.pathnm,buffer) == -1) return -1;
buffer->st_size = filelength(fd);
return 0;
}
int stat(pathname, buffer)
char *pathname;
struct statstr *buffer;
{
struct statstru {
char res[21];
char attr;
unsigned time;
unsigned date;
long size;
char name[13];
} statbufr;
int status;
unsigned flag;
char *p;
long time;
extern int errno, _doserrno;
extern int daylight;
long _timesec();
_sys_ad(0x1a00,&statbufr,&status);
if (_sys_acd(0x4e00,0x0016,pathname,&status) != 0)
{ errno = _doserrno; return -1; }
buffer->st_size = statbufr.size;
if ((p = strchr(pathname,':')) != NULL)
buffer->st_dev = tolower(*--p) - 'a';
else buffer->st_dev = _sys_al(0x1900);
buffer->st_rdev = buffer->st_dev;
time = _timesec(((statbufr.date >> 9) & 0x7f) + 1980,
(statbufr.date >> 5) & 0x0f, statbufr.date & 0x1f,
(statbufr.time >> 11) & 0x1f, (statbufr.time >> 5) & 0x3f,
statbufr.time & 0x1f);
if (daylight) time += 3600l;
buffer->st_atime = time;
buffer->st_mtime = time;
buffer->st_ctime = time;
_sysacdc(0x4300,0,pathname,&status);
if (status & 0x0010) flag = S_IFDIR; else flag = S_IFREG;
flag |= S_IREAD;
if ((status & 0x0001) == 0) flag |= S_IWRITE;
if ((stristr(pathname,".EXE") != NULL) ||
(stristr(pathname,".COM") != NULL)) flag |= S_IEXEC;
flag |= 0x36;
buffer->st_mode = flag;
buffer->st_ino = 0;
buffer->st_uid = 0;
buffer->st_gid = 0;
buffer->st_nlink = 1;
return 0;
}

245
Mix Power C v1/GET.ASM Normal file
View File

@ -0,0 +1,245 @@
;
; Copyright (c) Mix Software 1988
;
; ------------------------------------------------------------
;
; fgetc(fp)
; FILE *fp;
;
IDT fgetc
DEF fgetc
FREF _fflush
FREF _getc
fgetc MOV BX,SP
MOV SI,[BX][%PARM1-2]
TEST SI,SI
JZ ENDFL
;
; if (fp == NULL || !fp->file.init || !fp->file.openflg) return EOF;
;
; TEST SI,SI ; File ok?
; JZ ENDFL
; CMP %[SI][%FD$INIT],%0
; JZ ENDFL
; CMP %[SI][%FD$OPEN],%0
; JZ ENDFL
;
; if (fp->file.dirty & fdwrite) {
; }
;
TEST %[SI][%FD$DIRTY],%FL$WRITE
JNZ FLUSH
;
; if (fp->file.count) {
; c = *(fp->file.ptr++);
; fp->file.count--; }
;
NOFLUSH MOV CX,[SI][%FD$COUNT]
JCXZ NEEDMORE
DEC CX
MOV [SI][%FD$COUNT],CX
MOV BX,[SI][%FD$PTR]
MOV AL,[BX]
XOR AH,AH
INC BX
MOV [SI][%FD$PTR],BX
;
; if (fp->file.flags & fdbinary) return c;
;
OK TEST %[SI][%FD$FLAGS],%FL$BIN
JNZ DONE
;
; while (c == RETURN && (fp->file.flags & fdfilter)) c = _getc(fp);
;
NOTBIN TEST %[SI][%FD$FLAGS],%FL$LFEED
JZ NOTCR
NEXTCR CMP AX,>000D
JNZ NOTCR
PUSH SI
CALLFAR _getc
POP SI
JMPS NEXTCR
;
; if (c == 0x1a && (fp->file.flags & fdctlz)) return EOF;
;
NOTCR CMP AX,>001A
JNZ NOTCTLZ
TEST %[SI][%FD$FLAGS],%FL$CTLZ
JZ NOTCTLZ
ENDFL MOV AX,-1
RETFAR
;
; else return c;
;
DONE EQU $
NOTCTLZ RETFAR
;
; else c = _getc(fp);
;
NEEDMORE PUSH SI
CALLFAR _getc
POP SI
JMPS OK
;
; if (_fflush(fp) != 0) return EOF;
;
FLUSH PUSH SI
CALLFAR _fflush
POP SI
TEST AX,AX
JNZ ENDFL
JMPS NOFLUSH
END
;
; ------------------------------------------------------------
; _getc(fp)
; FILE *fp;
;
IDT _getc
DEF _getc
REF $$UBCON
REF _fileerr
_getc MOV BX,SP
MOV SI,[BX][%PARM1-2]
;
; if (fp->file.count--) return *(fp->file.ptr++);
;
MOV CX,[SI][%FD$COUNT]
JCXZ NEEDMORE
DEC CX
MOV [SI][%FD$COUNT],CX
MOV BX,[SI][%FD$PTR]
MOV AL,[BX]
XOR AH,AH
INC BX
MOV [SI][%FD$PTR],BX
RETSEG
;
;
; if ((device = fp->file.device) == 'c' || device == 'i') {
;
NEEDMORE MOV AL,[SI][%FD$DEV]
CMP AL,'c'
JZ CONSOLE
CMP AL,'i'
JNZ FILE
;
; if ((fp->file.flags & fdecho) || ($$UBCON & 2))
; return _sys_al(0x0700);
;
CONSOLE TEST %[SI][%FD$FLAGS],%FL$ECHO
JNZ NOECHO
TEST %[$$UBCON],%>02
JZ ECHO
NOECHO MOV AX,>0700
CONDIR INT >21
XOR AH,AH
RETSEG
;
; if ((fp->file.flags & fdunbufr) || ($$UBCON & 1))
; return _sys_al(0x0100);
;
ECHO TEST %[SI][%FD$FLAGS],%FL$UNBUF
JNZ UNBUFR
TEST %[$$UBCON],%>01
JZ FILE
UNBUFR MOV AX,>0100
JMPS CONDIR
;
; if (fp->file.flags & fdunbufr) {
;
FILE TEST %[SI][%FD$FLAGS],%FL$UNBUF
JZ USEBUFR
;
; Read one character (unbuffered)
; if (_sysabcd(0x3f00,handle,1,&c,&fp->file.count) != 0) {
; (*_fileerr)(fp->file.count,fp);
; fp->file.count = 0;
; return EOF; }
;
MOV BX,[SI][%FD$HNDL]
MOV CX,1
SUB SP,%2
MOV DX,SP
MOV AX,>3F00
INT >21
JNB READOK
MOV BX,SP
PUSH [BX][%PARM1]
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%6
MOV AX,-1
RETSEG
;
; else {
; if (fp->file.count) return c;
;
READOK TEST AX,AX
JZ ATEND
POP AX
XOR AH,AH
RETSEG
;
; else {
; fp->file.eofflag = 1;
; return EOF; } } }
;
ATEND POP AX
FILEEND MOV BX,SP
MOV SI,[BX][%PARM1-2]
MOV %[SI][%FD$EOF],%1
ENDFL MOV AX,-1
RETSEG
;
; fp->file.ptr = fp->file.bufr;
; if (_sysabcd(0x3f00,handle,fp->file.bufsize,
; fp->file.bufr,&fp->file.count) != 0) {
;
USEBUFR MOV DX,[SI][%FD$BUFR]
MOV [SI][%FD$PTR],DX
MOV AX,>3F00
MOV BX,[SI][%FD$HNDL]
MOV CX,[SI][%FD$BUFSZ]
INT >21
JNB READOK2
;
; (*_fileerr)(fp->file.count,fp);
; fp->file.count = 0;
; return EOF; }
;
MOV BX,SP
PUSH [BX][%PARM1-2]
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%4
JMPS ENDFL
READOK2 MOV CX,AX
JCXZ FILEEND
;
; fp->file.dirty = fdread;
;
MOV BX,SP
MOV SI,[BX][%PARM1-2]
OR %[SI][%FD$DIRTY],%FL$READ
;
; if (fp->file.count--) return *(fp->file.ptr++);
;
DEC CX
MOV [SI][%FD$COUNT],CX
MOV BX,[SI][%FD$PTR]
MOV AL,[BX]
XOR AH,AH
INC BX
MOV [SI][%FD$PTR],BX
RETSEG
;
; else {
; fp->file.count = 0;
; fp->file.eofflag = 1;
; return EOF;
; }
;
END

50
Mix Power C v1/GETS.C Normal file
View File

@ -0,0 +1,50 @@
/* String input from files */
/* Copyright (c) Mix Software 1988 */
/* ------------------------------------------------------------ */
char *gets(s) /* reads one line from stdin */
char *s; /* into string s */
/* newline replaced by '\0' */
{
int c;
char *sp;
sp = s;
while ((c = fgetc(stdin)) != EOF && c != NEWLINE) *sp++ = c;
*sp = NULL;
if ((c == EOF) && (sp == s)) return NULL;
return s;
}
/* ------------------------------------------------------------ */
char *fgets(s, n, fp) /* read a line from fp */
char *s; /* into s */
int n; /* maximum characters */
FILE *fp; /* is n-1 */
{
int c;
char *sp;
sp = s;
if (n <= 0) return NULL;
while (--n && (c = fgetc(fp)) != EOF && c != NEWLINE) *sp++ = c;
if (c == NEWLINE && n) *sp++ = c;
*sp = NULL;
if ((c == EOF) && (sp == s)) return NULL;
return s;
}
/* ------------------------------------------------------------ */
char *cgets(s) /* reads one line from console */
char *s; /* into string s */
/* newline replaced by '\0' */
{
int status;
int _sys_ad();
_sys_ad(0x0a00,s,&status);
*(s + (int)*(s+1)+2) = '\0';
return s+2;
}

582
Mix Power C v1/GRAPHICS.C Normal file
View File

@ -0,0 +1,582 @@
/* Graphics functions */
/* Copyright (c) Mix Software 1988 */
#define NULL 0
#define HERCMODE 99
#define CGAHIGH 6
#define CGALOW 4
#define CGALOWBW 5
#define PENCOLOR 0xff
#define TRANSPARENT 0xfe
struct vconfig {
int xpixels; /* number of pixels in x direction */
int ypixels; /* number of pixels in y direction */
int textcols; /* number of text columns */
int textrows; /* number of text rows */
int colors; /* number of colors */
int bitsperpixel; /* number of bits for each pixel */
int pages; /* number of video pages */
int colormask; /* value to & with color for bitsperpixel */
int aspect_v; /* aspect ratio of screen is: */
int aspect_h; /* aspect_v/aspect_h */
/* ie y = aspect_v/aspect_h * y0 for 1:1 */
};
struct fillpattern {
int width;
int height;
char *pattern;
};
/* ------------------------------------------------------------ */
/* Pie chart */
/* Create a pie chart from a set of values. Each value in the array */
/* determines the relative area of the pie. The pie is drawn as a */
/* circle in the current pen color. Each segment is bounded by a */
/* solid line in the current pen color. Each segment is filled using*/
/* an array of pattern pointers to determine the fill values. */
/* The center of the pie is at the current graphics cursor. */
/* Note: pie changes both the line style and the fill style. */
int pie(radius,data,datasize,patterns)
int radius; /* radius of the circle */
double *data; /* values to determine the size of each section */
int datasize; /* number of sections in the pie */
struct fillpattern *patterns;
{
extern int _v_color; /* pen color */
extern int _vxcurs, _vycurs;
extern struct vconfig _vconfig;
extern double sin(), cos();
double total;
double *dataptr;
double angle, section_width;
double aspect;
long s, c;
static double twopi = 6.283185307179586;
static double pi4 = 0.7853981633974483096;
int center_x, center_y;
int i, r, x, y, color;
getvconfig(&_vconfig);
color = _v_color & _vconfig.colormask;
center_x = _vxcurs;
center_y = _vycurs;
if (datasize <= 0 || datasize > radius) return -1;
if (patterns == NULL) return -1;
circle(radius,_v_color);
aspect = (double) _vconfig.aspect_v / (double) _vconfig.aspect_h;
move_to(center_x,center_y); /* first boundary */
line_style(&_v_color,1); /* solid lines in pen color */
line_to(center_x+radius,center_y);
for (i = 0, dataptr = data, total = 0.0; i < datasize; ++i)
total += *dataptr++;
for (i = 0, dataptr = data, angle = 0.0; i < datasize; ++dataptr, ++i) {
section_width = (*dataptr * twopi)/total;
angle += section_width;
move_to(center_x,center_y);
line_to(center_x + (int)(radius*cos(angle)+0.5),
center_y + (int)(radius*sin(angle)*aspect+0.5) );
fill_style(patterns->pattern,patterns->width,patterns->height);
patterns++;
r = radius;
/* locate an interior point to start filling */
section_width /= 2.0;
c = 32768. * cos(angle-section_width);
s = 32768. * sin(angle-section_width) * aspect;
if ((section_width > pi4) || (2.0 * radius * sin(section_width) >= 3.0)) {
while (--r > 1) { /* find interior point to fill */
x = center_x + ((r * c + 16384) >> 15);
y = center_y + ((r * s + 16384) >> 15);
if (readdot(y,x) != color) {
move_to(x,y);
fill(_v_color);
r = -1;
}
}
}
}
return 0;
}
/* ------------------------------------------------------------ */
/* Set the current pen color. The color is used for set_pixel. */
/* In line drawing, if any part of the pattern is set to PENCOLOR */
/* the current pen color is used. */
int pen_color(newcolor)
int newcolor;
{
extern int _v_color;
int oldcolor;
oldcolor = _v_color;
_v_color = newcolor;
return oldcolor;
}
/* ------------------------------------------------------------ */
/* Draw a rectangle of the specified size starting with the */
/* current graphics cursor as the upper left corner. The */
/* graphics cursor is unchanged. */
int box(x_size, y_size, fillflag)
int x_size; /* size of the box in the horizontal direction */
int y_size; /* size of the box in the vertical direction */
int fillflag; /* non-zero if box is to be filled */
{
if (x_size < 0) { move_by(x_size+1,0); x_size = -x_size; }
if (y_size < 0) { move_by(0,y_size+1); y_size = -y_size; }
line_by(0,y_size-1);
line_by(x_size-1,0);
line_by(0,-y_size+1);
line_by(-x_size+1,0);
if (fillflag) {
if (x_size > 2 && y_size > 2) {
move_by(1,1);
flood(x_size-2,y_size-2);
}
}
}
/* ------------------------------------------------------------ */
/* Draw a line from the current cursor for a specified distance. */
int line_by(x_offset, y_offset)
int x_offset; /* distance in x (horizonal) direction */
int y_offset; /* distance in y (vertical) direction */
{
extern int _vxcurs, _vycurs;
return line_to(_vxcurs+x_offset,_vycurs+y_offset);
}
/* ------------------------------------------------------------ */
/* Draw a line from the current cursor to the specified end */
/* point. The line style is in the external variable _vl_pat.*/
/* The pattern is repeated as necessary */
int line_to(x_end, y_end)
int x_end, y_end; /* end of line coordinate */
{
extern int _vl_psiz;
extern char *_vl_pat;
extern int _vxcurs, _vycurs;
extern int _v_color;
int t;
int x, y;
int x_start, y_start;
int d, incr1, incr2, dx, dy, delta;
int *xp = &x, *yp = &y; /* pointers to coordinates */
char *pat, *patlimit;
x_start = _vxcurs; _vxcurs = x_end;
y_start = _vycurs; _vycurs = y_end;
dy = (y_end > y_start) ? (y_end-y_start) : (y_start-y_end);
dx = (x_end > x_start) ? (x_end-x_start) : (x_start-x_end);
if (dy > dx) { /* slope greater than 1 */
t = y_end; y_end = x_end; x_end = t; /* swap */
t = y_start; y_start = x_start; x_start = t;
xp = &y; yp = &x;
}
if (x_start > x_end) { /* start with smaller coordinate */
t = x_end; x_end = x_start; x_start = t;
t = y_end; y_end = y_start; y_start = t;
}
dx = x_end-x_start;
delta = 1;
if (y_end > y_start) dy = y_end - y_start;
else {
dy = y_start-y_end;
delta = -1;
}
d = dy+dy - dx;
incr1 = dy+dy;
incr2 = incr1-dx-dx;
x = x_start; y = y_start;
pat = _vl_pat;
patlimit = _vl_pat + _vl_psiz;
do {
writedot(*yp,*xp,*pat);
++x;
if (d < 0) d += incr1;
else { y += delta; d += incr2; }
if (++pat >= patlimit) pat = _vl_pat;
} while (x <= x_end);
}
/* ------------------------------------------------------------ */
/* move graphics cursor to a specified coordinate */
int move_to(x,y)
int x; /* move graphics cursor */
int y;
{
extern int _vxcurs, _vycurs;
_vxcurs = x;
_vycurs = y;
}
/* ------------------------------------------------------------ */
/* move graphics cursor by a specified offset */
int move_by(x,y)
int x; /* move graphics cursor by a specified offset */
int y;
{
extern int _vxcurs, _vycurs;
_vxcurs += x;
_vycurs += y;
}
/* ------------------------------------------------------------ */
/* Set the style of lines. */
int line_style(colors, size)
char *colors; /* List of colors for each unit of line */
int size; /* Size of a unit (colors for each repetition) */
{
extern char *_vl_pat;
extern int _vl_psiz;
_vl_pat = colors;
_vl_psiz = size;
}
/* ------------------------------------------------------------ */
/* Draw a circle with center at (x,y) and given radius */
circle(radius,color)
int radius;
int color;
{
int x, y, d;
extern struct vconfig _vconfig;
getvconfig(&_vconfig);
x = 0;
y = radius;
d = 3 - radius+radius;
while (x < y) {
_cpoint(x,y,color);
if (d < 0) d = d + 4*x + 6;
else {
d = d + 4*(x - y) + 10;
y -= 1;
}
++x;
}
if (x == y) _cpoint(x,y,color);
}
/* ------------------------------------------------------------ */
/* Draw the 8 symetric points on a circle. The y coordinate */
/* is scaled according to the aspect ratio of the screen. */
_cpoint(x,y,color)
int x,y; /* coordinate of point in 45 to 90 degree region */
{
extern int _vxcurs,_vycurs; /* coordinate of center of circle */
extern struct vconfig _vconfig;
int x3, y3;
int round;
round = _vconfig.aspect_h >> 1;
y3 = (y * _vconfig.aspect_v + round) / _vconfig.aspect_h;
x3 = (x * _vconfig.aspect_v + round) / _vconfig.aspect_h;
writedot(_vycurs+y3, _vxcurs+x, color);
writedot(_vycurs+x3, _vxcurs+y, color);
writedot(_vycurs-x3, _vxcurs+y, color);
writedot(_vycurs-y3, _vxcurs+x, color);
writedot(_vycurs-y3, _vxcurs-x, color);
writedot(_vycurs-x3, _vxcurs-y, color);
writedot(_vycurs+x3, _vxcurs-y, color);
writedot(_vycurs+y3, _vxcurs-x, color);
}
/* ------------------------------------------------------------ */
/* Draw an ellipse with center at (x,y). The ellipse is */
/* drawn in display coordinates. There is no compensation */
/* for the aspect ratio of the screen. */
ellipse(x_radius,y_radius,color)
int x_radius; /* axis size in x direction */
int y_radius; /* axis size in y direction */
int color;
{
extern int _vxcurs,_vycurs; /* coordinate of center */
int x = _vxcurs;
int y = _vycurs;
int x0, y0, d, t;
int reverse = 0;
if (x_radius < y_radius) {
t = x; x = y; y = t;
t = x_radius; x_radius = y_radius; y_radius = t;
reverse = 1;
}
x0 = 0;
y0 = x_radius;
d = 3 - x_radius+x_radius;
while (x0 < y0) {
_epoint(x0,y0,x,y,color,x_radius,y_radius,reverse);
if (d < 0) d = d + 4*x0 + 6;
else {
d = d + 4*(x0 - y0) + 10;
--y0;
}
++x0;
}
if (x0 == y0) _epoint(x0,y0,x,y,color,x_radius,y_radius,reverse);
}
/* ------------------------------------------------------------ */
/* Draw the 8 symetric points on an ellipse. */
_epoint(x,y,x0,y0,color,x_radius,y_radius,reverse)
int x,y; /* coordinate of point in 45 to 90 degree region */
int x0,y0; /* coordinate of center */
int x_radius; /* major axis */
int y_radius; /* minor axis (x_radius >= y_radius) */
int reverse; /* flag to reverse x and y coordinates */
{
long round = x_radius >> 1;
int yy, xx;
int xpos, ypos;
int *xp, *yp;
yy = ((long)y_radius * y + round) / (long) x_radius;
xx = ((long)y_radius * x + round) / (long) x_radius;
if (reverse) { xp = &ypos; yp = &xpos; }
else { xp = &xpos; yp = &ypos; }
ypos = y0 + yy; xpos = x0 + x; writedot(*yp,*xp,color);
ypos = y0 + xx; xpos = x0 + y; writedot(*yp,*xp,color);
ypos = y0 - xx; xpos = x0 + y; writedot(*yp,*xp,color);
ypos = y0 - yy; xpos = x0 + x; writedot(*yp,*xp,color);
ypos = y0 - yy; xpos = x0 - x; writedot(*yp,*xp,color);
ypos = y0 - xx; xpos = x0 - y; writedot(*yp,*xp,color);
ypos = y0 + xx; xpos = x0 - y; writedot(*yp,*xp,color);
ypos = y0 + yy; xpos = x0 - x; writedot(*yp,*xp,color);
}
/* ------------------------------------------------------------ */
/* Set the pattern for filling areas */
int fill_style(colors, width, height)
char *colors; /* 2D array of colors to form fill pattern */
int width; /* Width of fill pattern */
int height; /* Height of fill pattern */
{
extern char *_vf_pat;
extern int _vf_wid, _vf_hgt;
_vf_pat = colors;
_vf_wid = width;
_vf_hgt = height;
}
/* ------------------------------------------------------------ */
/* Fill a bounded area with the current fill pattern. */
/* The area is enclosed by the boundary color. If the boundary*/
/* color does not form an enclosed area, the fill will "leak */
/* through" any holes and result in filling the entire screen. */
int fill(boundary_color)
int boundary_color;
{
extern int _vxcurs; /* graphics cursor */
extern int _vycurs;
extern char *_vf_pat; /* fill pattern */
extern int _vf_wid, _vf_hgt; /* pattern dimensions */
extern int _v_color; /* pen color */
extern int _vbcolor; /* color of boundary */
extern int _vminh, _vmaxh; /* horizontal screen boundaries */
extern int _vminv, _vmaxv; /* vertical screen boundaries */
extern int _vmode; /* screen mode */
extern int _vusemem; /* direct memory access */
extern struct vconfig _vconfig;
if (boundary_color == PENCOLOR) boundary_color = _v_color;
getvconfig(&_vconfig);
boundary_color = boundary_color & _vconfig.colormask;
if (_vxcurs < _vminh) return -1; /* start point out of window */
if (_vxcurs > _vmaxh) return -1;
if (_vycurs < _vminv) return -1;
if (_vycurs > _vmaxv) return -1;
if (readdot(_vycurs,_vxcurs) == boundary_color) return -1;
if (_vusemem) {
if (_vmode == HERCMODE) return _fill_pm(boundary_color);
if (_vmode == CGAHIGH) return _fill_pm(boundary_color);
if (_vmode == CGALOW) return _fill_pm(boundary_color);
if (_vmode == CGALOWBW) return _fill_pm(boundary_color);
}
_vbcolor = boundary_color;
return _fill_p(_vxcurs,_vycurs,NULL); /* fill with pattern */
}
struct _fill_chain {
int y; /* vertical coordinate at previous level */
int xmin; /* start of run */
int xmax; /* end of run */
struct _fill_chain *next; /* next level */
};
/*$STACKCHK*/
/* ------------------------------------------------------------ */
/* Recursive fill area with pattern. Due to the pattern, the */
/* areas that have already been filled are not distinguishable */
/* from areas that have not been touched. The previously */
/* visited areas are chained together via the stack. There */
/* is an explicit check for previously visited areas. This */
/* test is necessary to allow for filling areas that contain */
/* holes. */
int _fill_p(x,y,previous)
int x, y; /* coordinate of starting point */
struct _fill_chain *previous; /* link to previous line in the pattern */
{
struct _fill_chain thisrow;
extern char *_vf_pat; /* fill pattern */
extern int _vf_wid, _vf_hgt; /* pattern dimensions */
extern int _vbcolor; /* color of boundary */
extern int _vminh, _vmaxh; /* horizontal screen boundaries */
extern int _vminv, _vmaxv; /* vertical screen boundaries */
int xmax; /* rightmost edge of fill on this line */
int xmin; /* left edge of fill on this line */
static char *xlimit; /* maximum pointer to pattern */
static char *xstart; /* origin of this row of pattern */
static char *p; /* fill pattern pointer */
int nextx, nexty; /* next row coordinates */
static int dot;
int incr;
struct _fill_chain *prior;
xstart = _vf_pat + _vf_wid * (y % _vf_hgt);
xlimit = xstart + _vf_wid;
p = xstart + (x % _vf_wid); /* initial pattern pointer */
/* set dots to left of start point until boundary reached */
xmin = x;
p = xstart + (xmin % _vf_wid); /* initial pattern pointer */
while ((xmin >= _vminh) && (readdot(y,xmin) != _vbcolor)) {
writedot(y,xmin,*p);
--xmin;
if (--p < xstart) p = xlimit-1;
}
/* set dots to right of start point until boundary reached */
xmax = x+1;
p = xstart + (xmax % _vf_wid); /* initial pattern pointer */
while ((xmax <= _vmaxh) && (readdot(y,xmax) != _vbcolor)) {
writedot(y,xmax,*p);
++xmax;
if (++p >= xlimit) p = xstart;
}
/* save current line for use as a stop */
thisrow.y = y;
thisrow.xmin = xmin;
thisrow.xmax = xmax;
thisrow.next = previous;
/* Expand vertically */
for (incr = -1; incr <= 1; incr+=2) {
nexty = y + incr;
if (nexty >= _vminv && nexty <= _vmaxv) {
nextx = xmin;
while (nextx < xmax) {
do /* scan past boundary areas on line above or below */
dot = readdot(nexty,++nextx);
while ((dot == _vbcolor) && nextx < xmax);
/* skip the group that we came from */
if (nextx < xmax && dot != _vbcolor) {
prior = previous;
while (prior != NULL) {
if (prior->y == nexty) {
if (nextx > prior->xmin && nextx < prior->xmax) {
/* already done */
nextx = prior->xmax-1;
dot = _vbcolor;
prior = NULL;
}
else prior = prior->next;
}
else prior = prior->next;
}
if (dot != _vbcolor) nextx = _fill_p(nextx,nexty,&thisrow);
}
}
}
}
return xmax;
}
/* ------------------------------------------------------------ */
/* return configuration data for the screen. */
getvconfig(config)
struct vconfig *config;
{
static struct vconfig cfgtable[17] =
{{ 0, 0, 40, 25,16, 8, 8, 0xff, 10, 12 }, /* 40 x 25 text BW */
{ 0, 0, 40, 25,16, 8, 8, 0xff, 10, 12 }, /* 40 x 25 text color */
{ 0, 0, 80, 25,16, 8, 4, 0xff, 10, 24 }, /* 80 x 25 text BW */
{ 0, 0, 80, 25,16, 8, 4, 0xff, 10, 24 }, /* 80 x 25 text color */
{320,200, 0, 0, 4, 2, 1, 0x03, 10, 12 }, /* 320 x 200 graphics */
{320,200, 0, 0, 4, 2, 1, 0x03, 10, 12 }, /* 320 x 200 BW */
{640,200, 0, 0, 2, 1, 1, 0x01, 10, 24 }, /* 640 x 200 graphics */
{ 0, 0, 80, 25,16, 8, 1, 0xff, 10, 24 }, /* monochrome */
{160,200, 0, 0,16, 4, 1, 0x0f, 20, 12 }, /* 160 x 200 pc jr */
{320,200, 0, 0,16, 4, 1, 0x0f, 10, 12 }, /* 320 x 200 pc jr */
{640,200, 0, 0, 4, 2, 1, 0x03, 10, 12 }, /* 640 x 200 pc jr */
{ 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0 }, /* undefined */
{ 0, 0, 0, 0, 0, 0, 0, 0x00, 0, 0 }, /* undefined */
{320,200, 0, 0,16, 4, 8, 0x0f, 10, 12 }, /* 320 x 200 EGA */
{640,200, 0, 0,16, 4, 4, 0x0f, 10, 24 }, /* 640 x 200 EGA */
{640,350, 0, 0, 2, 1, 1, 0x01, 35, 48 }, /* 640 x 350 BW EGA */
{640,350, 0, 0,16, 4, 1, 0x0f, 35, 48 } /* 640 x 350 EGA */
{640,480, 0, 0, 2, 1, 1, 0x01, 2, 2 } /* 640 x 480 VGA, MCGA */
{640,480, 0, 0,16, 4, 1, 0x0f, 2, 2 } /* 640 x 480 VGA */
{320,200, 0, 0,256,8, 1, 0xff, 2, 2 } /* 320 x 200 VGA, MCGA */
};
static struct vconfig herccfg =
{720,348, 0, 0, 2, 1, 2, 0x1, 2, 3 }; /* Hercules BW */
int mode;
mode = getvmode();
if (mode == HERCMODE) memcpy(config,herccfg,sizeof(struct vconfig));
else if (mode <= 16) memcpy(config,&cfgtable[mode],sizeof(struct vconfig));
else memset(config,0,sizeof(struct vconfig));
}
plots(s)
char *s;
{
if (s != NULL) {
while (*s != '\0') plotch(*s++);
}
return s;
}
setpixel(x, y)
int x, y;
{
extern int _v_color;
writedot(y,x,_v_color);
}
int getpixel(x, y)
int x, y;
{
return readdot(y,x);
}
int setapage(page) /* set active page */
int page;
{
extern int _vapage;
int oldpage = _vapage;
_vapage = page;
return oldpage;
}
int _vbcolor; /* boundary color for fill */
struct vconfig _vconfig; /* screen configuration */

380
Mix Power C v1/INIT.ASM Normal file
View File

@ -0,0 +1,380 @@
;
; Initialize the runtime environment.
; The block at $$Link$$ contains parameters passed from
; the linker.
;
; Determine memory bounds. Create stack and heap. Initialize
; fundamental parameters.
;
;
BUFSIZ EQU >200
FALSE EQU 0
TRUE EQU ~FALSE
ENVIR EQU >2C
DOS EQU >21
MARGIN EQU >80
OP$EXIT EQU >4C
OP$PMSG EQU >09
OP$VERS EQU >30
OP$TIME EQU >2C
OP$DATE EQU >2A
CMDLINE EQU >80
CMDLENGTH EQU >80
ARGV0LEN EQU 64
LONGNAME EQU >FFFF
SHORTNAM EQU >FFFF
CASE TRUE
;
IDT $_INIT_$
DEF $_INIT_$
DEF $_init_$
DEF $$RETURN
$_init_$ equ $
$_INIT_$ MOV AX,DS
MOV ES,AX
MOV BX,SS
MOV DS,BX
MOV [$$PSP],AX
SEGES
MOV AX,[ENVIR]
MOV [$$ENVIR],AX
MOV AH,OP$VERS ; Dos version number
INT DOS
MOV [_osmajor],AX
CMP AL,3 ; If 3.0 or greater
JB GETTIME
MOV ES,[$$ENVIR] ; scan environment for argv[0]
XOR DI,DI
MOV AL,%0
MOV CX,-1
CLD
ENVNEXT SEGES
CMP %[DI],%0 ; end of table?
JZ ENDENV
REPNZ
SCASB
JMPS ENVNEXT
ENDENV INC DI ; skip terminator
SEGES
CMP [DI],1
JNZ GETTIME ; no argv[0]
ADD DI,%2
MOV SI,$$ARGV0
MOV CX,ARGV0LEN/2
CPYARG0 SEGES
MOV AX,[DI]
MOV [SI],AX
ADD DI,%2
ADD SI,%2
LOOP CPYARG0
GETTIME MOV AH,OP$DATE
INT DOS
MOV [$$CLOCK],CX
MOV [$$CLOCK2],DX
MOV AH,OP$TIME
INT DOS
MOV [$$CLOCK4],CX
MOV [$$CLOCK6],DX
MOV ES,[$$PSP]
SEGES
MOV SI,[2] ; Top of available memory
MOV [$$MAXSEG],SI
MOV DX,DS
SUB SI,DX
CMP SI,>1000 ; More than 64k available?
JAE DS64K
MOV CL,4
SHL SI,CL
DEC SI
JMPS DSSET
DS64K MOV SI,>FFFF
DSSET MOV BX,[DSSIZE] ; Size of initialized data
ADD BX,MARGIN
MOV [$$LIMIT],BX ; Lower limit of stack
MOV AX,[STKSIZE]
TEST AX,AX ; Zero means default
JNZ STACKVAL
MOV AX,[HPSIZE] ; Check heap size
TEST AX,AX
JNZ HPSET
MOV AX,SI
SUB AX,BX
SHR AX,1 ; Half of memory for stack
SUB AX,2
AND AX,>FFFE
MOV [STKSIZE],AX
MOV [HPSIZE],AX
JMPS STACKSET
STACKVAL TEST [HPSIZE],>FFFF
JNZ STACKSET
MOV CX,SI
SUB CX,AX
JB NOMEM1
SUB CX,BX
JB NOMEM1
DEC CX
JB NOMEM1
AND CX,>FFFE
MOV [HPSIZE],CX
JMPS STACKSET
HPSET MOV CX,SI
SUB CX,AX
JB NOMEM1
SUB CX,BX
JB NOMEM1
DEC CX
AND CX,>FFFE
JNB MEMOK
NOMEM1 JMP NOMEM
MEMOK MOV [STKSIZE],CX
MOV AX,CX
STACKSET ADD BX,AX
JB NOMEM1
CMP BX,SI ; Enough memory available
JA NOMEM1
MOV [$$BOTTOM],BX ; Top limit of stack
MOV [$$MAXS],BX ; Maximum stack used
INC BX
AND BX,>FFFE
POP AX ; Copy return address
POP CX ; to new stack
MOV SP,BX ; Set stack location for program
MOV DX,CS
PUSH DX ; Set final return address
MOV [$$RETIS],DX
MOV DX,$$RETURN
PUSH DX
MOV [$$RETI],DX
MOV BP,SP ; Initial frame
PUSH CX ; Save return to program
PUSH AX
MOV AX,DS ; initialize to zero
MOV ES,AX
MOV DI,[$$LIMIT]
MOV CX,SP
SUB CX,256
SUB CX,DI
SHR CX,1
XOR AX,AX
REP
STOSW
;
; Create heap
;
INC BX ; Start heap on word boundary
AND BX,>0FFFE
MOV [$$HMIN],BX
XOR AX,AX
MOV [$$CURH],AX ; No heap used
MOV [$$MAXH],AX
ADD BX,[HPSIZE]
JZ ALLMEM
JB NOMEM1
JMPS MAKEHEAP
ALLMEM MOV BX,>FFFE
MAKEHEAP AND BX,>FFFE ; Make top of heap a word boundary
MOV [$$HMAX],BX ; STORE HEAP LIMIT
MOV AX,BX
DEC AX ; round up with top-16+15
MOV CL,4
SHR AX,CL
INC AX ; add back the 16
MOV DX,DS
ADD AX,DX
MOV [$$TOPSEG],AX ; First unused extra memory
MOV [$$ENDDS],AX ; Segment of end of ds
SUB AX,DX
SHL AX,CL
MOV [$$TOPDS],AX ; Top of data segment
ADD BX,-6 ; RESERVE DUMMY PACKET
MOV CX,BX ; SAVE POINTER TO DUMMY
MOV DX,BX ; SAVE POINTER TO DUMMY
MOV [BX],0 ; LENGTH OF DUMMY PACKET
MOV AX,[$$HMIN] ; AX=ADDRESS OF INITIAL HEAP
MOV [BX][%2],AX ; SET NEXT PACKET PTR
MOV [BX][%4],AX ; SET PREDECESSOR PTR
;
; SET LENGTH OF INITIAL HEAP PACKET
;
SUB CX,AX ; CALCULATE HEAP SIZE
MOV [$$FREE],AX
MOV BX,AX ; POINT TO BIG HEAP PACKET
MOV [BX],CX ; SET HEAP SIZE
MOV [BX][%2],DX ;NEXT IS DUMMY PACKET
MOV [BX][%4],DX ;PREDECESSOR IS DUMMY PACKET
;
; COPY COMMAND LINE TO DATA SEGMENT
;
MOV SI,CMDLINE
MOV ES,[$$PSP]
SEGES
MOV CL,[SI] ; Length of command line
CMP CL,5
JB COPYALL ; Too short for trace
SEGES
CMP %[SI][%1],%>0D
JNZ COPYALL ; Not trace
SEGES
MOV AX,[SI][%2]
MOV [$$XTRC],AX
SEGES
MOV AX,[SI][%4]
MOV [$$XTRC2],AX
PUSH AX
PUSH [$$XTRC]
SUB CL,%5
ADD SI,%5
SEGES
MOV %[SI],CL
COPYALL MOV DI,$$CMDLIN
MOV CX,CMDLENGTH/2
MOV AX,DS
MOV ES,AX
MOV DS,[$$PSP]
COPYCMD REP
MOVSW
MOV AX,ES
MOV DS,AX
MOV ES,[$$PSP]
XOR BX,BX
RETSEG
;
$$RETURN MOV AX,[$$EXSTAT]
TEST AH,AH
JZ STOP
MOV AL,%>FF
STOP CMP [$$XTRC2],0
JZ NOTRC
MOV BX,1
CALLSEG [$$XTRC]
NOTRC MOV AH,OP$EXIT
INT DOS
NOMEM MOV DX,NOMEMMSG
MOV AH,OP$PMSG
INT DOS
MOV AL,%>FE
JMPS STOP
;
; Data areas.
; $$Link$$ contains information supplied by the linker.
; $$PROCES contains control and status information used
; by the program.
;
DORG 0
;
; Process control record. Contains status values, limits and
; runtime flags
;
$$PROCES EQU $
$$EXITPT DW $$RETI ; Exit address
$$BOTTOM DW 0 ; Stack bottom (empty stack)
$$LIMIT DW 0 ; Stack limit (full stack)
$$HMIN DW 0 ; Lower bound of heap
$$HMAX DW 0 ; Upper bound of heap
$$FREE DW 0 ; Free space pointer for heap
$$MAXS DW 0 ; Maximum stack used
$$MAXH DW 0 ; Maximum heap used
$$CURH DW 0 ; Current heap used
$$IOTERM DB 0 ; Terminate on io error
$$HPTERM DB 0 ; Terminate on heap full
$$IOFLG DB 0 ; IO default flags
$$ZFILL DB 0 ; Zero locals & heap packets flag
$$FATAL DW 0 ; Fatal error address
DW 0 ; Fatal error address (segment)
$$CMDPTR DW $$CMDLIN ; Address of command line
$$LIOERR DW 0 ; File for last io error
_psp EQU $
$$PSP DW 0 ; Program segment prefix segment
$$ENVIR DW 0 ; Environment segment
$$XTRC DW 0 ; Address of ctrace
$$XTRC2 DW 0 ; Address of ctrace (segment)
DW 0,0,0
;
errno DW 0 ; Error number
_doserrn DW 0 ; Operating system error code
$$FLERR DW 0 ; Floating point error code
$$BUFSIZ DW BUFSIZ ; Default buffer size for files
$$MAXSEG DW 0 ; First unavailable paragraph
$$TOPSEG DW 0 ; First unused paragraph
$$TOPDS DW 0 ; Top address in data segment
$$ENDDS DW 0 ; Segment of end of data segment
$$EXSTAT DW 0 ; Exit status
$$MACHIN DB 0
$$OPSYS DB >20
$$SHMSG DB 0 ; Display statistics
$$CLFEED DB 1 ; Filter line feeds (default)
$$CCTLZ DB 0 ; Treat ctl/z as end of file (default)
$$STATSV DB 0
$$UBCON DB 0 ; Unbuffered console
$$ARTERM DB 0 ; Terminate on arithmetic errors
$$RETI DW 0 ; Far address of exit routine
$$RETIS DW 0
$$CMDLIN DS >80 ; Copy of command line
_osmajor DB 0
_osminor DB 0
$$CLOCK DW 0
$$CLOCK2 DW 0
$$CLOCK4 DW 0
$$CLOCK6 DW 0
$$ARGV0 DB 0
DS ARGV0LEN
NOMEMMSG DB 'Not enough memory$'
DDEF $$Link$$
DORG 2*(($+1)/2)
$$Link$$ EQU $
STKSIZE DW 0 ; Stack size
HPSIZE DW 0 ; Heap size
DSSIZE DW 0 ; Size of initialized data
DW 0,0,0,0,0 ; Filler for more parameters
DW 0,0,0,0,0,0,0,0
DDEF $$EXITPT
DDEF $$BOTTOM
DDEF $$LIMIT
DDEF $$HMIN
DDEF $$HMAX
DDEF $$FREE
DDEF $$MAXS
DDEF $$MAXH
DDEF $$CURH
DDEF $$IOTERM
DDEF $$HPTERM
DDEF $$IOFLG
DDEF $$ZFILL
DDEF $$FATAL
DDEF $$CMDPTR
DDEF $$LIOERR
DDEF $$PSP
DDEF _psp
DDEF $$ENVIR
DDEF $$XTRC
DDEF $$XTRC2
DDEF errno
IF SHORTNAM
DDEF _doserrn
ENDIF
IF LONGNAME
LDDEF _doserrno
ENDIF
DDEF $$FLERR
DDEF $$BUFSIZ
DDEF $$MAXSEG
DDEF $$TOPSEG
DDEF $$TOPDS
DDEF $$ENDDS
DDEF $$EXSTAT
DDEF $$MACHIN
DDEF $$OPSYS
DDEF $$SHMSG
DDEF $$CLFEED
DDEF $$CCTLZ
DDEF $$STATSV
DDEF $$UBCON
DDEF $$ARTERM
DDEF $$RETI
DDEF $$CMDLIN
DDEF _osmajor
DDEF _osminor
DDEF $$CLOCK
DDEF $$ARGV0
END
;

166
Mix Power C v1/INIT.C Normal file
View File

@ -0,0 +1,166 @@
/* Initialization functions. */
/* Copyright (c) Mix Software 1988 */
/* _INITIO is called by the lowest level initialization
function. It is the first C function executed by a program.
_INITIO opens the standard files, creates argv and argc
and calls main.
*/
_INITIO(stdfiles)
int stdfiles; /*stdfiles = 1 says open standard files*/
{
extern char *$$CMDPTR;
extern FILE *_iob[MAXFILES];
extern int (*_fclose)();
extern char $$ARGV0[];
register char *cmdline;
register int count;
static char *argv[MAXARGS]; /*pointers to command line arguments*/
int argc; /*number of command line arguments*/
int quote;
int main();
int exit();
cmdline = $$CMDPTR;
count = *cmdline++;
argv[0] = $$ARGV0;
argc = 1;
while (count > 0 && argc < MAXARGS) {
while (*cmdline == ' ' && count) {
count--;
cmdline++;
}
if (count) {
quote = 0;
argv[argc] = cmdline;
while (count && (*cmdline != ' ' || quote)) {
if (*cmdline == '"') {
if (quote) {*cmdline = ' '; quote = 0; }
else if (argv[argc] == cmdline) {
quote = 1;
cmdline++, count--;
argv[argc] = cmdline;
}
else cmdline++, count--;
}
else if (*cmdline == '\\' && quote) {
memcpy(cmdline,cmdline+1,count);
cmdline++, count--;
if (count) count--;
}
else cmdline++, count--; /* not " or \ */
}
argc++;
*cmdline++ = '\0';
count--;
}
}
exit(main(argc,argv));
_iob[0]; /* These statements look useless but are not. */
_fclose; /* They force these variables to be linked into program */
}
/* _INITIO3 is called if main requires 3 arguments. In addition to
the functions performed by _INITIO, it also creates the environment
and passes envp to main.
*/
_INITIO3(stdfiles)
int stdfiles; /*stdfiles = 1 says open standard files*/
{
extern char *$$CMDPTR;
extern char *(*environ)[];
extern FILE *_iob[MAXFILES];
extern int (*_fclose)();
extern char $$ARGV0[];
register char *cmdline;
register int count;
char *argv[MAXARGS]; /*pointers to command line arguments*/
int argc; /*number of command line arguments*/
int quote;
int main();
int exit();
cmdline = $$CMDPTR;
count = *cmdline++;
argv[0] = $$ARGV0;
argc = 1;
while (count > 0 && argc < MAXARGS) {
while (*cmdline == ' ' && count) {
count--;
cmdline++;
}
if (count) {
quote = 0;
argv[argc] = cmdline;
while (count && (*cmdline != ' ' || quote)) {
if (*cmdline == '"') {
if (quote) {*cmdline = ' '; quote = 0; }
else if (argv[argc] == cmdline) {
quote = 1;
cmdline++, count--;
argv[argc] = cmdline;
}
else cmdline++, count--;
}
else if (*cmdline == '\\' && quote) {
memcpy(cmdline,cmdline+1,count);
cmdline++, count--;
if (count) count--;
}
else cmdline++, count--; /* not " or \ */
}
argc++;
*cmdline++ = '\0';
count--;
}
}
getenv("PATH=");
exit(main(argc,argv,environ));
_iob[0];
_fclose;
}
/* standard files */
char _STDINB[128];
FILE _STDFL1, _STDFL2, _STDFL3, _STDFL4, _STDFL5;
FILE *_iob[MAXFILES] = {&_STDFL1, &_STDFL2, &_STDFL3,
&_STDFL4, &_STDFL5};
FILE _STDFL1 = {{'S', '\001', 0, &_STDINB,
&_STDINB, 0, 128, 0,
'i', '\0', '\0', '\0',
'\0', fdfilter+fdsetbuf, '\0', '\0',
0, 0, '\0', "\0\0\0\0" },
0};
FILE _STDFL2 = {{'S', '\001', 1, 0,
0, 0, 0, 0,
'o', '\0', '\001', '\0',
'\0', fdfilter+fdunbufr, '\0', '\0',
0, 0, '\0', "\0\0\0\0" },
1};
FILE _STDFL3 = {{'S', '\001', 2, 0,
0, 0, 0, 0,
'e', '\0', '\001', '\0',
'\0', fdfilter+fdunbufr, '\0', '\0',
0, 0, '\0', "\0\0\0\0" },
2};
FILE _STDFL4 = {{'S', '\001', 3, 0,
0, 0, 0, 0,
'a', '\0', '\001', '\0',
'\0', fdfilter+fdunbufr, '\0', '\0',
0, 0, '\0', "\0\0\0\0" },
3};
FILE _STDFL5 = {{'S', '\001', 4, 0,
0, 0, 0, 0,
'l', '\0', '\001', '\0',
'\0', fdfilter+fdunbufr, '\0', '\0',
0, 0, '\0', "\0\0\0\0" },
4};
extern int _stdclose(); /* Close function for std files only */
int (*_fclose)() = _stdclose;

63
Mix Power C v1/INOUT.ASM Normal file
View File

@ -0,0 +1,63 @@
;
; Copyright (c) Mix Software 1988
;
IDT inp
DEF inp
IF UPPER
DEF INP
ENDIF
inp EQU $
INP MOV BX,SP
MOV DX,[BX][%PARM1-2]
IN AL,DX
XOR AH,AH
RETFAR
END
;
IDT inport
DEF inport
inport MOV BX,SP
MOV DX,[BX][%PARM1-2]
IN AX,DX
RETFAR
END
;
IDT inportb
DEF inportb
inportb MOV BX,SP
MOV DX,[BX][%PARM1-2]
IN AL,DX
XOR AH,AH
RETFAR
END
;
IDT outp
DEF outp
IF UPPER
DEF OUTP
ENDIF
outp EQU $
OUTP MOV BX,SP
MOV DX,[BX][%PARM1-2]
MOV AX,[BX][%PARM2-2]
OUT DX,AL
RETFAR
END
;
IDT outport
DEF outport
outport MOV BX,SP
MOV DX,[BX][%PARM1-2]
MOV AX,[BX][%PARM2-2]
OUT DX,AX
RETFAR
END
;
IDT outportb
DEF outportb
outportb MOV BX,SP
MOV DX,[BX][%PARM1-2]
MOV AX,[BX][%PARM2-2]
OUT DX,AL
RETFAR
END

230
Mix Power C v1/INTENT.ASM Normal file
View File

@ -0,0 +1,230 @@
;
; Copyright (c) Mix Software 1988
;
; Entry from an interrupt
; sets ds and ss to the proper values
; passes registers as arguments
; Called with a far return address followed by an
; interrupt return on the stack. All registers are
; in an unknown state.
;
IDT $_INTENT
DEF $_INTENT
DREF $$LIMIT ; Maximum limit of stack
DREF $$BOTTOM ; Start of stack
FREF $$MAXS
MARGIN EQU >100 ; Minimum stack needed
;
$_INTENT CLI
PUSH AX
MOV AX,SS
SEGCS
CMP AX,[PROGDS]
JNZ DIFFSTK
POP AX ; interrupt uses same stack
PUSH BP ; as the program
MOV BP,SP
XCHG AX,[BP][%4] ; ax = caller cs
XCHG BX,[BP][%2] ; ax = caller ip
POP BP
PUSH CX
PUSH DX
PUSH ES
PUSH DS
PUSH SI
PUSH DI
PUSH BP
MOV CX,CS
PUSH CX ; return to here
MOV CX,RET1
PUSH CX
PUSH AX ; Caller's address
PUSH BX
MOV AX,SS
MOV DS,AX
STI
RETFAR ; Go to caller with parms set
RET1 POP BP
POP DI
POP SI
POP AX
MOV DS,AX
POP AX
MOV ES,AX
POP DX
POP CX
POP BX
POP AX
IRET
;
DIFFSTK POP AX
PUSH DS
SEGCS
MOV DS,[PROGDS]
CLI
POP [SAVEDS]
MOV [SAVEDI],DI
MOV [SAVEAX],AX
MOV [SAVECX],CX
CMP %[STKLOCK],%0
JNZ FINDSTK
MOV %[STKLOCK],%1
MOV DI,[$$LIMIT]
ADD DI,[_INT_STK]
AND DI,>FFFE
MOV AX,SS ; switch stacks
MOV CX,SP
SEGCS
MOV SS,[PROGDS]
MOV SP,DI
MOV DI,CX
MOV DS,AX
MOV CX,RET2
JMPS NEWSTK
;
RET2 CLI
MOV AX,SS
MOV DS,AX
MOV %[STKLOCK],%0
POP BP
POP [SAVEDI]
POP SI
POP [SAVEDS]
POP AX
MOV ES,AX
POP DX
POP CX
POP BX
POP [SAVEAX]
ADD SP,%6 ; Remove cs:ip and flags
POP DI ; Interrupted task's sp
ADD DI,%4 ; Remove return from int function
POP AX ; Interrupted task's ss
MOV SS,AX ; Set to prior stack
MOV SP,DI
MOV AX,[SAVEAX]
MOV DI,[SAVEDI]
MOV DS,[SAVEDS]
IRET
;
; Search for stack space
;
FINDSTK MOV [SAVEES],ES
MOV AX,DS
MOV ES,AX
XOR AX,AX
MOV DI,[$$LIMIT] ; Scan for available stack
ADD DI,[_INT_STK]
MOV CX,[$$BOTTOM]
SUB CX,DI
SHR CX,1
REPZ
SCASW
SUB DI,%2
DEC DI
AND DI,>FFFE ; round down to word boundary
MOV CX,DI
SUB CX,[$$LIMIT]
CMP CX,MARGIN
JB NOSTACK
MOV ES,[SAVEES]
MOV AX,SS ; switch stacks
MOV CX,SP
SEGCS
MOV SS,[PROGDS]
MOV SP,DI
MOV DI,CX
MOV DS,AX
MOV CX,RET3
NEWSTK PUSH DS ; save interrupt's stack
PUSH DI
PUSH [DI][%2*4] ; flags
PUSH [DI][%2*3] ; interrupt cs
PUSH [DI][%2*2] ; interrupt ip
MOV AX,DS
PUSH DI
MOV DI,SS
MOV DS,DI
POP DI
PUSH [SAVEAX] ; ax
PUSH BX
PUSH [SAVECX] ; cx
PUSH DX
PUSH ES
PUSH [SAVEDS] ; DS
PUSH SI
PUSH [SAVEDI] ; DI
PUSH BP
MOV DS,AX
MOV AX,CS
PUSH AX ; return segment
PUSH CX ; return address
PUSH [DI][%2*1] ; Caller's address
PUSH [DI][%2*0]
MOV AX,SS
MOV DS,AX
STI
RETFAR ; Go to caller with parms set
;
NOSTACK PUSH DX
PUSH BX
MOV AX,CS
MOV DS,AX
MOV AX,>4000 ; Write message to stderr
MOV BX,2
MOV CX,MSGLEN
MOV DX,STKMSG
INT >21
POP BX
POP DX
JMPS GOBACK
;
RET3 CLI
MOV AX,SS
MOV DS,AX
POP BP
POP [SAVEDI]
POP SI
POP [SAVEDS]
POP [SAVEES]
POP DX
POP [SAVECX]
POP BX
POP [SAVEAX]
ADD SP,%6 ; Remove cs:ip and flags
MOV DI,SS
MOV ES,DI
POP DI ; Interrupted task's sp
ADD DI,%4 ; Remove return from int function
POP AX ; Interrupted task's ss
MOV CX,SP
MOV SS,AX ; Set to prior stack
MOV SP,DI
MOV DI,[$$LIMIT]
ADD DI,[_INT_STK]
SUB CX,DI
SHR CX,1
XOR AX,AX
REP
STOSW
GOBACK MOV AX,[SAVEAX]
MOV CX,[SAVECX]
MOV DI,[SAVEDI]
MOV ES,[SAVEES]
MOV DS,[SAVEDS]
IRET
;
STKMSG DB >0D,>0A,'Out of stack',>0D,>0A
MSGLEN EQU $-STKMSG
PROGDS EQU $+3
callfar $$MAXS
DORG 0
DDEF _INT_STK
SAVEAX DW 0-0
SAVECX DW 0-0
SAVEDI DW 0-0
SAVEDS DW 0-0
SAVEES DW 0-0
_INT_STK DW >400
STKLOCK DW 0
END

70
Mix Power C v1/INTR.ASM Normal file
View File

@ -0,0 +1,70 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; int intr(intno, reg);
; int intno;
; union REGPACK reg;
; -------------------------------------------------------
;
IDT intr
DEF intr
;
intr PUSH BP
MOV BP,SP
SUB SP,INSTRSZ
MOV SI,INSTRINT
MOV DI,SP
MOV AX,SS
MOV ES,AX
MOV CX,INSTRSZ
CLD
REP
MOVSB
MOV BX,SP
MOV AX,[BP][%PARM1]
MOV [BX][%1],AL
MOV BP,[BP][%PARM2]
PUSH BP
MOV AX,CS
PUSH AX ; Return segment
CALL DOINT
PUSH DS
PUSH BP
MOV BP,SS
MOV DS,BP
MOV BP,SP
MOV BP,[BP][%4]
MOV [BP][%0],AX
MOV [BP][%2],BX
MOV [BP][%4],CX
MOV [BP][%6],DX
POP [BP][%8]
MOV [BP][%10],SI
MOV [BP][%12],DI
POP [BP][%14]
MOV [BP][%16],ES
PUSHF
POP [BP][%18]
ADD SP,%INSTRSZ+2
POP BP
RETFAR
;
DOINT MOV AX,SS
PUSH AX ; Segment of int xx instruction
PUSH BX ; offset of int xx instruction
MOV AX,[BP][%0]
MOV BX,[BP][%2]
MOV CX,[BP][%4]
MOV DX,[BP][%6]
MOV SI,[BP][%10]
MOV DI,[BP][%12]
MOV DS,[BP][%14]
MOV ES,[BP][%16]
MOV BP,[BP][%8]
RETFAR
DORG 0
INSTRINT INT >21
INSTRRET RETSEG
INSTRSZ EQU (($-INSTRINT)+1)|>FFFE
END

48
Mix Power C v1/INTRPT.ASM Normal file
View File

@ -0,0 +1,48 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; getvect - get interrupt vector
; return contents of interrupt vector
; -------------------------------------------------------
;
IDT getvect
DEF getvect
;
getvect PUSH BP
MOV BP,SP
MOV AL,[BP][%PARM1]
MOV AH,>35
INT >21
MOV DX,ES
MOV AX,BX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; setvect - set interrupt vector
; void setvect(int intno, void (*fn)())
; -------------------------------------------------------
;
IDT setvect
DEF setvect
;
setvect PUSH BP
MOV BP,SP
PUSH DS
MOV AL,[BP][%PARM1]
; if near pointer
; MOV BX,[BP][%PARM2]
; MOV DX,[BX]
; MOV DS,[BX][%2]
; if far pointer
MOV DX,[BP][%PARM2]
MOV DS,[BP][%PARM3]
MOV AH,>25
INT >21
POP AX
MOV DS,AX
POP BP
RETSEG
END

16
Mix Power C v1/IO.ASM Normal file
View File

@ -0,0 +1,16 @@
;
; Assembly language file io
; Copyright (c) Mix Software 1988
;
GLOBAL
INCLUDE LIBDEF.ASM
CASE 1
ENDGLOBAL
;
INCLUDE READ.ASM
INCLUDE WRITE.ASM
INCLUDE PUT.ASM
INCLUDE GET.ASM
INCLUDE SEEK.ASM
INCLUDE FLUSH.ASM
;

34
Mix Power C v1/LIB.ASM Normal file
View File

@ -0,0 +1,34 @@
;
; Assembly language functions for Mix C
; Large memory model
;
; Copyright (C) 1988 by Mix Software Inc.
; ALL RIGHTS RESERVED
;
GLOBAL
NOLIST
INCLUDE LIBDEF.ASM
LIST
CASE 1
ENDGLOBAL
INCLUDE SYS.ASM
INCLUDE SETMEM.ASM
INCLUDE MOVMEM.ASM
INCLUDE STRING.ASM
INCLUDE TO.ASM
INCLUDE ENVIR.ASM
INCLUDE NHEAP.ASM
INCLUDE NEW.ASM
INCLUDE FREE.ASM
INCLUDE FARSTR1.ASM
INCLUDE FARSTR.ASM
INCLUDE FARHEAP.ASM
INCLUDE DIV.ASM
INCLUDE LONG.ASM
INCLUDE FAR.ASM
INCLUDE SETJMP.ASM
INCLUDE STACK.ASM
INCLUDE INOUT.ASM
INCLUDE FATAL.ASM
;

28
Mix Power C v1/LIB2.ASM Normal file
View File

@ -0,0 +1,28 @@
;
; Assembly language functions for Mix C and Pascal
; Large memory model
;
; COPYRIGHT (C) 1986 by Mix Software Inc.
; ALL RIGHTS RESERVED
;
GLOBAL
NOLIST
INCLUDE LIBDEF.ASM
LIST
CASE 1
ENDGLOBAL
; INCLUDE FARSTR.ASM
INCLUDE FARMEM.ASM
INCLUDE SOUND.ASM
INCLUDE ABSDISK.ASM
INCLUDE BIOSFN.ASM
INCLUDE DISABLE.ASM
INCLUDE INTENT.ASM
INCLUDE SIGNAL.ASM
INCLUDE EXEC.ASM
INCLUDE DTAFAT.ASM
INCLUDE INTRPT.ASM
INCLUDE INTR.ASM
INCLUDE PEEK.ASM
;

150
Mix Power C v1/LIBDEF.ASM Normal file
View File

@ -0,0 +1,150 @@
;
; Definitions for Power C assembly language library functions
; Copyright (c) Mix Software 1988
;
LONGNAME EQU >FFFF ; include long (>8 character) names
SHORTNAM EQU >0 ; include short (8 character) names
UPPER EQU >0 ; include uppercase names
;
; Parameter offsets for large memory
;
PARMORG EQU >6 ; offset to parameters
PARM1 EQU PARMORG ; offset of first word parameter (c)
PARM2 EQU PARMORG+2
PARM3 EQU PARMORG+4
PARM4 EQU PARMORG+6
PARM5 EQU PARMORG+8
PARM6 EQU PARMORG+10
;
; typedef struct {
; char init; { initialized flag }
; char openflg; { file open }
; int handle; { file handle }
; char *bufr; { start of buffer }
; char *ptr; { address of next character }
; int count; { number of characters left in bufr }
; int bufsize; { size of buffer }
; int reclen; { record length }
; char device; { device code }
; char eofflag; { end of file detected }
; char mode; { read, write or read/write }
; char dirty; { buffer written to }
; char error; { error code }
; union {
; char flagbyte;
; struct {
; unsigned noblank : 1 ;
; unsigned binary : 1 ;
; unsigned ctlz : 1 ;
; unsigned filter : 1 ;
; unsigned echo : 1 ;
; unsigned unbufr : 1 ;
; unsigned fill : 2 ;
; } flagbits;
; } flags;
; char column; { column (text files }
; char fill1;
; char *gpbufr; { buffer used by get & put }
; char *pathnm; { name of file }
; char fill2[6];
; } fdb;
;
; FILE DESCRIPTOR DISPLACEMENTS
;
FD$INIT EQU 0 ; File initialized if non-zero
FD$OPEN EQU 1 ; File open if non-zero
FD$HNDL EQU 2 ; File handle
FD$BUFR EQU 4 ; Address of buffer
FD$PTR EQU 6 ; Pointer to next character in buffer
FD$COUNT EQU 8 ; remaining characters in buffer
FD$BUFSZ EQU 10 ; Size of buffer
FD$RECLN EQU 12 ; Record length (pascal only) (-1 for text)
FD$DEV EQU 14 ; DISK OR DEVICE
FD$EOF EQU 15 ; At end of file
FD$MODE EQU 16 ; Read, Write or read/write
FD$DIRTY EQU 17 ; Buffer has been written to
FL$READ EQU >02 ; Buffer has been read
FL$WRITE EQU >01 ; Buffer has been written
FD$ERR EQU 18 ; error code
FD$FLAGS EQU 19 ; flags for console
FL$NOBL EQU >01 ; Flag bit for no blank
FL$BIN EQU >02 ; Flag bit for binary file
FL$CTLZ EQU >04 ; Flag bit for ctl/z = eof
FL$LFEED EQU >08 ; Flag bit for filter line feed
FL$ECHO EQU >10 ; Flag bit for echo to console
FL$UNBUF EQU >20 ; Flag bit for unbuffered
FL$APPEN EQU >40 ; Flag bit for append mode
FL$SETBF EQU >80 ; Flag bit for external buffer
FD$COL EQU 20 ; current column
FD$GPBUF EQU 22 ; buffer for get & put
FD$PATH EQU 24 ; Pointer to path string
FD$SIZE EQU 32 ; size of file descriptor
;
DV$LST EQU 26
DV$CON EQU 27
DV$DMY EQU 28
;
;
; ---------------------------------------------------
; CODES FOR FATAL ERRORS
;
E$STACK EQU >81 ; STACK OVERFLOW
E$HEAP EQU >82 ; HEAP EXHAUSTED
E$PACKET EQU >83 ; INVALID PACKET POINTER
E$LEVEL EQU >84 ; INVALID STATIC LEVEL
E$DIVZ EQU >85 ; DIVIDE BY ZERO
E$NOINS EQU >86 ; INSTRUCTION NOT IMPLEMENTED
E$SET EQU >87 ; SETS NOT COMPATIBLE
E$IERR EQU >88 ; UNDEFINED INTERNAL PROCEDURE
E$IOERR EQU >89 ; IO ERROR
E$SETIX EQU >8A ; SET INDEX OUT OF RANGE
E$WERR EQU >8B ; WRITE TO INPUT FILE
E$NOTOPEN EQU >8C ; FILE NOT OPEN
E$GPERR EQU >8D ; GET, PUT FOR TEXT ONLY
E$OPEN EQU 0ECH ; FILE NOT OPEN
E$READ EQU 0EDH ; FILE NOT OPEN FOR READING
E$WRIT EQU 0EBH ; FILE NOT OPEN FOR WRITING
E$NOHEAP EQU 0EEH ; NO HEAP FOR FILE BUFFER
E$PASTEN EQU >99
E$NOSPAC EQU >9A
;
EOFCHR EQU >1A
;
EZERO EQU 0
EPERM EQU 1
ENOENT EQU 2
ESRCH EQU 3
EINTR EQU 4
EIO EQU 5
ENXIO EQU 6
E2BIG EQU 7
ENOEXEC EQU 8
EBADF EQU 9
ECHILD EQU 10
EAGAIN EQU 11
ENOMEM EQU 12
EACCES EQU 13
EFAULT EQU 14
ENOTBLK EQU 15
EBUSY EQU 16
EEXIST EQU 17
EXDEV EQU 18
ENODEV EQU 19
ENOTDIR EQU 20
EISDIR EQU 21
EINVAL EQU 22
ENFILE EQU 23
EMFILE EQU 24
ENOTTY EQU 25
ETXTBSY EQU 26
EFBIG EQU 27
ENOSPC EQU 28
ESPIPE EQU 29
EROFS EQU 30
EMLINK EQU 31
EPIPE EQU 32
EDOM EQU 33
ERANGE EQU 34
EUCLEAN EQU 35
EDEADLOCK EQU 36
;

118
Mix Power C v1/LOCKING.C Normal file
View File

@ -0,0 +1,118 @@
/* Record locking */
/* Copyright (c) Mix Software 1988 */
#include "locking.h"
int locking(fd, mode, nbyte)
int fd;
int mode;
long nbyte;
{
struct intlong {
unsigned int lower;
unsigned int upper;
};
union {
long l;
struct intlong words;
} v;
union REGS lock;
union REGS time;
union REGS answer;
extern int errno;
int status;
int trycount, sec;
lock.x.ax = 0x5c00;
lock.x.bx = fd;
v.l = nbyte;
lock.x.si = v.words.upper;
lock.x.di = v.words.lower;
v.l = lseek(fd,0L,1);
lock.x.cx = v.words.upper;
lock.x.dx = v.words.lower;
if (mode == LK_UNLCK) lock.h.al = 0x01;
trycount = (mode == LK_LOCK || mode == LK_RLCK) ? 10 : 1;
do {
status = intdos(&lock,&answer);
if (answer.x.cflag == 0) return 0;
if (status != 0x21) { errno = status; return -1; }
if (--trycount) {
time.h.ah = 0x2c;
intdos(&time,&answer);
sec = answer.h.dh;
do {
intdos(&time,&answer);
} while (sec == answer.h.dh);
}
} while (trycount);
errno = (mode == LK_LOCK || mode == LK_RLCK) ? EDEADLOCK : EACCES;
return -1;
} /* locking */
int lock(fd, offset, length)
int fd;
long offset;
long length;
{
union {
long l;
struct {
unsigned int lower;
unsigned int upper;
} words;
} v;
union REGS lockfl, time, answer;
extern int errno;
int status;
int trycount = 4;
int sec;
lockfl.x.ax = 0x5c00;
lockfl.x.bx = fd;
v.l = length;
lockfl.x.si = v.words.upper;
lockfl.x.di = v.words.lower;
v.l = offset;
lockfl.x.cx = v.words.upper;
lockfl.x.dx = v.words.lower;
while (--trycount) {
status = intdos(&lockfl,&answer);
if (answer.x.cflag == 0) return 0;
if (status != 0x21) { errno = status; return -1; }
time.h.ah = 0x2c;
intdos(&time,&answer);
sec = answer.h.dh;
do {
intdos(&time,&answer);
} while (sec == answer.h.dh);
}
return -1;
} /* lock */
int unlock(fd, offset, length)
int fd;
long offset;
long length;
{
union {
long l;
struct {
unsigned int lower;
unsigned int upper;
} words;
} v;
union REGS lockfl, answer;
extern int errno;
int status;
lockfl.x.ax = 0x5c01;
lockfl.x.bx = fd;
v.l = length;
lockfl.x.si = v.words.upper;
lockfl.x.di = v.words.lower;
v.l = offset;
lockfl.x.cx = v.words.upper;
lockfl.x.dx = v.words.lower;
status = intdos(&lockfl,&answer);
if (answer.x.cflag == 0) return 0;
errno = status;
return -1;
} /* unlock */

10
Mix Power C v1/LOCKING.H Normal file
View File

@ -0,0 +1,10 @@
/*$no list*//*$no trace <<< locking.h >>> */
/* Copyright (c) Mix Software 1988 */
#define LK_UNLCK 0 /* unlock the file region */
#define LK_LOCK 1 /* lock the file region (10 attempts) */
#define LK_NBLCK 2 /* lock the file region (1 attempt) */
#define LK_RLCK 3 /* same as LK_LOCK */
#define LK_NBRLCK 4 /* same as LK_NBLCK */
/*$list*//*$trace <<< locking.h >>> */

524
Mix Power C v1/LONG.ASM Normal file
View File

@ -0,0 +1,524 @@
;
; Copyright (c) Mix Software 1988
;
; ---------------------------------------
; LONG ABSOLUTE VALUE
; ---------------------------------------
;
IDT LABS
DEF LABS
DEF labs
labs equ $
LABS MOV BX,SP
MOV AX,[BX][%PARM1-2] ; GET L1
MOV DX,[BX][%PARM2-2] ; GET H1
TEST DX,DX
JNS POS
NEG DX
NEG AX
SBB DX,%0
POS RETSEG
END
;
;----------------------------------------------------
; LONG MULTIPLY
;----------------------------------------------------
IDT $_LMUL
DEF $_LMUL
$_LMUL PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1] ; LSW OF MULTIPLIER
MOV BX,[BP][%PARM2] ; MSW OF MULTIPLIER
MOV CX,[BP][%PARM3] ; LSW OF MULTIPLICAND
MOV DX,[BP][%PARM4] ; MSW OF MULTIPLICAND
PUSH BX
XOR BX,DX ; SIGN OF RESULT
ROL BX ; SAVE IN CARRY
POP BX
PUSHF
TEST BX,BX ; CHECK SIGN
JNS MUL01
NEG BX
NEG AX
SBB BX,%0
MUL01 TEST DX,DX ; CHECK SIGN
JNS MUL02
NEG DX
NEG CX
SBB DX,%0
MUL02 PUSH DX
PUSH AX
MUL CX ; LSW*LSW
MOV SI,AX ; SAVE LSW OF RESULT
MOV DI,DX ; MSW PARTIAL
POP AX
POP DX
MUL DX ; L1*H1
ADD DI,AX
MOV AX,BX
MUL CX ; L2*H1
ADD AX,DI
MOV DX,SI
POPF
JNB MUL03 ; NOT NEGATIVE
NEG AX
NEG DX
SBB AX,0
MUL03 XCHG AX,DX
POP BP
RETSEG
END
;
;----------------------------------------------------
; unsigned long multiply
;----------------------------------------------------
IDT $_LUMUL
DEF $_LUMUL
$_LUMUL PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1] ; LSW OF MULTIPLIER
MOV BX,[BP][%PARM2] ; MSW OF MULTIPLIER
MOV CX,[BP][%PARM3] ; LSW OF MULTIPLICAND
MOV DX,[BP][%PARM4] ; MSW OF MULTIPLICAND
PUSH DX
PUSH AX
MUL CX ; LSW*LSW
MOV SI,AX ; SAVE LSW OF RESULT
MOV DI,DX ; MSW PARTIAL
POP AX
POP DX
MUL DX ; L1*H1
ADD DI,AX
MOV AX,BX
MUL CX ; L2*H1
ADD AX,DI
MOV DX,SI
XCHG AX,DX
POP BP
RETSEG
END
;
;-----------------------------------------
; DIVIDE LONG
;-----------------------------------------
;
;
DIVBY0 EQU >85
IDT $_LDIV
DEF $_LDIV
DREF $$ARTERM
DREF errno
FREF $_FATAL
$_LDIV PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1] ;BX=LSW OF DIVISOR
MOV AX,[BP][%PARM2] ;AX=MSW OF DIVISOR
MOV DX,[BP][%PARM3] ;DX=LSW OF DIVIDEND
MOV CX,[BP][%PARM4] ;CX=MSW OF DIVIDEND
CALL DIVIDE
MOV DX,BX
XCHG AX,DX
POP BP
RETSEG
;
;-----------------------------------------
; MOD LONG
;-----------------------------------------
;
;
DEF $_LMOD
DEF $_LBENCO
$_LBENCO EQU $
$_LMOD PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1] ;BX=LSW OF DIVISOR
MOV AX,[BP][%PARM2] ;AX=MSW OF DIVISOR
MOV DX,[BP][%PARM3] ;DX=LSW OF DIVIDEND
MOV CX,[BP][%PARM4] ;CX=MSW OF DIVIDEND
CALL DIVIDE
MOV AX,CX
XCHG AX,DX
POP BP
RETSEG
;
DEF $_LUDIV
$_LUDIV PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1] ;BX=LSW OF DIVISOR
MOV AX,[BP][%PARM2] ;AX=MSW OF DIVISOR
MOV DX,[BP][%PARM3] ;DX=LSW OF DIVIDEND
MOV CX,[BP][%PARM4] ;CX=MSW OF DIVIDEND
CALL UDIVIDE
MOV DX,BX
XCHG AX,DX
POP BP
RETSEG
;
;-----------------------------------------
; MOD LONG
;-----------------------------------------
;
;
DEF $_LUMOD
$_LUMOD PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1] ;BX=LSW OF DIVISOR
MOV AX,[BP][%PARM2] ;AX=MSW OF DIVISOR
MOV DX,[BP][%PARM3] ;DX=LSW OF DIVIDEND
MOV CX,[BP][%PARM4] ;CX=MSW OF DIVIDEND
CALL UDIVIDE
MOV AX,CX
XCHG AX,DX
POP BP
RETSEG
;
; ---------------------------------------
; ldiv - divide and return both
; quotient and reamainder
; ---------------------------------------
; typedef struct {
; long quot; /* quotient */
; long rem; /* remainder */
; } ldiv_t;
;
; ldiv_t div(long numer, long denom)
; {
; ldiv_t s;
; s.quot = numer/denom;
; s.rem = numer%denom;
; return s;
; }
;
IDT ldiv
DEF ldiv
NUMER EQU PARM1+4
DENOM EQU PARM3+4
STRUC EQU PARM1+2
;
ldiv PUSH BP
MOV BP,SP
MOV BX,[BP][%DENOM] ;BX=LSW OF DIVISOR
MOV AX,[BP][%DENOM+2] ;AX=MSW OF DIVISOR
MOV DX,[BP][%NUMER] ;DX=LSW OF DIVIDEND
MOV CX,[BP][%NUMER+2] ;CX=MSW OF DIVIDEND
CALL DIVIDE
MOV SI,[BP][%STRUC]
MOV [SI],BX
MOV [SI][%2],AX
MOV [SI][%4],DX
MOV [SI][%6],CX
MOV AX,SI
POP BP
RETFAR
;
;-------------------------------------------
; LONG DIVIDE ROUTINE
; -------------------
; INPUT : CXDX=DIVIDEND
; AXBX=DIVISOR
; OUTPUT: AXBX=QUOTIENT
; CXDX=REMAINDER
;--------------------------------------------
DIVIDE MOV SI,AX
XOR SI,CX ; MSBit of SI = sign of result
DIV04 TEST CX,CX
JNS DIV05 ; DIVIDEND IS POSITIVE
NEG CX
NEG DX
SBB CX,%0
DIV05 TEST AX,AX
JNS DIV06
NEG AX
NEG BX
SBB AX,0
DIV06 CALL UDIVIDE
TEST SI,SI
JNS DONE
NEG AX
NEG BX
SBB AX,0
NEG CX
NEG DX
SBB CX,%0
DONE RET
;
;-------------------------------------------
; UNSIGNED LONG DIVIDE ROUTINE
; -------------------
; INPUT : CXDX=DIVIDEND
; AXBX=DIVISOR
; OUTPUT: AXBX=QUOTIENT
; CXDX=REMAINDER
;--------------------------------------------
UDIVIDE TEST AX,AX
JNZ UDIV01
TEST BX,BX
JZ DIVZERO
UDIV01 TEST DX,DX
JNZ UDIV04
TEST CX,CX
JNZ UDIV04
XOR AX,AX
XOR BX,BX
RET
UDIV04 TEST AX,AX
JNZ UDIV32
; ; MS 16 bits of divisor = 0
MOV AX,CX ; Upper word of dividend
MOV CX,DX
XOR DX,DX
DIV BX ; Divide 0:upper by bx
XCHG AX,CX ; CX = quotient, AX = lsw
DIV BX ; Divide remainder:lower by bx
MOV BX,AX ; CX = quotient MSW, AX = LSW
MOV AX,CX
XOR CX,CX ; remainder is 0:DX
EXIT RET
;
; Divisor is 32 bits long
; since msw of the divisor is non-zero, the upper 16 bits of the
; quotient must be zero, and only 16 cycles are needed to divide.
;
UDIV32 XOR DI,DI
MOV BP,16
DIVLOOP SHL DX
RCL CX
RCL DI
CMP DI,AX ; Fits in msw?
JB NEXTBIT
JNZ TOOMUCH
CMP CX,BX ; upper words equal, check lower
JB NEXTBIT
TOOMUCH SUB CX,BX
SBB DI,AX
INC DX ; Quotient gets a 1 bit
NEXTBIT DEC BP
JNZ DIVLOOP
;
; Quotient is 0:DX, remainder is DI:CX
;
XOR AX,AX
MOV BX,DX
MOV DX,CX
MOV CX,DI
JMPS EXIT
DIVZERO MOV AX,DIVBY0
MOV %[errno],AL
TEST %[$$ARTERM],%>01
JZ IGNORE
PUSH AX
CALLFAR $_FATAL
POP AX
IGNORE MOV AX,>FFFF
MOV BX,>FFFF
POS RET
END
;
; -----------------------------------------
; COMPARE LONG
; -----------------------------------------
; PUSHES A RESULT BYTE
; FF FOR LESS THAN
; 00 FOR EQUAL
; 01 FOR GREATER
;
IDT $_LCMP
DEF $_LCMP
$_LCMP PUSH BP
MOV BP,SP
XOR AX,AX
MOV CX,[BP][%PARM3]
MOV DX,[BP][%PARM4] ; GET L2
SUB CX,[BP][%PARM1]
SBB DX,[BP][%PARM2] ; COMPARE MSW
JG LCMP06
JL LCMP07
TEST CX,CX
JNZ LCMP06
POP BP
RETSEG
LCMP06 INC AX
POP BP
RETSEG
LCMP07 DEC AX
POP BP
RETSEG
END
;
; -----------------------------------------
; compare unsigned long
; -----------------------------------------
; PUSHES A RESULT BYTE
; FF FOR LESS THAN
; 00 FOR EQUAL
; 01 FOR GREATER
;
IDT $_LUCMP
DEF $_LUCMP
DEF $_LFIXUL
$_LFIXUL EQU $
$_LUCMP PUSH BP
MOV BP,SP
XOR AX,AX
MOV CX,[BP][%PARM3]
MOV DX,[BP][%PARM4] ; GET L2
CMP DX,[BP][%PARM2] ; COMPARE MSW
JA LCMP01
JB LCMP02
CMP CX,[BP][%PARM1] ; COMPARE LSW
JZ LCMP03 ; EQUAL
JNA LCMP02
LCMP01 MOV AL,1 ; GREATER THAN
JMPS LCMP04
LCMP02 MOV AL,>FF ; LESS THAN
JMPS LCMP04
LCMP03 XOR AX,AX ; EQUAL
LCMP04 POP BP
RETSEG
END
;
; ---------------------------------------
; LONG BITWISE AND
; ---------------------------------------
;
IDT $_LBITAN
DEF $_LBITAN
$_LBITAN MOV BX,SP
MOV AX,[BX][%PARM1-2] ; GET L1
MOV DX,[BX][%PARM2-2] ; GET H1
MOV CX,[BX][%PARM3-2] ; GET L2
AND AX,CX
MOV CX,[BX][%PARM4-2] ; GET H2
AND DX,CX
RETSEG
END
;
; ---------------------------------------
; LONG BITWISE INCLUSIVE OR
; ---------------------------------------
;
IDT $_LBITOR
DEF $_LBITOR
$_LBITOR MOV BX,SP
MOV AX,[BX][%PARM1-2] ; GET L1
MOV DX,[BX][%PARM2-2] ; GET H1
MOV CX,[BX][%PARM3-2] ; GET L2
OR AX,CX
MOV CX,[BX][%PARM4-2]
OR DX,CX
RETSEG
END
;
; ---------------------------------------
; LONG BITWISE INVERT
; ---------------------------------------
;
IDT $_LBITNO
DEF $_LBITNO
$_LBITNO MOV BX,SP
MOV AX,[BX][%PARM1-2] ; GET OPERAND
MOV DX,[BX][%PARM2-2]
NOT AX
NOT DX
RETSEG
END
;
; ---------------------------------------
; LONG BITWISE EXCLUSIVE OR
; ---------------------------------------
;
IDT $_LXOR
DEF $_LXOR
$_LXOR MOV BX,SP
MOV AX,[BX][%PARM1-2] ; GET L1
MOV DX,[BX][%PARM2-2] ; GET H1
MOV CX,[BX][%PARM3-2] ; GET L2
XOR AX,CX
MOV CX,[BX][%PARM4-2]
XOR DX,CX
RETSEG
END
;
; ---------------------------------------
; LONG BITWISE IMPLIES (NOT A) OR B
; ---------------------------------------
;
IDT $_LIMPL
DEF $_LIMPL
$_LIMPL MOV BX,SP
MOV AX,[BX][%PARM1-2] ; GET L1
MOV DX,[BX][%PARM2-2] ; GET H1
MOV CX,[BX][%PARM3-2] ; GET L2
NOT AX
OR AX,CX
MOV CX,[BX][%PARM4-2]
NOT DX
OR DX,CX
RETSEG
END
;
; ---------------------------------------
; LONG SHIFT RIGHT WITH ZERO FILL
; TOP OF STACK WORD CONTAINS THE COUNT
; TOP OF STACK-2 IS THE VALUE
; ---------------------------------------
;
IDT $_LSHIFR
DEF $_LSHIFR
$_LSHIFR MOV BX,SP
MOV CX,[BX][%PARM1-2] ; GET SHIFT COUNT
CMP CX,32
JNA LSHFR01
MOV CX,32 ; LIMIT TO 32
LSHFR01 MOV AX,[BX][%PARM2-2]
MOV DX,[BX][%PARM3-2]
JCXZ LSHFR03
LSHFR02 SHR DX ; SHIFT
RCR AX
LOOP LSHFR02
LSHFR03 RETSEG
END
;
; ---------------------------------------
; LONG SHIFT LEFT WITH ZERO FILL
; TOP OF STACK WORD CONTAINS THE COUNT
; TOP OF STACK-2 IS THE VALUE
; ---------------------------------------
;
IDT $_LSHIFL
DEF $_LSHIFL
$_LSHIFL MOV BX,SP
MOV CX,[BX][%PARM1-2] ; GET SHIFT COUNT
CMP CX,32
JNA LSHFL01
MOV CX,32 ; LIMIT TO 32
LSHFL01 MOV AX,[BX][%PARM2-2]
MOV DX,[BX][%PARM3-2]
JCXZ LSHFL03
LSHFL02 SHL AX ; SHIFT
RCL DX
LOOP LSHFL02
LSHFL03 RETSEG
END
;
; ---------------------------------------
; LONG SHIFT RIGHT WITH SIGN PROPOGATE
; TOP OF STACK WORD CONTAINS THE COUNT
; TOP OF STACK-2 IS THE VALUE
; ---------------------------------------
;
IDT $_LASHIF
DEF $_LASHIF
$_LASHIF MOV BX,SP
MOV CX,[BX][%PARM1-2] ; GET SHIFT COUNT
CMP CX,32
JNA LASHF01
MOV CX,32 ; LIMIT TO 32
LASHF01 MOV AX,[BX][%PARM2-2]
MOV DX,[BX][%PARM3-2]
JCXZ LASHF03
LASHF02 SAR DX ; SHIFT
RCR AX
LOOP LASHF02
LASHF03 RETSEG
END

21
Mix Power C v1/MEMORY.C Normal file
View File

@ -0,0 +1,21 @@
/* Copyright (c) Mix Software 1988 */
char *realloc(oldptr, newsize)
char *oldptr;
int newsize;
{
char *newptr, *malloc();
if (oldptr == NULL) return malloc(newsize);
if (newsize == 0) {
free(newptr);
return NULL;
}
if (newptr = malloc(newsize)) {
if (oldptr == NULL) return newptr;
memcpy(newptr, oldptr, newsize);
free(oldptr);
return newptr;
}
else return NULL;
}

BIN
Mix Power C v1/MERGE.EXE Normal file

Binary file not shown.

10
Mix Power C v1/MIXC.BAT Normal file
View File

@ -0,0 +1,10 @@
echo off
pc mixc1,dystring
if errorlevel 1 goto stop
if exist mixc.mix del mixc.mix
merge mixc mixc1 dystring
if errorlevel 1 goto stop
goto end
:stop
echo Errors building mixc
:end

BIN
Mix Power C v1/MIXC.MIX Normal file

Binary file not shown.

277
Mix Power C v1/MIXC1.C Normal file
View File

@ -0,0 +1,277 @@
#include <stdio.h>
#include <dos.h>
#include <process.h>
#include <fcntl.h>
#include <stat.h>
/* Functions present in Mix C that are not in the Power C
standard libraries. Also includes functions (such as
chmod) whose definition has been changed. For portability
from mix c, this library should be searched first.
It is recommended that these functions not be used in
new programs.
*/
typedef union { /* register structure used by asm and asmx */
struct {
char al, ah, bl, bh, cl, ch, dl, dh;
} byte;
struct {
int ax, bx, cx, dx, si, di, bp, es, ds, cs;
} word;
} MREGS;
int asm(address, bx)
int address; /* address of code (in data segment) */
int bx; /* value to pass in bx register */
{
MREGS r;
r.word.bx = bx;
return asmx(address,&r);
}
int bdos(fn, dx)
int fn; /* function number */
int dx; /* value to pass in dx */
{
union REGS r;
r.h.ah = fn;
r.x.dx = dx;
intdos(&r, &r);
return r.h.al;
}
chain(command)
char *command;
{
static char nullchar = '\0';
char filename[130];
char *p, *q;
int argc;
char *argv[32];
p = command;
q = filename;
while (*p != ' ' && *p != '/' && *p != '\0') *q++ = *p++;
*q = '\0';
argv[0] = &nullchar;
argc = 1;
while (*p != '\0' && argc < 32) {
while (*p == ' ') ++p;
if (*p != '\0') {
argv[argc] = p;
argc++;
while (*p != ' ' && *p != '\0') ++p;
*p = '\0';
}
}
return execvp(filename,argv);
} /* chain */
chmod(name, mode)
char *name; /* name of file */
int mode; /* new mode */
{
extern int errno, _doserrno;
int status;
if (_sysacdc(0x4301,mode,name,&status) == 0) return 0;
errno = _doserrno;
return -1;
}
creat(name, mode)
char *name;
int mode;
{
int fd, status;
fd = open(name,O_CREAT|O_RDWR|O_TRUNC,S_IREAD|S_IWRITE);
if (fd != -1) _sys_acd(0x4300,mode,name,&status);
return fd;
}
exec(command)
char *command;
{
static char nullchar = '\0';
char filename[130];
char *p, *q;
int argc;
char *argv[32];
p = command;
q = filename;
while (*p != ' ' && *p != '/' && *p != '\0') *q++ = *p++;
*q = '\0';
argv[0] = &nullchar;
argc = 1;
while (*p != '\0' && argc < 32) {
while (*p == ' ') ++p;
if (*p != '\0') {
argv[argc] = p;
argc++;
while (*p != ' ' && *p != '\0') ++p;
*p = '\0';
}
}
return spawnvp(P_WAIT,filename,argv);
} /* exec */
getd(dptr, fp)
double *dptr;
FILE *fp;
{
char buffer[128];
char *p;
int c;
while (isspace(c = fgetc(fp)));
if (c == '+' || c == '-') *p++ = c;
while (isdigit(c)) { *p++ = c; c = fgetc(fp); }
if (c == '.') {
*p++ = c;
c = fgetc(fp);
while (isdigit(c = fgetc(fp))) {*p++ = c; c = fgetc(fp); }
}
if (toupper(c) == 'E') {
*p++ = c;
c = fgetc(fp);
while (isdigit(c = fgetc(fp))) {*p++ = c; c = fgetc(fp); }
}
if (c != -1) ungetc(c,fp);
*dptr = atof(buffer);
return 0;
}
geti(iptr, fp)
int *iptr;
FILE *fp;
{
char buffer[128];
char *p;
int c;
while (isspace(c = fgetc(fp)));
if (c == '+' || c == '-') *p++ = c;
while (isdigit(c = fgetc(fp))) *p++ = c;
*p = '\0';
if (p == buffer) return -1;
if (c != -1) ungetc(c,fp);
*iptr = atio(buffer);
return 0;
}
getmode()
{
return getvmode();
}
int puti(i, fp)
int i;
FILE *fp;
{
char buffer[16];
__itoa(i,buffer);
return fputs(buffer,fp);
}
itoa(n,s)
int n;
char *s;
{
return __itoa(n,s);
}
__itoa(n, s)
int n;
char *s;
{
char buffer[7], flag = '\0', *ptr;
buffer[6] = '\0';
ptr = &buffer[5];
if (n < 0) {
if (n == -32768) {
strcpy(s, "-32768");
return;
}
++flag;
n = -n;
}
do {
*(ptr--) = n % 10 + 48;
} while ((n /= 10) > 0);
if (flag) *ptr = '-';
else ptr++;
strcpy(s, ptr);
return;
}
int open(name, rwmode)
char *name;
int rwmode;
{
int openmode;
int r;
r = rwmode & 0x03;
if (r == 0) openmode = O_RDONLY;
else if (r == 1) openmode = O_WRONLY;
else openmode = O_RDWR;
if (rwmode & 0x8000) openmode += O_BINARY;
return _open(name,openmode,0);
}
int peek(address)
char *address;
{
return *address;
}
int putd(d, fp)
double d;
FILE *fp;
{
char buffer[64];
ftoa(d,buffer,0x8a,1,16);
return fputs(buffer,fp);
}
setdate(s)
char *s;
{
int mm, dd, yy;
int result;
mm = (*s++ - '0')*10 + *s++ - '0';
++s;
dd = (*s++ - '0')*10 + *s++ - '0';
++s;
yy = (*s++ - '0')*10 + *s++ - '0';
_sys_acd(0x2b00,yy+1900,(mm<<8)+dd,&result);
return;
}
setmode(mode)
int mode;
{
return setvmode(mode);
}
settime(s)
char *s;
{
int hh, mm, ss;
int result;
hh = (*s++ - '0')*10 + *s++ - '0';
++s;
mm = (*s++ - '0')*10 + *s++ - '0';
++s;
ss = (*s++ - '0')*10 + *s++ - '0';
_sys_acd(0x2b00,(hh<<8)+mm,ss<<8,&result);
return;
}
double sqr(x)
double x;
{
return x*x;
}
char *strsave(s)
char *s;
{
return strdup(s);
}

484
Mix Power C v1/MOVMEM.ASM Normal file
View File

@ -0,0 +1,484 @@
;
; -------------------------------------------------------
; movmem(source, destination, n) - move block of memory
; memcpy(destination, source, n) - move block of memory
; -------------------------------------------------------
;
IDT movmem
IF UPPER
DEF MOVMEM
ENDIF
DEF movmem
; DEF MEMCPY
; DEF memcpy
DEF $_MOV
;
movmem equ $
MOVMEM PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM1]
MOV DI,[BP][%PARM2]
COPY1 MOV CX,[BP][%PARM3]
COPY2 MOV AX,DI ; result is pointer to dest
JCXZ DONE
CLD
MOV DX,DS
MOV ES,DX
CMP SI,DI
JAE COPY
STD
ADD SI,CX
ADD DI,CX
TEST CL,>01
JZ EVEN
DEC SI
DEC DI
MOVSB
SHR CX,1
JCXZ DONE
DEC SI
DEC DI
REP
MOVSW
JMPS DONE
EVEN SUB SI,%2
SUB DI,%2
SHR CX,1
JCXZ DONE
REP
MOVSW
JMPS DONE
COPY PUSH CX
SHR CX,1
JCXZ LASTCHAR
REP
MOVSW
LASTCHAR POP CX
AND CL,>01
JZ DONE
MOVSB
DONE CLD
POP BP
RETSEG
memcpy equ $
MEMCPY PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM2]
MOV DI,[BP][%PARM1]
JMPS COPY1
$_MOV PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM3]
MOV DI,[BP][%PARM2]
MOV CX,[BP][%PARM1]
JMPS COPY2
END
;
; -------------------------------------------------------
; memcpy(destination, source, n) - move block of memory
; -------------------------------------------------------
;
IDT memcpy
IF UPPER
DEF MEMCPY
ENDIF
DEF memcpy
;
memcpy equ $
MEMCPY MOV BX,SP
MOV DI,[BX][%PARM1-2]
MOV SI,[BX][%PARM2-2]
MOV CX,[BX][%PARM3-2]
MOV AX,DI ; result is pointer to dest
JCXZ DONE
CLD
MOV DX,DS
MOV ES,DX
CMP SI,DI
JAE COPY
STD
ADD SI,CX
ADD DI,CX
DEC SI
DEC DI
COPY REP
MOVSB
CLD
DONE RETFAR
END
;
; -------------------------------------------------------
; memmove(destination, source, n) - move block of memory
; -------------------------------------------------------
;
IDT memmove
DEF memmove
;
memmove MOV BX,SP
MOV DI,[BX][%PARM1-2]
MOV SI,[BX][%PARM2-2]
MOV CX,[BX][%PARM3-2]
MOV AX,DI ; result is pointer to dest
JCXZ DONE
CLD
MOV DX,DS
MOV ES,DX
CMP SI,DI
JAE COPY
STD
ADD SI,CX
ADD DI,CX
DEC SI
DEC DI
COPY REP
MOVSB
CLD
DONE RETFAR
END
;
; -------------------------------------------------------
; memswap(addr1, addr2, n) - swap two blocks of memory
; -------------------------------------------------------
;
IDT memswap
IF UPPER
DEF MEMSWAP
ENDIF
DEF memswap
;
memswap equ $
MEMSWAP MOV BX,SP
MOV SI,[BX][%PARM1-2]
MOV DI,[BX][%PARM2-2]
MOV CX,[BX][%PARM3-2]
JCXZ DONE
CLD
MOV DX,DS
MOV ES,DX
SWAP MOV AL,[DI]
XCHG AL,[SI]
STOSB
INC SI
LOOP SWAP
DONE RETSEG
END
;
; -------------------------------------------------------
; memset(addr, value, count) - fill a block with character
; -------------------------------------------------------
;
IDT memset
IF UPPER
DEF MEMSET
ENDIF
DEF memset
;
memset equ $
MEMSET MOV BX,SP
MOV DI,[BX][%PARM1-2]
MOV AX,[BX][%PARM2-2]
MOV CX,[BX][%PARM3-2]
JCXZ DONE
CLD
MOV DX,DS
MOV ES,DX
REP
STOSB
DONE RETSEG
END
;
; -------------------------------------------------------
; swab(source, destination, n) - swap bytes in a block of memory
; -------------------------------------------------------
;
IDT swab
DEF swab
;
swab PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM1]
MOV DI,[BP][%PARM2]
MOV CX,[BP][%PARM3]
SHR CX,1 ; word count
CLD
MOV DX,DS
MOV ES,DX
JCXZ DONE
COPY LODSW
XCHG AH,AL
STOSW
LOOP COPY
DONE TEST [BP][%PARM3],1
JZ EVEN
LODSB
STOSB
EVEN POP BP
RETSEG
END
;
; -------------------------------------------------------
; $_movarg(source,dest,n) - move block of memory
; source is address of last byte of block
; -------------------------------------------------------
;
IDT $_MOVARG
DEF $_MOVARG
;
$_MOVARG PUSH BP
MOV BP,SP
MOV CX,[BP][%PARM1]
JCXZ DONE
MOV DI,[BP][%PARM2]
MOV SI,[BP][%PARM3]
SUB SI,CX
INC SI
CLD
MOV DX,DS
MOV ES,DX
REP
MOVSB
DONE POP BP
RETSEG
END
;
; -------------------------------------------------------
; memccpy(dest, src, c, cnt) - copy up to & including c
; -------------------------------------------------------
;
IDT memccpy
IF UPPER
DEF MEMCCPY
ENDIF
DEF memccpy
;
memccpy equ $
MEMCCPY PUSH BP
MOV BP,SP
MOV DI,[BP][%PARM1]
MOV SI,[BP][%PARM2]
MOV DX,[BP][%PARM3]
MOV CX,[BP][%PARM4]
JCXZ ENDCOUNT
MOV DX,DS
MOV ES,DX
CLD
COPY LODSB
STOSB
CMP AL,DL
JZ FOUND
LOOP COPY
ENDCOUNT XOR AX,AX ; Return null if c not copied
POP BP
RETSEG
FOUND MOV AX,DI ; return address of next after c
POP BP
RETSEG
END
;
; -------------------------------------------------------
; memchr(buf, c, cnt) - search for c in buffer
; -------------------------------------------------------
;
IDT memchr
IF UPPER
DEF MEMCHR
ENDIF
DEF memchr
;
memchr equ $
MEMCHR PUSH BP
MOV BP,SP
MOV DI,[BP][%PARM1]
MOV AX,[BP][%PARM2]
MOV CX,[BP][%PARM3]
MOV DX,DS
MOV ES,DX
CLD
REPNZ
SCASB
JNZ NOFIND
DEC DI
MOV AX,DI ; Return pointer to c in buf
POP BP
RETSEG
NOFIND XOR AX,AX ; Return null if not found
POP BP
RETSEG
END
;
; -------------------------------------------------------
; memcmp(buf1, buf2, cnt) - compare memory
; $_cmp(src, dest, cnt) - compare memory (byte result)
; -------------------------------------------------------
;
IDT memcmp
IF UPPER
DEF MEMCMP
ENDIF
DEF memcmp
DEF $_CMP
;
$_CMP PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM3]
MOV DI,[BP][%PARM2]
MOV CX,[BP][%PARM1]
JMPS COMPARE
memcmp equ $
MEMCMP PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM1]
MOV DI,[BP][%PARM2]
MOV CX,[BP][%PARM3]
COMPARE JCXZ EQUAL
MOV DX,DS
MOV ES,DX
CLD
REPZ
CMPSB
JZ EQUAL
MOV AL,[SI][%-1]
SUB AL,[DI][%-1]
CBW
POP BP
RETSEG
EQUAL XOR AX,AX ; Return 0 if buffers are equal
POP BP
RETSEG
END
;
; -------------------------------------------------------
; memicmp(buf1, buf2, cnt) - compare memory
; -------------------------------------------------------
;
IDT memicmp
IF UPPER
DEF MEMICMP
ENDIF
DEF memicmp
;
memicmp equ $
MEMICMP PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM1]
MOV DI,[BP][%PARM2]
MOV CX,[BP][%PARM3]
JCXZ EQUAL
MOV DX,DS
MOV ES,DX
CLD
MATCH REPZ
CMPSB
JZ EQUAL
MOV AL,[SI][%-1]
MOV AH,[DI][%-1]
CMP AL,'a'
JB X1
CMP AL,'z'
JA X1
SUB AL,>20
X1 CMP AH,'a'
JB X2
CMP AH,'z'
JA X2
SUB AH,>20
X2 CMP AL,AH
JZ MATCH
MOV AL,[SI][%-1]
SUB AL,[DI][%-1]
CBW
POP BP
RETSEG
EQUAL XOR AX,AX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; movedata(srcseg, srcoff, destseg, destoff, nbytes);
; move a block of data between segments
; -------------------------------------------------------
;
IDT movedata
IF UPPER
DEF MOVEDATA
ENDIF
DEF movedata
;
movedata equ $
MOVEDATA PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM2]
MOV DI,[BP][%PARM4]
CLD
PUSH DS
MOV DS,[BP][%PARM1]
MOV ES,[BP][%PARM3]
MOV CX,[BP][%PARM5]
JCXZ DONE
MOV AX,[BP][%PARM1]
CMP AX,[BP][%PARM3]
JNZ COPY
CMP DI,SI ; Allow overlap if segments equal
JBE COPY
STD
DEC CX
ADD SI,CX ; point to end of data
ADD DI,CX
INC CX
REP
MOVSB
CLD
JMPS DONE
COPY PUSH CX
SHR CX,1
JCXZ LASTCHAR
REP
MOVSW
LASTCHAR POP CX
AND CX,>0001
JCXZ DONE
MOVSB
DONE POP AX
MOV DS,AX
POP BP
RETSEG
END
;
; -------------------------------------------------------
; xmovmem(xsource, xdest, size);
; -------------------------------------------------------
;
IDT xmovmem
IF UPPER
DEF XMOVMEM
ENDIF
DEF xmovmem
xmovmem equ $
XMOVMEM PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1] ; lsw of source
MOV CL,%4
MOV SI,AX
AND SI,>000F
SHR AX,CL
ADD AX,[BP][%PARM2] ; msw of source
MOV DX,[BP][%PARM3] ; lsw of dest
MOV CL,%4
MOV DI,DX
AND DI,>000F
SHR DX,CL
ADD DX,[BP][%PARM4] ; msw of dest
MOV ES,DX
PUSH DS
MOV DS,AX
MOV CX,[BP][%PARM5]
JCXZ DONE
CLD
REP
MOVSB
DONE POP AX
MOV DS,AX
POP BP
RETSEG
END

205
Mix Power C v1/MSDOS.C Normal file
View File

@ -0,0 +1,205 @@
/* MSDOS Functions */
/* Copyright (c) Mix Software 1988 */
chdir(dirname)
char *dirname;
{
extern int errno;
extern int _doserrno;
int result;
int _sys_ad();
if (_sys_ad(0x3b00,dirname,&result) == 0) return 0;
errno = ENOENT;
return -1;
}
/* ------------------------------------------------------------ */
char *getcwd(pathbuf,n) /* get current working directory */
char *pathbuf; /* buffer for result */
int n; /* maximum length of result */
{
extern int errno,_doserrno;
int drive;
char buf[64];
char *path;
union REGS reg;
if (pathbuf == NULL) {
pathbuf = malloc(n);
if (pathbuf == NULL) return NULL;
}
reg.x.ax = 0x4700;
reg.h.dl = 0;
reg.x.si = buf;
intdos(&reg,&reg);
if (reg.x.cflag) { errno = _doserrno; return -1; }
if (strlen(buf)+3 >= n) { errno = ERANGE; return -1; }
drive = _sys_al(0x1900);
path = pathbuf;
*path++ = drive + 'A';
*path++ = ':';
*path++ = '\\';
strcpy(path,buf);
return pathbuf;
}
/* ------------------------------------------------------------ */
getch()
{
extern int _ungetch;
int ch = _ungetch;
if (ch != EOF) {
_ungetch = EOF;
return ch;
}
else return _sys_al(0x0700);
}
/* ------------------------------------------------------------ */
void putch(c)
int c;
{
int s;
_sys_ad(0x0600,c,&s);
}
/* ------------------------------------------------------------ */
getche()
{
return _sys_al(0x0100);
}
/* ------------------------------------------------------------ */
getkey()
{
union REGS reg;
int bdosx();
reg.h.dl = 0xFF;
if (bdosx(0x06, &reg) & 0x40) return EOF;
else return reg.h.al;
}
/* ------------------------------------------------------------ */
int isatty(fd)
int fd;
{
union REGS reg;
reg.x.ax = 0x4400;
reg.x.bx = fd;
reg.x.cx = 0;
reg.x.dx = 0;
intdos(&reg,&reg);
if (reg.x.cflag != 0) return 0;
if ((reg.x.dx & 0x0080) == 0) return 0; else return 1;
}
/* ------------------------------------------------------------ */
int kbhit()
{
return _sys_al(0x0b00);
}
/* ------------------------------------------------------------ */
keypress()
{
return _sys_al(0x0b00);
}
/* ------------------------------------------------------------ */
unlink(name)
char *name;
{
extern int errno, _doserrno;
int _sys_ad();
int result;
if (_sys_ad(0x4100,name,&result) == 0) return 0;
errno = _doserrno;
return -1;
}
/* ------------------------------------------------------------ */
remove(name)
char *name;
{
extern int errno, _doserrno;
int _sys_ad();
int result;
if (_sys_ad(0x4100,name,&result) == 0) return 0;
errno = _doserrno;
return -1;
}
/* ------------------------------------------------------------ */
mkdir(dirname)
char *dirname;
{
extern int errno, _doserrno;
int _sys_ad();
int result;
if (_sys_ad(0x3900,dirname,&result) == 0) return 0;
errno = _doserrno;
return -1;
}
/* ------------------------------------------------------------ */
rmdir(dirname)
char *dirname;
{
extern int errno, _doserrno;
int _sys_ad();
int result;
if (_sys_ad(0x3A00,dirname,&result) == 0) return 0;
errno = _doserrno;
return -1;
}
/* ------------------------------------------------------------ */
rename(oldname, newname)
char *oldname, *newname;
{
int _sysdxdi();
int result;
extern int errno;
return _sysdxdi(0x5600,oldname,newname,&result);
}
/* ------------------------------------------------------------ */
int sbrk(incr)
int incr;
{ return -1; }
int brk(endds)
int endds;
{ return -1; }
/* ------------------------------------------------------------ */
int getpid()
{
static unsigned _pid = 0;
extern unsigned char _osmajor;
union REGS reg;
if (_pid != 0) return _pid;
if (_osmajor > 3) _pid = _sys_al(0x8700);
if (_pid == 0) {
reg.h.ah = 0x2c;
intdos(&reg,&reg);
_pid = reg.x.dx;
}
return _pid;
}

270
Mix Power C v1/NEW.ASM Normal file
View File

@ -0,0 +1,270 @@
;
; Copyright (c) Mix Software 1988
;
IDT alloc
DEF alloc
IF UPPER
DEF ALLOC
ENDIF
FREF $$ALLOC
alloc equ $
ALLOC JMPFAR $$ALLOC
END
;
IDT calloc
DEF calloc
IF UPPER
DEF CALLOC
ENDIF
FREF $$CALLOC
calloc equ $
CALLOC JMPFAR $$CALLOC
END
;
IDT malloc
DEF malloc
IF UPPER
DEF MALLOC
ENDIF
FREF $$MALLOC
malloc equ $
MALLOC JMPFAR $$MALLOC
END
;
; --------------------------------------------------
; new - allocate a block of heap
; --------------------------------------------------
;
IDT $$ALLOC
DEF $$CALLOC
DEF $$MALLOC
DEF $$ALLOC
DEF _nmalloc
REF $$HPTERM
FREF $_FATAL
FREF $$NEW$$
REF errno
;
; calloc(number,size) - block is number*size bytes in length
;
$$CALLOC PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
MUL [BP][%PARM2]
JC NOSPACE ; multiply overflows
CALLFAR $$NEW$$
RETURN TEST AX,AX ; out of space?
JZ NOSPACE
IGNORE POP BP
RETSEG
NOSPACE MOV [errno],ENOMEM
TEST %[$$HPTERM],%>FF ; teminate on heap full?
JZ IGNORE
MOV AX,E$HEAP
PUSH AX
CALLFAR $_FATAL
POP AX
XOR AX,AX
JMPS IGNORE
;
; alloc(size) - block is size bytes in length
;
_nmalloc EQU $
$$ALLOC EQU $
$$MALLOC PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1]
CALLFAR $$NEW$$
JMPS RETURN
END
;
; $_NEW(ptr,size)
; ptr is address of a pointer to receive the result
; size is the size of the block in bytes
;
IDT $_NEW
DEF $_NEW
REF $$HPTERM
FREF $$NEW$$
FREF $_FATAL
REF errno
$_NEW PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM1] ; size
CALLFAR $$NEW$$
MOV BX,[BP][%PARM2] ; pointer
MOV [BX],AX
TEST AX,AX ; out of space?
JZ NOSPACE
IGNORE POP BP
RETSEG
NOSPACE MOV [errno],ENOMEM
TEST %[$$HPTERM],%>FF ; teminate on heap full?
JZ IGNORE
MOV AX,E$HEAP
PUSH AX
CALLFAR $_FATAL
POP AX
XOR AX,AX
JMPS IGNORE
END
;
;
; ----------------------------------------------------------
; NEW$$ - Allocate a block from the heap
; ----------------------------------------------------------
; inputs:
; AX - required length of the packet
; outputs:
; AX - pointer to the packet; 0 if none available
; REGISTERS USED:
; uses ax, bx, cx, dx, di
;
;
IDT $$NEW$$
DEF $$NEW$$
REF $$FREE
REF $$CURH
REF $$MAXH
;
$$NEW$$ MOV CX,AX
ADD CX,%3 ; reserve two bytes for length
AND CL,%#FE ; Round up if size is odd
;
; if size is less than 6, set to 6
;
CMP CX,%6
JAE NEW01
MOV CX,6 ; MINIMUM SIZE IS 6
;
; SET BX TO POINT TO THE CURRENT FREE LIST
;
NEW01 MOV BX,[$$FREE]
;
; SEARCH FREE LIST FOR A PACKET OF SUFFICIENT SIZE
;
NEWLOOP CMP CX,[BX] ; COMPARE LENGTHS
JBE NEW02
JMP NEW03 ; NOT LARGE ENOUGH
;
; THE CURRENT PACKET IS LARGE ENOUGH
; REMOVE NEEDED SPACE & CHECK RESULT FOR > 6
;
NEW02 MOV AX,[BX] ; GET PACKET SIZE
SUB AX,CX ; SUBTRACT NEEDED SPACE
CMP AX,6 ; LARGE ENOUGH?
JAE NEW04
MOV CX,[BX] ; SET SIZE TO WHOLE PACKET
;
; LESS THAN 6 BYTES ARE LEFT, SO ALLOCATE THE ENTIRE PACKET
; LENGTH IS IN CX, LOCATION IS IN BX
;
MOV AX,[BX][2] ; GET SUCCESSOR FIELD
MOV [$$FREE],AX ; NEW FREE LIST
MOV DX,[BX][4] ; DX = PREDECESSOR
;
; LAST+2 := NEXT
;
XCHG BX,DX
MOV [BX][2],AX ; SET PRED@.NEXT TO CUR@.NEXT
XCHG BX,DX
;
; NEXT+4 := LAST
;
XCHG BX,AX
MOV [BX][4],DX ; SET NEXT@.LAST TO CUR@.LAST
XCHG BX,AX
JMPS NEW05
;
; THE REMAINDER OF THE CURRENT PACKET IS LONG ENOUGH
;
; REDUCE THE SIZE OF THE PACKET
; AX CONTAINS THE NEW LENGTH
; CX CONTAINS THE LENGTH OF THE REQUESTED PACKET
; BX CONTAINS THE PACKET ADDRESS
;
NEW04 MOV DX,BX ; SAVE CURRENT PACKET ADDR
ADD BX,CX ; BX <-- ADDR OF NEW FREE PKT
MOV [BX],AX ; SET NEW LENGTH
;
; SET SUCCESSOR OF NEW FREE PACKET TO SUCCESSOR OF OLD
; FREE PACKET & PREDECESSOR OF NEW TO PREDECESSOR OF OLD
; IE. MOVE 4 BYTES FROM (DE) TO (HL)
;
MOV DI,DX
MOV AX,[DI][2] ; OLD SUCCESSOR
MOV [BX][2],AX
MOV AX,[DI][4]
MOV [BX][4],AX
;
; DI CONTAINS OLD FREE PACKET
; BX CONTAINS NEW FREE PACKET
;
MOV AX,[BX][2] ; GET SUCCESSOR
MOV [$$FREE],AX ; NEW FREE LIST POINTER
XCHG BX,AX
MOV [BX][4],AX ; NEXT@.PRED = NEW FREE PKT
XCHG AX,BX
MOV AX,[BX][4] ; GET PREDECESSOR
XCHG AX,BX
MOV [BX][2],AX ; PREV@.SUCC = NEW FREE PKT
XCHG AX,BX
MOV BX,DX
;
; AT THIS POINT CX CONTAINS THE LENGTH OF THE NEWLY ALLOCATED
; PACKET, AND BX CONTAINS ITS ADDRESS
;
; SET THE LENGTH OF THE NEWLY ALLOCATED PACKET. LENGTH+1, WHICH
; IS ODD, IS USED TO MARK THE PACKET AS ALLOCATED
;
NEW05 MOV [BX],CX
INC [BX] ; MAKE LENGTH ODD
INC BX ; POINT TO DATA AREA
INC BX
;
; ADD SIZE OF CURRENT PACKET TO CURRENT HEAP ALLOCATED
;
ADD [$$CURH],CX ; ADD TO CURRENT ALLOCATION
MOV AX,[$$CURH] ; LARGER THAN MAX USED?
CMP AX,[$$MAXH]
JB NEW08
MOV [$$MAXH],AX ; SET MAXIMUM HEAP USED
NEW08 EQU $
; TEST %[$$ZFILL],>FF ; ZERO FILL?
; JZ NEW10 ; NO ZERO FILL
MOV DX,BX ; SAVE POINTER
MOV DI,BX
CLD
MOV AX,DS
MOV ES,AX
SHR CX,1 ; LENGTH IN WORDS
DEC CX ; ALLOW FOR LENGTH FIELD
MOV AX,0
REP
STOSW
MOV AX,DX
RETSEG
NEW10 MOV AX,BX
RETSEG ; DONE
;
;
; THE CURRENT PACKET IN THE FREE LIST IS NOT LARGE ENOUGH
; MOVE TO THE NEXT PACKET
; BX CONTAINS THE ADDRESS OF THE CURRENT PACKET
; CX CONTAINS THE REQUIRED SIZE
;
NEW03 MOV BX,[BX][%2] ; POINT TO SUCCESSOR
;
; CHECK THE CURRENT PACKET AGAINST THE FREELIST POINTER.
; IF CURRENT=FREELIST, THEN ALL PACKETS HAVE BEEN EXAMINED,
; AND THE REQUEST CANNOT BE SATISFIED
;
CMP BX,[$$FREE]
JZ NEW11
JMP NEWLOOP
;
; UNABLE TO ALLOCATE
;
NEW11 MOV AX,0
RETSEG
END

251
Mix Power C v1/NHEAP.ASM Normal file
View File

@ -0,0 +1,251 @@
;
; Copyright (c) Mix Software 1988
;
; --------------------------------------------------
; _fmalloc - allocate from far heap
; if no memory available, allocate from near heap
; char far *_fmalloc(size)
; unsigned size;
; --------------------------------------------------
;
IDT _fmalloc
DEF _fmalloc
FREF falloc
FREF malloc
;
_fmalloc MOV SI,SP
PUSH [SI][%PARM1-2]
CALLFAR falloc
ADD SP,%2
MOV CX,DX
OR CX,AX
JNZ OK
MOV SI,SP
PUSH [SI][%PARM1-2]
CALLFAR malloc
ADD SP,%2
TEST AX,AX
JZ NULL
MOV DX,DS
OK RETSEG
NULL XOR DX,DX
RETSEG
END
;
; --------------------------------------------------
; _ffree - release from near or far heap
; void _ffree(ptr)
; char far *ptr;
; --------------------------------------------------
;
IDT _ffree
DEF _ffree
FREF ffree
FREF free
;
_ffree MOV SI,SP
MOV AX,[SI][%PARM2-2]
MOV CX,DS
CMP AX,CX
JZ NEAR
PUSH AX
PUSH [SI][%PARM1-2]
CALLFAR ffree
ADD SP,%4
RETSEG
NEAR PUSH [SI][%PARM1-2]
CALLFAR free
ADD SP,%2
RETSEG
END
;
; --------------------------------------------------
; _nmsize - return the size of a memory block
; unsigned _nmsize(ptr)
; char near *ptr;
; --------------------------------------------------
;
IDT _nmsize
DEF _nmsize
DEF _msize
;
_msize EQU $
_nmsize MOV SI,SP
MOV BX,[SI][%PARM1-2]
MOV AX,[BX][%-2] ; get size and allocated flag
AND AX,>FFFE
SUB AX,%2
RETSEG
END
;
; --------------------------------------------------
; _memavl - return the byte count of available memory
; unsigned _memavl()
; --------------------------------------------------
;
IDT _memavl
REF $$CURH
REF $$HMIN
REF $$HMAX
DEF _memavl
;
_memavl MOV AX,[$$HMAX]
SUB AX,[$$HMIN]
SUB AX,[$$CURH]
SUB AX,6
RETSEG
END
;
; --------------------------------------------------
; coreleft - return the byte count of available memory
; unsigned coreleft()
; --------------------------------------------------
;
IDT coreleft
REF $$CURH
REF $$HMIN
REF $$HMAX
DEF coreleft
;
coreleft MOV AX,[$$HMAX]
SUB AX,[$$HMIN]
SUB AX,[$$CURH]
SUB AX,6
RETSEG
END
;
; --------------------------------------------------
; _freect - return the number of items in heap
; unsigned _freect(size)
; unsigned size;
; --------------------------------------------------
;
IDT _freect
REF $$CURH
REF $$HMIN
REF $$HMAX
DEF _freect
;
_freect MOV AX,[$$HMAX]
SUB AX,[$$HMIN]
SUB AX,[$$CURH]
SUB AX,6
MOV BX,SP
MOV BX,[BX][%PARM1-2]
XOR DX,DX
TEST BX,BX
JZ EXIT
DIV BX
EXIT RETSEG
END
;
; --------------------------------------------------
; _expand - expand a block of memory without moving it
; _expand(ptr,size)
; char *ptr;
; unsigned size; /* requested new size */
; --------------------------------------------------
;
IDT _expand
DEF _expand
IF UPPER
DEF _EXPAND
ENDIF
REF $$FREE
REF $$CURH
REF $$MAXH
FREF free
;
_EXPAND EQU $
_expand PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1]
MOV CX,[BX][%-2] ; get size and allocated flag
TEST CX,>0001
JZ AVAIL
SUB CX,%3 ; remove flag and overhead
CMP CX,[BP][%PARM2]
JB EXPAND ; Make larger
;
; Try to shrink the block
; If shrink is by at least 6 bytes, create a new pointer
; and use free to release it.
;
SHRINK SUB CX,[BP][%PARM2]
NEG CX
AND CX,>FFFE ; Must be an even number
CMP CX,%6
JB FREEOK ; Not enough to free
SUB [BX][%-2],CX ; Remove from this block count
ADD BX,[BX][%-2] ; Point to end of block
DEC BX ; remove allocated flag
INC CX
MOV [BX][%-2],CX ; create allocated block header
PUSH BX
CALLFAR free
POP BX
MOV AX,[BP][%PARM1]
POP BP
RETSEG
;
; Try to expand the block.
; the next higher block must be free
;
EXPAND MOV SI,[$$FREE] ; Start of free list
MOV DX,SI
ADD BX,CX ; Point to next block header
SEARCH CMP SI,BX ; Found next block?
JZ FOUND
MOV SI,[SI][%2] ; Move to next free block
CMP SI,DX ; Full circuit?
JNZ SEARCH
JMPS NULLEXIT ; unable to expand
FOUND CMP [SI],6
JBE NULLEXIT ; protect anchor
MOV DI,[SI][%4] ; predecessor
MOV BX,[SI][%2] ; successor
MOV [DI][%2],BX
MOV [BX][%4],DI ; block linked out
MOV CX,[SI] ; length of the free block
ADD [$$CURH],CX
MOV AX,[$$CURH]
CMP AX,[$$MAXH]
JBE ADJUST
MOV [$$MAXH],AX
ADJUST MOV BX,[BP][%PARM1] ; merge block
ADD CX,[BX][%-2]
MOV [BX][%-2],CX ; Blocks are merged
SUB CX,%3
JMPS SHRINK ; Return the excess
;
; Block is free - it has therefore already become as large as
; possible. Check size to generate return value
;
AVAIL SUB CX,%2
CMP CX,[BP][%PARM2]
JAE FREEOK ; Large enough
NULLEXIT XOR AX,AX
POP BP
RETSEG
FREEOK MOV AX,BX
POP BP
RETSEG
END
;
; --------------------------------------------------
; heapsiz - return the byte count of available memory
; unsigned heapsiz()
; --------------------------------------------------
;
IDT heapsiz
REF $$CURH
REF $$HMIN
REF $$HMAX
DEF heapsiz
;
heapsiz MOV AX,[$$HMAX]
SUB AX,[$$HMIN]
SUB AX,[$$CURH]
SUB AX,6
RETSEG
END

254
Mix Power C v1/OPEN.C Normal file
View File

@ -0,0 +1,254 @@
/* Open/Create files */
/* Copyright (c) Mix Software 1988 */
/* ------------------------------------------------------------ */
FILE *fdopen(fd, type)
int fd;
char *type;
{
FILE *fp;
int c;
int mode;
if (fd < 0 || fd > MAXFILES) return NULL;
fp = _iob[fd];
if (fp == NULL) return NULL;
c = *type;
if (c == 'r') mode = O_RDONLY; else mode = O_WRONLY;
if (*++type == '+') mode = O_RDWR;
if (c == 'a') {
if ((fp->file.flags & fdappend) == 0) return NULL;
}
if (fp->file.mode == mode) return fp;
return NULL;
}
/* ------------------------------------------------------------ */
FILE *freopen(filename, type, old_fp)
char *filename, *type;
FILE *old_fp;
{
FILE *new_fp;
int old_fd, new_fd;
FILE *fopen();
old_fd = fileno(old_fp);
if (fclose(old_fp)) return NULL;
if ((new_fp = fopen(filename, type)) == NULL) return NULL;
new_fd = fileno(new_fp);
if (new_fd != old_fd) { /* keep same file number */
_iob[new_fd] = _iob[old_fd];
_iob[old_fd] = new_fp;
new_fp->fd = old_fd;
if (_iob[new_fd] != NULL) _iob[new_fd]->fd = new_fd;
}
}
/* ------------------------------------------------------------ */
FILE *fopen(name,modes)
char *name, *modes;
{
char ch;
int fd, mode, rw;
ch = tolower(*modes);
mode = 0;
if (ch == 'r') rw = O_RDONLY;
else if (ch == 'w') {rw = O_WRONLY; mode = O_CREAT|O_TRUNC;}
else if (ch == 'a') {rw = O_RDWR; mode = O_CREAT|O_APPEND;}
else return NULL;
if (*++modes == '+') {
rw = O_RDWR;
++modes;
}
ch = tolower(*modes);
if (ch == 'b') mode |= O_BINARY;
else if (ch == 't') mode |= O_TEXT;
fd = _open(name,mode|rw,S_IREAD|S_IWRITE);
if (fd < 0) return NULL;
return _iob[fd];
}
/* ------------------------------------------------------------ */
creat(name, pmode)
char *name;
int pmode;
{
return _open(name,O_CREAT|O_WRONLY|O_TRUNC,pmode);
}
/* ------------------------------------------------------------ */
creatnew(name, attrib)
char *name;
int attrib;
{
int fd, status;
fd = _open(name,O_CREAT|O_RDWR|O_TRUNC|O_EXCL|O_BINARY,S_IREAD|S_IWRITE);
if (fd != -1) _sys_acd(0x4300,attrib,name,&status);
return fd;
}
/* ------------------------------------------------------------ */
_creat(name, attrib)
char *name;
int attrib;
{
int fd, status;
fd = _open(name,O_CREAT|O_RDWR|O_TRUNC|O_BINARY,S_IREAD|S_IWRITE);
if (fd != -1) _sys_acd(0x4300,attrib,name,&status);
return fd;
}
/* ------------------------------------------------------------ */
sopen(name, oflag, shflag, pmode)
char *name;
int oflag;
int shflag;
int pmode;
{
return _open(name,oflag|shflag,pmode);
}
/* ------------------------------------------------------------ */
open(name, mode, pmode)
char *name;
int mode;
int pmode;
{
return _open(name,mode,pmode);
}
/* ------------------------------------------------------------ */
_open(name, mode, pmode)
char *name;
int mode;
int pmode;
{
int fd;
FILE *fp;
extern int $$BUFSIZ;
extern char $$CCTLZ;
extern int errno, _doserrno;
extern char _fmode;
extern int _umask_;
extern int (*_fileerr)();
extern int (*_fclose)();
int fclose();
int handle;
int flmode;
int crmode;
int chmode = 0;
_fclose = fclose;
flmode = mode & O_MODEMASK;
crmode = pmode & (~_umask_);
crmode = ((crmode & S_IWRITE) == 0) ? 1 : 0;
if (mode & O_TRUNC) {
if ((mode & O_CREAT) == 0) {
if (_sys_ad(0x3d00,name,&handle) != 0) goto doserror;
_sys_ab(0x3e00,handle,&handle);
}
else {
if (mode & O_EXCL) {
if (_sys_ad(0x3d00,name,&handle) == 0) {
_sys_ab(0x3e00,handle,&handle);
errno = EEXIST;
return -1;
}
}
} /* create */
if (_sys_acd(0x3c00,0,name,&handle) != 0) goto doserror;
chmode = crmode;
if (flmode != O_RDWR) {
_sys_ab(0x3e00,handle,&handle);
if (_sys_ad(0x3d00+flmode,name,&handle) != 0) goto doserror;
}
} /* trunc */
else {
if (_sys_ad(0x3d00+flmode,name,&handle) != 0) { /* not found */
if (mode & O_CREAT) {
if (_sys_acd(0x3c00,0,name,&handle) != 0) goto doserror;
chmode = crmode;
if (flmode != O_RDWR) {
_sys_ab(0x3e00,handle,&handle);
if (_sys_ad(0x3d00+flmode,name,&handle) != 0)
goto doserror;
}
} /* create */
else goto doserror;
} /* file does not exist */
else {
if (mode & O_CREAT) {
if (mode & O_EXCL) {
_sys_ab(0x3e00,handle,&handle);
errno = EEXIST;
return -1;
}
}
} /* file exists */
} /* not trunc */
/* file is open and file handle is set */
if (chmode != 0) {
_sys_acd(0x4301,chmode,name,&chmode);
}
fp = malloc(sizeof(FILE));
fd = handle;
if (fd >= MAXFILES || _iob[fd] != NULL || fp == NULL) {
_sys_ab(0x3e00,handle,&handle);
errno = EMFILE;
return -1;
}
_iob[fd] = fp;
setmem(fp,sizeof(FILE),0);
fp->fd = fd;
fp->file.pathnm = strsave(name);
fp->file.handle = fd;
fp->file.init = 'C';
fp->file.openflg = 1;
fp->file.mode = flmode & 0x0003;
if (mode & O_BINARY) fp->file.flags = fdbinary;
else if (mode & O_TEXT) fp->file.flags = fdfilter;
else {
if (_fmode == 'b') fp->file.flags = fdbinary;
else fp->file.flags = fdfilter;
}
if (fp->file.flags == fdfilter) {
if ($$CCTLZ) fp->file.flags |= fdctlz;
}
if ($$BUFSIZ == 0) fp->file.flags |= fdunbufr;
else {
fp->file.ptr = fp->file.bufr = malloc($$BUFSIZ);
if (fp->file.ptr == NULL) fp->file.flags |= fdunbufr;
else fp->file.bufsize = $$BUFSIZ;
}
if (mode & O_APPEND) fp->file.flags |= fdappend;
return fd;
doserror:
errno = _doserrno;
return -1;
} /* _open */
char _fmode = 't';
/* ------------------------------------------------------------ */
int umask(pmode)
int pmode;
{
extern int _umask_;
int old;
old = _umask_;
_umask_ = pmode;
return old;
}
int _umask_ = 0;

BIN
Mix Power C v1/PC.EXE Normal file

Binary file not shown.

BIN
Mix Power C v1/PC87.MIX Normal file

Binary file not shown.

BIN
Mix Power C v1/PCA.EXE Normal file

Binary file not shown.

BIN
Mix Power C v1/PCAUTO.MIX Normal file

Binary file not shown.

BIN
Mix Power C v1/PCDMY.MIX Normal file

Binary file not shown.

BIN
Mix Power C v1/PCIEEE.MIX Normal file

Binary file not shown.

BIN
Mix Power C v1/PCL.EXE Normal file

Binary file not shown.

10
Mix Power C v1/PCLIB.BAT Normal file
View File

@ -0,0 +1,10 @@
echo off
pc pclib.prj
if errorlevel 1 goto stop
if exist pclib.mix del pclib.mix
merge pclib init printf scanf stdlib io errors lib
if errorlevel 1 goto stop
goto end
:stop
echo Errors building pclib
:end

BIN
Mix Power C v1/PCLIB.MIX Normal file

Binary file not shown.

25
Mix Power C v1/PCLIB.PRJ Normal file
View File

@ -0,0 +1,25 @@
init init.asm
pca init
printf printf.c stdarg.h stdio.h dos.h
pc /f- printf
scanf scanf.c stdarg.h stdio.h
pc /f- scanf
stdlib std_lib.h fdb.h init.c convert.c rand.c gets.c puts.c open.c \
exit.c setbuf.c file.c close.c sort.c strcoll.c memory.c msdos.c \
ungetc.c envir.c bios.c
io.mix io.asm libdef.asm read.asm write.asm put.asm get.asm \
seek.asm flush.asm
pca io
errors std_lib.h error.c
lib.mix lib.asm libdef.asm sys.asm setmem.asm movmem.asm string.asm \
to.asm envir.asm nheap.asm new.asm free.asm farstr1.asm farstr.asm \
farheap.asm div.asm long.asm far.asm setjmp.asm stack.asm inout.asm \
fatal.asm
pca lib

10
Mix Power C v1/PCLIB2.BAT Normal file
View File

@ -0,0 +1,10 @@
echo off
pc pclib2.prj
if errorlevel 1 goto stop
if exist pclib2.mix del pclib2.mix
merge pclib2 graphics screen stdlib2 lib2
if errorlevel 1 goto stop
goto end
:stop
echo Error creating pclib2
:end

BIN
Mix Power C v1/PCLIB2.MIX Normal file

Binary file not shown.

14
Mix Power C v1/PCLIB2.PRJ Normal file
View File

@ -0,0 +1,14 @@
graphics
screen.mix screen.asm fillm.asm
pca screen
stdlib2 std_lib.h fstat.c dup.c dstring.c time.c bessel.c arith.c \
tempfile.c chain.c flags.c locking.c perror.c allocmem.c \
findfirs.c dosetc.c etc.c
lib2.mix lib2.asm libdef.asm farmem.asm sound.asm absdisk.asm \
biosfn.asm disable.asm intent.asm signal.asm exec.asm dtafat.asm \
intrpt.asm intr.asm peek.asm
pca lib2

BIN
Mix Power C v1/PCO.EXE Normal file

Binary file not shown.

75
Mix Power C v1/PEEK.ASM Normal file
View File

@ -0,0 +1,75 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; peek(segment, offset) - read a word from memory
; unsigned segment;
; unsigned offset;
; -------------------------------------------------------
;
IDT peek
DEF peek
;
peek MOV BX,SP
MOV ES,[BX][%PARM1-2]
MOV SI,[BX][%PARM2-2]
SEGES
MOV AX,[SI]
RETSEG
END
;
; -------------------------------------------------------
; peekb(segment, offset) - read a byte from memory
; unsigned segment;
; unsigned offset;
; -------------------------------------------------------
;
IDT peekb
DEF peekb
;
peekb MOV BX,SP
MOV ES,[BX][%PARM1-2]
MOV SI,[BX][%PARM2-2]
SEGES
MOV AL,[SI]
XOR AH,AH
RETSEG
END
;
; -------------------------------------------------------
; poke(segment, offset, value) - store a word
; unsigned segment;
; unsigned offset;
; int value;
; -------------------------------------------------------
;
IDT poke
DEF poke
;
poke MOV BX,SP
MOV ES,[BX][%PARM1-2]
MOV SI,[BX][%PARM2-2]
MOV AX,[BX][%PARM3-2]
SEGES
MOV [SI],AX
RETSEG
END
;
; -------------------------------------------------------
; pokeb(segment, offset, value) - store a byte
; unsigned segment;
; unsigned offset;
; int value;
; -------------------------------------------------------
;
IDT pokeb
DEF pokeb
;
pokeb MOV BX,SP
MOV ES,[BX][%PARM1-2]
MOV SI,[BX][%PARM2-2]
MOV AL,[BX][%PARM3-2]
SEGES
MOV [SI],AL
RETSEG
END

95
Mix Power C v1/PERROR.C Normal file
View File

@ -0,0 +1,95 @@
/* Error message functions */
/* Copyright (c) Mix Software 1988 */
dosexterr(struct DOSERROR *buffer)
{
union REGS reg;
int intdos();
reg.x.ax = 0x5900;
reg.x.bx = 0;
intdos(&reg,&reg);
if (buffer == NULL) return reg.x.ax;
buffer->exterror = reg.x.ax;
buffer->class = reg.h.bh;
buffer->action = reg.h.bl;
buffer->locus = reg.h.ch;
return buffer->exterror;
}
perror(s)
char *s;
{
fputs(s, stderr); fputc(':', stderr);
fputs(strerror(NULL),stderr);
}
#define ERRmaxln 32
char *strerror(string)
char *string;
{
extern int errno;
extern int sys_nerr;
extern char *sys_errlist[];
extern char *int_errlist[];
static char unknown[] = "Error cause unknown\n";
static char *buffer = NULL;
char *msg;
if (errno <= sys_nerr) msg = sys_errlist[errno];
else {
if (errno > 0x80 && errno < 0x97)
msg = int_errlist[errno-0x81];
else msg = unknown;
}
if (string == NULL) return msg;
if (buffer == NULL) buffer = malloc(94+4+ERRmaxln);
if (buffer == NULL) return NULL;
strncpy(buffer,string,94);
strcat(buffer,": ");
strcat(buffer,msg);
return buffer;
}
int sys_nerr = 17;
char *sys_errlist[] = {"No Errors\n",
"Invalid Function Number\n",
"File not Found\n",
"Path not Found\n",
"No More File Handles\n",
"File Access Denied\n",
"Invalid File Handle\n",
"Memory Blocks Destroyed\n",
"Insufficient Memory\n",
"Invalid Block Address\n",
"Invalid Environment\n",
"Invalid Format\n",
"Invalid Access Code\n",
"Invalid Data\n",
"Invalid Drive\n",
"Can't Remove Current Directory\n",
"Not Same Device\n",
"No More Files\n" };
char *int_errlist[] = {"Out of Stack\n",
"Out of Heap\n",
"Damaged Stack or Heap\n",
"Damaged Stack or Heap\n",
"Divide by Zero\n",
"Invalid Instruction\n",
"Damaged Stack or Heap\n",
"Damaged Stack or Heap\n",
"I/O Error\n",
"Error Cause Unknown\n",
"Attempt to Write Input\n",
"File Not Open\n",
"Attempt to Read Output\n",
"No Memory for File Buffer\n",
"Error Cause Unknown\n",
"Damaged Stack or Heap\n",
"Bad Digit in Number\n",
"Damaged Stack or Heap\n",
"Arithmetic Overflow\n",
"Error Cause Unknown\n",
"Arithmetic Underflow\n",
"Log of Negative Number\n",
"Sqrt of Negative Number\n" };

589
Mix Power C v1/PRINTF.C Normal file
View File

@ -0,0 +1,589 @@
/* printf */
/* Copyright (c) Mix Software 1988 */
#include "stdio.h"
#include "stdarg.h"
#include "dos.h"
static signflag; /* signed value flag */
static plusflag; /* include + sign for positive values */
static blankflag; /* include blank for positive values */
static poundflag; /* numeric format flag */
static upperflag; /* upper case flag for X, E & G formats */
static precision; /* precision of numbers */
static farflag; /* far pointer flag used by _eint */
static farhalf; /* half of a far pointer */
static va_list parms; /* pointer to parameters */
printf(fs) /* standard routine */
char *fs;
{
int fputc();
int _write();
int count;
va_start(parms, fs);
count = _output(stdout, fs, fputc, _write);
return ferror(stdout) ? -1 : count;
}
fprintf(fp, fs) /* standard routine */
FILE *fp;
char *fs;
{
int fputc();
int _write();
int count;
va_start(parms, fs);
count = _output(fp, fs, fputc, _write);
return ferror(fp) ? -1 : count;
}
sprintf(s,fs)
char *s;
char *fs;
{
int _mputc();
int _mwrite();
int count;
va_start(parms,fs);
count = _output(&s, fs, _mputc, _mwrite);
*s = '\0';
return count;
}
cprintf(fs)
char *fs;
{
int putch();
int _cwrite();
va_start(parms, fs);
return _output(0, fs, putch, _cwrite);
}
vprintf(fs, argptr) /* standard routine */
char *fs;
char *argptr;
{
int fputc();
int _write();
int count;
parms = argptr;
count = _output(stdout, fs, fputc, _write);
return ferror(stdout) ? -1 : count;
}
vfprintf(fp, fs, argptr) /* standard routine */
FILE *fp;
char *fs;
char *argptr;
{
int fputc();
int _write();
int count;
parms = argptr;
count = _output(fp, fs, fputc, _write);
return ferror(fp) ? -1 : count;
}
vsprintf(s, fs, argptr) /* standard routine */
char *s;
char *fs;
char *argptr;
{
int _mputc();
int _mwrite();
int count;
parms = argptr;
count = _output(&s, fs, _mputc, _mwrite);
*s = '\0';
return count;
}
_output(fp, format, putc, write) /* output routine for */
/* printf, sprintf, fprintf */
char *fp; /* pointer to destination */
char *format; /* pointer to format string */
int (*putc)(); /* pointer to output function */
int (*write)(); /* pointer to output function */
{
char *bufptr; /* pointer into buffer */
char far *fbufptr; /* far pointer into buffer */
char c; /* current character */
char padchar; /* pad character */
int count=0; /* count of characters output */
int ljflag; /* left justify flag */
int longflag; /* long ("l") present in format */
int Nflag; /* near pointer flag */
int Fflag; /* far pointer flag */
int length; /* length of output string */
int len; /* length of output string */
int flag; /* ftoa edit flag */
int left; /* number digits left of decimal */
int right; /* number digits right of decimal */
int width; /* mimimum field width */
char buffer[255]; /* encode buffer */
char null[]="(null)"; /* print this for %s with NULL pointer */
STRING *dynamic; /* dynamic string pointer */
int (*enc)(); /* pointer to encode function */
int _eint(); /* encode integer function */
int _elong(); /* encode long function */
int _atoi(); /* convert string to integer */
int _ftoaflag(); /* get format flag for ftoa function */
int strlen(); /* determine length of string */
while (c = *format) {
if (c != '%') {
(*putc)(c,fp);
count++;
format++;
continue;
}
precision = -1;
bufptr = buffer;
ljflag = signflag = blankflag = poundflag = longflag
= upperflag = plusflag = Nflag = Fflag = 0;
flags: switch (*(++format)) {
case '-': ++ljflag; goto flags;
case '+': ++plusflag; goto flags;
case ' ': ++blankflag; goto flags;
case '#': ++poundflag; goto flags;
}
padchar = (*format == '0') ? '0' : ' ';
if (*format == '*') {
++format;
if ((width = va_arg(parms, int)) < 0) {
width = -width;
++ljflag;
}
}
else width = _atoi(&format);
if ((*format) == '.') {
++format;
if (*format == '*') {
++format;
precision = va_arg(parms, int);
}
else precision = _atoi(&format);
}
enc = _eint;
if (((c = *format++) == 'l') || c == 'L') {
c = *format++;
enc = _elong;
longflag++;
}
else if (c == 'h') c = *format++;
else if (c == 'N') {
Nflag++;
c = *format++;
}
else if (c == 'F') {
Fflag++;
c = *format++;
}
switch(c) {
case 'i': /* signed decimal */
case 'd':
signflag++;
(*enc)(buffer, 10);
length = strlen(bufptr);
break;
case 'u': /* unsigned decimal */
(*enc)(buffer, 10);
length = strlen(bufptr);
break;
case 'o': /* unsigned octal */
(*enc)(buffer, 8);
length = strlen(bufptr);
break;
case 'X': upperflag++; /* unsigned hexadecimal */
case 'x':
(*enc)(buffer, 16);
length = strlen(bufptr);
break;
case 'p': /* pointer */
precision = 4;
upperflag++;
poundflag = 0;
#ifdef LARGE
if (Nflag) {
_eint(buffer, 16);
length = 4;
}
else {
farflag++;
bufptr = va_arg(parms, char*);
farhalf = FP_SEG(bufptr);
_eint(buffer, 16);
buffer[4] = ':';
farhalf = FP_OFF(bufptr);
_eint(buffer + 5, 16);
length = 9;
farflag = 0;
}
#else
if (Fflag) {
farflag++;
fbufptr = va_arg(parms, char far*);
farhalf = FP_SEG(fbufptr);
_eint(buffer, 16);
buffer[4] = ':';
farhalf = FP_OFF(fbufptr);
_eint(buffer + 5, 16);
length = 9;
farflag = 0;
}
else {
_eint(buffer, 16);
length = 4;
}
#endif
break;
case 's': /* string */
#ifdef LARGE
if (Nflag) bufptr = va_arg(parms, char near*);
else bufptr = va_arg(parms, char*);
if (bufptr == NULL) {
bufptr = null;
length = 6;
break;
}
length = strlen(bufptr);
if (precision >= 0 && length > precision)
length = precision;
break;
#else
if (Fflag) {
fbufptr = va_arg(parms, char far*);
if (fbufptr == NULL) {
bufptr = null;
length = 6;
break;
}
length = _fstrlen(fbufptr);
if (precision >= 0 && length > precision)
length = precision;
width = width - length;
if (!ljflag) {
c = *fbufptr;
if (padchar == '0' && (c == '-' || c == '+')) {
--length;
(*putc)(c, fp);
fbufptr++;
count++;
}
while (width-- > 0) (*putc)(padchar, fp);
}
while (length > 0) {
len = length < 256 ? length : 255;
_fmemcpy((char far*) buffer, fbufptr, len);
(*write)(fp, buffer, len);
count += len;
fbufptr += len;
length -= len;
}
while (width-- > 0) {
(*putc)(padchar,fp);
count++;
}
continue;
}
else {
bufptr = va_arg(parms, char*);
if (bufptr == NULL) {
bufptr = null;
length = 6;
break;
}
length = strlen(bufptr);
if (precision >= 0 && length > precision)
length = precision;
break;
}
#endif
case 'c': /* character */
buffer[0] = va_arg(parms, int);
buffer[1] = '\0';
length = 1;
break;
case 'E': upperflag++; /* exponential */
case 'e':
flag = 1;
goto reals;
case 'G': upperflag++; /* no trailing 0's */
case 'g':
/* fixed or exponential? */
if (precision < 0) precision = 6;
flag = _ftoaflag(parms, poundflag, precision);
goto reals;
case 'f': /* fixed point */
flag = 0;
reals:
if (plusflag) flag |= 8;
else if (blankflag) flag |= 136;
if (precision < 0) right = 6;
else right = precision;
left = 1;
ftoa(va_arg(parms, double), bufptr, flag, left, right);
length = 0;
while (c=buffer[length]) {
if (poundflag == 0) {
if (c == '.' && precision == 0) {
strcpy(&buffer[length], &buffer[length+1]);
continue;
}
}
if (c == 'e' && upperflag) buffer[length] = 'E';
else if (c == 'E' && !upperflag) buffer[length] = 'e';
++length;
}
break;
case 'n':
*(va_arg(parms, int*)) = count;
continue;
case 'y': /* dynamic string */
dynamic = va_arg(parms, STRING*);
length = dynamic->length;
bufptr = dynamic->string;
break;
default : /* format string character */
(*putc)(c, fp);
count++;
continue;
}
width = width - length;
if (!ljflag) {
if (padchar == '0' && (*bufptr == '-' || *bufptr == '+')) {
--length;
(*putc)(*bufptr++, fp);
count++;
}
while (width-- > 0) {
(*putc)(padchar, fp);
count++;
}
}
(*write)(fp,bufptr,length);
count += length;
while (width-- > 0) {
(*putc)(padchar,fp);
count++;
}
}
return count;
}
_eint(bufptr, base) /* encode an integer */
char *bufptr; /* pointer to encode buffer */
int base; /* number base */
{
char buffer[7];
char *ptr = buffer;
int i;
if (farflag) i = farhalf;
else i = va_arg(parms, int);
if (precision == 0 && i == 0) *bufptr = '\0';
else {
if (base == 10) {
if (signflag) {
if (i < 0) {
*bufptr++ = '-';
i = -i;
}
else if (plusflag) *bufptr++ = '+';
else if (blankflag) *bufptr++ = ' ';
}
_dtoa(i, &ptr);
}
else if (base == 16) {
if (poundflag && i) {
*bufptr++ = '0';
*bufptr++ = upperflag ? 'X' : 'x';
}
_htoa(i, &ptr);
}
else {
if (poundflag && i) {
*bufptr++ = '0';
}
_otoa(i, &ptr);
}
*ptr = '\0';
for (i=precision-strlen(buffer); i > 0; i--) *bufptr++ = '0';
strcpy(bufptr, buffer);
}
}
_dtoa(n, bufptr) /* decimal integer encode routine */
unsigned n; /* unsigned integer */
char **bufptr; /* pointer to the buffer pointer */
{
if (n < 10) *(*bufptr)++ = n + 48;
else {
_dtoa(n/10, bufptr);
_dtoa(n%10, bufptr);
}
}
_htoa(n, bufptr) /* hexadecimal integer encode routine */
unsigned n; /* unsigned integer */
char **bufptr; /* pointer to the buffer pointer */
{
if (n < 16) {
if (n < 10) *(*bufptr)++ = n + 48;
else *(*bufptr)++ = upperflag ? n + 55 : n + 87;
}
else {
_htoa(n/16, bufptr);
_htoa(n%16, bufptr);
}
}
_otoa(n, bufptr) /* octal integer encode routine */
unsigned n; /* unsigned integer */
char **bufptr; /* pointer to the buffer pointer */
{
if (n < 8) *(*bufptr)++ = n + 48;
else {
_otoa(n/8, bufptr);
_otoa(n%8, bufptr);
}
}
_elong(bufptr, base) /* encode a long */
char *bufptr; /* pointer to encode buffer */
int base; /* number base */
{
char buffer[12];
char *ptr = buffer;
int i;
long l;
l = va_arg(parms, long);
if (precision == 0 && l == 0) *bufptr = '\0';
else {
if (base == 10) {
if (signflag) {
if (l < 0) {
*bufptr++ = '-';
l = -l;
}
else if (plusflag) *bufptr++ = '+';
else if (blankflag) *bufptr++ = ' ';
}
_ldtoa(l, &ptr);
}
else if (base == 16) {
if (poundflag && l) {
*bufptr++ = '0';
*bufptr++ = upperflag ? 'X' : 'x';
}
_lhtoa(l, &ptr);
}
else {
if (poundflag && l) {
*bufptr++ = '0';
}
_lotoa(l, &ptr);
}
*ptr = '\0';
for (i = precision - strlen(buffer); i > 0; i--) *bufptr++ = '0';
strcpy(bufptr, buffer);
}
}
_ldtoa(l, bufptr) /* long decimal encode routine */
unsigned long l; /* long integer */
char **bufptr; /* pointer to the buffer pointer */
{
if (l < 10) *(*bufptr)++ = l + 48;
else {
_ldtoa(l/10, bufptr);
_ldtoa(l%10, bufptr);
}
}
_lhtoa(l, bufptr) /* long hexadecimal encode routine */
long l; /* long integer */
char **bufptr; /* pointer to the buffer pointer */
{
int i, start;
int digit[9];
digit[8] = 1;
for (i = 7; i >= 0; i--) {
digit[i] = l & 0xf;
l = l >> 4;
}
start = 0;
while (digit[start] == 0) start++;
if (start == 8) *(*bufptr)++ = '0';
else {
for (i = start; i < 8; i++) {
if (digit[i] < 10) *(*bufptr)++ = digit[i] + 48;
else *(*bufptr)++ = upperflag ? digit[i] + 55 : digit[i] + 87;
}
}
}
_lotoa(l, bufptr) /* long octal encode routine */
long l; /* long integer */
char **bufptr; /* pointer to the buffer pointer */
{
int i, start;
int digit[12];
digit[11] = 1;
for (i = 10; i > 0; i--) {
digit[i] = l & 7;
l = l >> 3;
}
digit[0] = l & 3;
start = 0;
while (digit[start] == 0) start++;
if (start == 11) *(*bufptr)++ = '0';
else {
for (i = start; i < 11; i++)
*(*bufptr)++ = digit[i] + 48;
}
}
_mputc(c, fp) /* write c to fp */
int c;
char **fp;
{
*(*fp)++ = c;
return c;
}
_mwrite(fp, s, n)
char **fp;
char *s;
int n;
{
int i;
for (i=0; i < n; i++) *(*fp)++ = *s++;
return n;
}
_cwrite(fp, s, n)
int fp;
char *s;
int n;
{
int i;
for (i=0; i < n; i++) putch(*s++);
return n;
}

32
Mix Power C v1/PROCESS.H Normal file
View File

@ -0,0 +1,32 @@
/*$no list*//*$no trace <<< process.h >>> */
/* Copyright (c) Mix Software 1988 */
extern int _p_overlay;
#define P_WAIT 0
#define P_NOWAIT 1
#define P_OVERLAY _p_overlay
void abort(void);
int execl(char *filename, char *arg0, ...);
int execle(char *filename, char *arg0, ...);
int execlp(char *filename, char *arg0, ...);
int execlpe(char *filename, char *arg0, ...);
int execv(char *filename, char *argv[]);
int execve(char *filename, char *argv[], char *envp[]);
int execvp(char *filename, char *argv[]);
int execvpe(char *filename, char *argv[], char *envp[]);
void exit(int status);
void _exit(int status);
int getpid(void);
int spawnl(int mode, char *filename, char *arg0, ...);
int spawnle(int mode, char *filename, char *arg0, ...);
int spawnlp(int mode, char *filename, char *arg0, ...);
int spawnlpe(int mode, char *filename, char *arg0, ...);
int spawnv(int mode, char *filename, char *argv[]);
int spawnve(int mode, char *filename, char *argv[], char *envp[]);
int spawnvp(int mode, char *filename, char *argv[]);
int spawnvpe(int mode, char *filename, char *argv[], char *envp[]);
int system(char *cmdstring);
/*$list*//*$trace <<< process.h >>> */

222
Mix Power C v1/PUT.ASM Normal file
View File

@ -0,0 +1,222 @@
;
; Copyright (c) Mix Software 1988
;
; fputc(c,fp)
; int c;
; FILE *fp;
;
IDT fputc
DEF fputc
FREF _rflush
FREF _putc
fputc MOV BX,SP
MOV SI,[BX][%PARM2-2]
TEST SI,SI
JZ ENDFL
;
; if (fp == NULL || !fp->file.init || !fp->file.openflg) return EOF;
;
; TEST SI,SI ; File ok?
; JZ ENDFL
; CMP %[SI][%FD$INIT],%0
; JZ ENDFL
; CMP %[SI][%FD$OPEN],%0
; JZ ENDFL
;
; if (fp->file.dirty & fdread) {
; if (_rflush(fp) != 0) return EOF;
;
TEST %[SI][%FD$DIRTY],%FL$READ
JNZ FLUSH
;
; if (c != NEWLINE) {
;
NOFLUSH MOV AX,[BX][%PARM1-2]
CMP AL,>0A
JZ NEWLINE
;
; if (fp->file.count--) return (*(fp->file.ptr++) = c);
;
MOV CX,[SI][%FD$COUNT]
JCXZ BUFFULL
DEC CX
MOV [SI][%FD$COUNT],CX
MOV DI,[SI][%FD$PTR]
MOV %[DI],AL
INC DI
MOV [SI][%FD$PTR],DI
RETSEG
;
; else {
; fp->file.count++;
; return _putc(c,fp); } }
;
BUFFULL PUSH SI
PUSH AX
CALLFAR _putc
ADD SP,%4
RETSEG
;
; if ( (fp->file.flags & fdbinary) ||
; ((fp->file.flags & fdfilter) == 0) ) return _putc(c,fp);
;
NEWLINE TEST [SI][%FD$FLAGS],%FL$LFEED
JZ NOCR
;
; if (_putc('\r',fp) == EOF) return EOF;
;
PUSH SI
MOV AX,>000D
PUSH AX
CALLFAR _putc
POP DX
POP SI
INC AX
JNZ PUTLF
DEC AX
RETSEG
PUTLF MOV AX,>000A
NOCR PUSH SI
PUSH AX
;
; return _putc(c,fp);
;
CALLFAR _putc
ADD SP,%4
RETSEG
;
FLUSH PUSH SI
CALLFAR _rflush
POP SI
MOV BX,SP
TEST AX,AX
JZ NOFLUSH
;
ENDFL MOV AX,-1
RETSEG
END
;
;
; _putc(c,fp)
; int c;
; FILE *fp;
;
; Lowest level file output (one character)
; file validity has already been checked
;
IDT _putc
DEF _putc
FREF _fflush
FREF _seekend
REF _fileerr
DISKFULL EQU >009A
;
_putc PUSH BP
MOV BP,SP
MOV SI,[BP][%PARM2]
;
; if (fp->file.device == 'o') {
; _sys_adx(0x0200,c);
; return c; }
;
CMP %[SI][%FD$DEV],'o'
JNZ NOTSTD
MOV DX,[BP][%PARM1]
MOV AX,>0200
INT >21
MOV AX,[BP][%PARM1]
POP BP
RETSEG
;
; if (fp->file.count--) return (*(fp->file.ptr++) = c);
;
NOTSTD MOV AX,[BP][%PARM1]
MOV CX,[SI][%FD$COUNT]
JCXZ BUFFULL
DEC CX
MOV [SI][%FD$COUNT],CX
MOV DI,[SI][%FD$PTR]
MOV %[DI],AL
INC DI
MOV [SI][%FD$PTR],DI
EXIT POP BP
RETSEG
;
; fp->file.count = 0;
;
BUFFULL MOV [SI][%FD$COUNT],0
;
; if (fp->file.device == 'd') return c;
;
CMP [SI][%FD$DEV],'d'
JZ EXIT
;
; if (fp->file.dirty & fdwrite) {
; if (_fflush(fp) != 0) return EOF; }
;
TEST %[SI][%FD$DIRTY],%FL$WRITE
JZ NOFLUSH
PUSH SI
CALLFAR _fflush
POP SI
TEST AX,AX
JNZ ENDFL
;
; if (fp->file.flags & fdunbufr) {
; if (_sysabcd(0x4000,fp->file.handle,1,&c,&status) != 0) {
; (*_fileerr)(status,fp);
; return EOF; }
;
NOFLUSH TEST %[SI][%FD$FLAGS],%FL$UNBUF
JZ USEBUFR
; Seek to end of file if append mode
TEST [SI][%FD$FLAGS],FL$APPEN
JNZ PUTACHAR
PUSH SI
CALLFAR _seekend
POP SI
PUTACHAR LEA DX,[BP][%PARM1]
MOV BX,[SI][%FD$HNDL]
MOV CX,1
MOV AX,>4000
INT >21
JNB OK1
ERROR PUSH [BP][%PARM2]
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%4
ENDFL MOV AX,-1
POP BP
RETSEG
;
; return c;
;
OK1 EQU $
CMP AX,1
JZ OK2
MOV AX,DISKFULL
JMPS ERROR
OK2 MOV AX,[BP][%PARM1]
POP BP
RETSEG
;
; fp->file.ptr = fp->file.bufr;
; fp->file.count = fp->file.bufsize - 1;
; *fp->file.ptr++ = c;
; fp->file.dirty |= fdwrite;
; return c;
;
USEBUFR MOV BX,[SI][%FD$BUFR]
MOV AX,[SI][%FD$BUFSZ]
DEC AX
MOV [SI][%FD$COUNT],AX
MOV AX,[BP][%PARM1]
MOV %[BX],AL
INC BX
MOV [SI][%FD$PTR],BX
OR %[SI][%FD$DIRTY],%FL$WRITE
POP BP
RETSEG
;
END

60
Mix Power C v1/PUTS.C Normal file
View File

@ -0,0 +1,60 @@
/* String output to files */
/* Copyright (c) Mix Software 1988 */
/* ------------------------------------------------------------ */
char *puts(s) /* write s to stdout */
char *s;
{
int _write();
int strlen();
int count;
count = strlen(s);
if (_write(stdout, s, count) != count) return EOF;
if (fputc('\n', stdout) != EOF) return s;
else return EOF;
}
/* ------------------------------------------------------------ */
int _printf_(s) /* write s to stdout */
char *s;
{
int _write();
int strlen();
int count = 0;
if (s == NULL) return 0;
while (*s != '\0') {
if (*s == '%') ++s;
if (fputc(*s,stdout) == EOF) return EOF;
++count;
++s;
}
return count;
}
/* ------------------------------------------------------------ */
char *fputs(s, fp) /* write s to fp */
char *s;
FILE *fp;
{
int _write();
int strlen();
int count;
count = strlen(s);
if (_write(fp, s, count) != count) return EOF;
else return s;
}
/* ------------------------------------------------------------ */
char *cputs(s) /* write s to console */
char *s;
{
int putch();
while (*s) putch(*s++);
return s;
}

51
Mix Power C v1/RAND.C Normal file
View File

@ -0,0 +1,51 @@
/* Random numbers */
/* Copyright (c) Mix Software 1988 */
/* ------------------------------------------------------------ */
double drand(n)
int n;
{
extern double (far *$0DFIXR)();
double d;
d = (double) rand() / (double) 0x7FFF;
if (n == 0) return d;
return $0DFIXR(d * n);
}
/* ------------------------------------------------------------ */
rand()
{
extern long _seed;
_seed = _seed * 15790321;
return (int) ((_seed >> 17) & 0x7FFF);
}
/* ------------------------------------------------------------ */
void srand(seed)
unsigned seed;
{
extern long _seed;
union REGS r;
union {
long lval;
struct {
unsigned lsword;
unsigned msword;
} words;
} val;
if (seed == 1) _seed = 13849l;
else {
r.x.ax = 0x2c00;
intdos(&r,&r);
val.words.lsword = r.x.dx;
val.words.msword = r.x.cx;
_seed = val.lval;
}
}
long _seed = 13849;

360
Mix Power C v1/READ.ASM Normal file
View File

@ -0,0 +1,360 @@
;
; Copyright (c) Mix Software 1988
;
; fread(buffer,itemsize,no_of_items,fp)
; char *buffer;
; int itemsize;
; int no_of_items;
; FILE *fp;
; { return (read(fp->fd,buffer,itemsize*no_of_items) / itemsize); }
;
IDT fread
DEF fread
FREF read
fread MOV BX,SP
MOV SI,[BX][%PARM4-2]
MOV AX,[BX][%PARM2-2]
MOV CX,[BX][%PARM3-2]
CMP AX,1
JZ FREAD1SZ
CMP CX,%1
JZ FREAD1I
MUL CX
PUSH AX
PUSH [BX][%PARM1-2]
PUSH [SI][FD$SIZE]
CALLFAR read
ADD SP,%6
MOV BX,SP
MOV CX,[BX][%PARM2-2]
CWD
DIV CX
RETSEG
;
; Item size is 1
;
FREAD1SZ PUSH CX
PUSH [BX][%PARM1-2]
PUSH [SI][FD$SIZE]
CALLFAR read
ADD SP,%6
RETSEG
;
; Number of items is 1
;
FREAD1I PUSH AX
PUSH [BX][%PARM1-2]
PUSH [SI][FD$SIZE]
CALLFAR read
ADD SP,%6
MOV BX,SP
CMP AX,[BX][%PARM2-2]
JZ ONE
MOV CX,[BX][%PARM2-2]
CWD
DIV CX
RETSEG
ONE MOV AX,1
RETSEG
END
;
; ------------------------------------------------------------
;
; read(fd, buffer, n)
; int n;
; int fd;
; char *buffer;
;
IDT read
DEF read
FREF _fflush
FREF _getc
REF _iob
REF _fileerr
read PUSH BP
MOV BP,SP
;
; FILE *fp = _iob[fd];
;
MOV SI,[BP][%PARM1]
ADD SI,SI
ADD SI,_iob
MOV SI,[SI]
;
; if (fp == NULL || !fp->file.init || !fp->file.openflg) return 0;
;
; TEST SI,SI ; File ok?
; JZ ENDFL
; CMP %[SI][%FD$INIT],%0
; JZ ENDFL
; CMP %[SI][%FD$OPEN],%0
; JZ ENDFL
;
; if (fp->file.dirty & fdwrite) {
; if (_fflush(fp) != 0) return 0;
; }
;
TEST %[SI][%FD$DIRTY],%FL$WRITE
JZ NOFLUSH
PUSH SI
CALLFAR _fflush
POP SI
TEST AX,AX
JNZ ENDFL
;
; if (fp->file.flags & fdfilter) {
; if (!(fp->file.flags & fdctlz)) {
;
NOFLUSH MOV AL,[SI][%FD$FLAGS]
TEST AL,%FL$LFEED
JZ NOCR
;
; Read and filter carriage return (but not ctlz)
;
; while (n-- != 0) {
; c = _getc(fp);
; while (c == RETURN) c = _getc(fp);
; if (c==EOF) {
; readcount = readcount-n-1;
; n = 0;
; }
; else *buffer++ = c;
; }
;
; bx = file
; si = file buffer
; di = buffer address
; dx = count remaining
; cx = buffer count
;
MOV BX,SI
MOV DI,[BP][%PARM2]
MOV DX,[BP][%PARM3] ; Requested count
TEST DX,DX
JZ DONE1
MOV SI,[BX][%FD$PTR]
MOV CX,[BX][%FD$COUNT]
TEST AL,%FL$CTLZ
JNZ CR_CTLZ
JCXZ MORE1
MOV AX,DS
MOV ES,AX
COPY1 LODSB ; Get a byte
NEXTCH1 CMP AL,>0D
JZ SKIPCR1
STOSB ; Store in read buffer
DEC DX ; count character read
JZ DONE1A ; read complete
SKIPCR1 LOOP COPY1
MORE1 MOV [BX][%FD$COUNT],CX ; Use _getc to get more
MOV [BX][%FD$PTR],SI ; into buffer
PUSH DX ; Save context
PUSH DI
PUSH BX ; Pass fp to _getc
CALLFAR _getc
MOV BX,DS
MOV BX,BX
POP BX
POP DI
POP DX
MOV SI,[BX][%FD$PTR]
MOV CX,[BX][%FD$COUNT]
INC CX
CMP AX,-1
JNZ NEXTCH1
DONE1 MOV AX,[BP][%PARM3]
SUB AX,DX
POP BP
RETSEG
DONE1A DEC CX
DONE1B MOV [BX][%FD$COUNT],CX
MOV [BX][%FD$PTR],SI
JCXZ DONE1
MOV %[BX][%FD$DIRTY],%FL$READ
JMPS DONE1
ENDFL XOR AX,AX
POP BP
RETSEG
;
; No filtering for end of line characters
;
NOCR TEST %[SI][%FD$FLAGS],%FL$CTLZ
JZ BINMODE
;
; while (n-- != 0) {
; c = _getc(fp);
; if ((c==EOF) || (c == 0x1a) {
; readcount = readcount-n-1;
; n = 0; }
; else *buffer++ = c;
;
MOV CX,[BP][%PARM3]
MOV DI,[BP][%PARM2]
JCXZ ENDFL3
CPYCTLZ PUSH CX
PUSH DI
PUSH SI
CALLFAR _getc
POP SI
POP DI
POP CX
CMP AX,-1
JZ ENDFL3
CMP AX,>001A
JZ ENDFL3
MOV %[DI],AL
INC DI
LOOP CPYCTLZ
ENDFL3 MOV AX,[BP][%PARM3]
SUB AX,CX
POP BP
RETSEG
;
;
CR_CTLZ JCXZ MORE2
COPY2 LODSB ; Get a byte
NEXTCH2 CMP AL,>0D
JZ SKIPCR2
CMP AL,>1A
JZ DONE1B
MOV %[DI],AL ; Store in read buffer
INC DI
DEC DX ; count character read
JZ DONE1A ; read complete
SKIPCR2 LOOP COPY2
MORE2 MOV [BX][%FD$COUNT],CX ; Use _getc to get more
MOV [BX][%FD$PTR],SI ; into buffer
PUSH DX ; Save context
PUSH DI
PUSH BX ; Pass fp to _getc
CALLFAR _getc
POP BX
POP DI
POP DX
MOV SI,[BX][%FD$PTR]
MOV CX,[BX][%FD$COUNT]
INC CX
CMP AX,-1
JNZ NEXTCH2
JMPS DONE1
;
; if (movcount = fp->file.count) {
; if (movcount > n) movcount = n;
; movmem(fp->file.ptr,buffer,movcount);
; buffer += movcount;
; fp->file.ptr += movcount;
; fp->file.count -= movcount;
; n -= movcount;
; }
;
BINMODE TEST [SI][%FD$FLAGS],%FL$UNBUF
JZ BUFR
JMP NOBUFR
BUFR XOR DX,DX ; already read is 0
MOV DI,[BP][%PARM2] ; buffer pointer
BINMOVE MOV CX,[SI][%FD$COUNT]
JCXZ NOMOVE
MOV AX,[BP][%PARM3]
SUB AX,DX ; Additional needed
CMP CX,AX
JB MOVEALL
MOV CX,AX ; Use only part of buffer
MOVEALL PUSH CX
MOV AX,DS
MOV ES,AX
PUSH SI
MOV SI,[SI][%FD$PTR]
CLD
REP
MOVSB
MOV BX,SI
POP SI
POP CX
SUB [SI][%FD$COUNT],CX
MOV [SI][%FD$PTR],BX
;
; CX contains count of moved characters
;
; if (n) {
; if (_sysabcd(0x3f00,fp->file.handle,n,buffer,&readcount) != 0) {
; (*_fileerr)(readcount,fp);
; return 0;
; }
; else {
; if (readcount==0) fp->file.eofflag = 1;
; return movcount+readcount;
; }
; }
;
NOMOVE ADD DX,CX
MOV CX,[BP][%PARM3]
SUB CX,DX ; Characters left
JCXZ DONE4
CMP CX,[SI][%FD$BUFSZ]
JA READDIR
MOV BX,[SI][%FD$HNDL]
MOV AX,>3F00
PUSH DX
MOV DX,[SI][%FD$BUFR]
MOV [SI][%FD$PTR],DX
MOV CX,[SI][%FD$BUFSZ]
INT >21
JNB READOK1
FLERROR PUSH SI
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%4
POP DX
MOV [SI][%FD$COUNT],0
DONE4 MOV AX,DX
POP BP
RETSEG
READOK1 POP DX
MOV [SI][%FD$COUNT],AX
TEST AX,AX
JZ DONE4
JMPS BINMOVE
;
READDIR MOV AX,[SI][%FD$BUFR]
MOV [SI][%FD$PTR],AX
MOV [SI][%FD$COUNT],0
MOV AX,>3F00
MOV BX,[SI][%FD$HNDL]
MOV CX,[BP][%PARM3]
SUB CX,DX
PUSH DX
MOV DX,DI
INT >21
JB FLERROR
POP DX
ADD AX,DX
POP BP
RETSEG
;
NOBUFR MOV DI,[BP][%PARM2]
TEST [SI][%FD$FLAGS],FL$BIN
JZ NOBUFR0
XOR DX,DX
JMPS READDIR
NOBUFR0 MOV CX,[BP][%PARM3]
JCXZ ENDFL5
UNBUF PUSH CX
PUSH DI
PUSH SI
CALLFAR _getc
POP SI
POP DI
POP CX
CMP AX,-1
JZ ENDFL5
; CMP AX,>001A
; JZ ENDFL5
MOV %[DI],AL
INC DI
LOOP UNBUF
ENDFL5 MOV AX,[BP][%PARM3]
SUB AX,CX
POP BP
RETSEG
END

555
Mix Power C v1/SCANF.C Normal file
View File

@ -0,0 +1,555 @@
/* scanf */
/* Copyright (c) Mix Software 1988 */
#include "stdio.h"
#include "stdarg.h"
static va_list parms; /* pointer to parameters */
static int base; /* number base */
static int ch; /* input character */
scanf(fs) /* standard routine */
char *fs;
{
int getc();
int ungetc();
va_start(parms, fs);
return _input(stdin, fs, getc, ungetc);
}
fscanf(fp, fs) /* standard routine */
char *fp, *fs;
{
int getc();
int ungetc();
va_start(parms, fs);
return _input(fp, fs, getc, ungetc);
}
sscanf(s,fs) /* standard routine */
char *s, *fs;
{
int _mread();
int _mungetc();
va_start(parms, fs);
return _input(&s, fs, _mread, _mungetc);
}
cscanf(fs)
char *fs;
{
static int _getche();
static int _un_getche();
va_start(parms, fs);
return _input(stdin, fs, _getche, _un_getche);
}
_input(fp, format, read, ungetc) /* input routine for */
/* scanf, sscanf, fscanf */
char *fp; /* pointer to input */
char *format; /* pointer to format string */
int (*read)(); /* character read function */
int (*ungetc)(); /* character unget function */
{
char c; /* format string character */
char *bufptr; /* pointer to buffer */
char far *fptr; /* far pointer to character */
int value; /* value of current digit */
int asflag; /* assignment supression flag */
int sflag; /* sign flag */
int lflag; /* long flag */
int iflag; /* flag for %i format */
int Nflag; /* Near pointer flag */
int Fflag; /* Far pointer flag */
int i; /* loop counter */
int width; /* maximum field width */
int valid; /* valid real number format */
int caret; /* flag for %[^ format */
int count=0; /* character count */
int number=0; /* number of characters read */
union {
int i;
long l;
char *ptr;
char near *nptr;
char far *fptr;
struct {
int offset;
int segment;
} half;
} accum; /* accumulator */
char buffer[256]; /* floating point string buffer */
int _digit(); /* decode digit function */
int _atoi(); /* convert string to integer */
int isspace(); /* isspace function */
int isdigit(); /* isdigit function */
char *strchr(); /* search for character in string */
double atof(); /* atof function */
STRING *stods(); /* convert string to dynamic string */
while (c = *format++) {
if (isspace(c)) {
while (isspace(*format)) format++;
while (isspace(ch = (*read)(fp))) number++;
(*ungetc)(ch, fp);
continue;
}
if (c != '%') {
number++;
if ((ch = (*read)(fp)) == c) continue;
else {
if (ch == EOF) return EOF;
else {
(*ungetc)(ch,fp);
return count;
}
}
}
sflag = asflag = lflag = Nflag = Fflag = iflag = 0;
if ((*format) == '*') { /* check for assignment suppression */
++asflag;
++format;
}
if (isdigit(*format)) width = _atoi(&format);
else width = -1;
if (*format == 'N') {
format++;
Nflag++;
}
else if (*format == 'F') {
format++;
Fflag++;
}
if (*format == 'l' || *format == 'L') { /* check for double precision */
format++;
lflag++;
}
else if (*format == 'h') format++;
if (width == 0) {
format++;
continue;
}
switch (*format++) {
case 'o': /* unsigned octal */
base = 8;
goto decode;
case 'X':
case 'x': /* unsigned hexadecimal */
base = 16;
goto decode;
case 'i': /* signed decimal, 0 or 0x prefix OK */
iflag++;
base = 10;
goto decode;
case 'd': /* signed decimal */
case 'u':
base = 10;
decode:
while (isspace(ch=(*read)(fp))) number++;
if (ch == EOF) return EOF;
number++;
width--;
if (width && (ch == '+' || ch == '-')) {
if (ch == '-') ++sflag;
if ((ch = (*read)(fp)) == EOF) return EOF;
number++;
width--;
}
if (iflag) {
if ((ch == '0') && width) {
base = 8;
if ((ch = (*read)(fp)) == 'x' || ch == 'X') {
number++;
width--;
base = 16;
if (width) {
ch = (*read)(fp);
number++;
width--;
}
if (ch == EOF) return EOF;
}
else {
(*ungetc)(ch, fp);
ch = '0';
}
}
}
accum.l = _digit();
if (accum.i == -1) {
(*ungetc)(ch,fp);
return count;
}
while (width) {
ch = (*read)(fp);
if ((value = _digit()) == -1) {
(*ungetc)(ch, fp);
break;
}
width--;
number++;
if (lflag)
accum.l = accum.l * base + value;
else
accum.i = accum.i * base + value;
}
if (!asflag) {
if (lflag) {
if (sflag) accum.l = -accum.l;
#ifdef LARGE
if (Nflag) *(va_arg(parms, long near*)) = accum.l;
#else
if (Fflag) *(va_arg(parms, long far*)) = accum.l;
#endif
else *(va_arg(parms, long*)) = accum.l;
}
else {
if (sflag) accum.i = -accum.i;
#ifdef LARGE
if (Nflag) *(va_arg(parms, int near*)) = accum.i;
#else
if (Fflag) *(va_arg(parms, int far*)) = accum.i;
#endif
else *(va_arg(parms, int*)) = accum.i;
}
count++;
}
break;
case 's': /* string */
while (isspace(ch=(*read)(fp))) number++;
if (ch == EOF) return EOF;
if (!asflag) {
#ifdef LARGE
if (Nflag) fptr = va_arg(parms, char near*);
#else
if (Fflag) fptr = va_arg(parms, char far*);
#endif
else fptr = va_arg(parms, char*);
}
while (!isspace(ch) && ch != EOF && width) {
if (!asflag) *fptr++ = ch;
ch = (*read)(fp);
number++;
width--;
}
(*ungetc)(ch,fp);
if (!asflag) {
*fptr = '\0';
++count;
}
break;
case '[': /* string delimited by [character set] */
if (!asflag) {
#ifdef LARGE
if (Nflag) fptr = va_arg(parms, char near*);
#else
if (Fflag) fptr = va_arg(parms, char far*);
#endif
else fptr = va_arg(parms, char*);
}
i = caret = 0;
if (*format == '^') {
caret++;
format++;
}
if (*format == ']' || *format == '-')
buffer[i++] = *format++;
while (i < 255 && *format != ']') {
if (*format == '-') {
format++;
c = buffer[i-1];
if (*format != ']' && *format > c) {
for (c++; i < 255 && c <= *format; c++)
buffer[i++] = c;
format++;
}
else buffer[i++] = '-';
}
else buffer[i++] = *format++;
}
format++;
buffer[i] = '\0';
i = number;
while (((caret && strchr(buffer, ch=(*read)(fp))==NULL) ||
(!caret && strchr(buffer, ch=(*read)(fp))!=NULL)) &&
ch != EOF && width) {
if (!asflag) *fptr++ = ch;
number++;
width--;
}
(*ungetc)(ch,fp);
if (number == i) return count;
if (!asflag) {
*fptr = '\0';
++count;
}
break;
case 'c': /* character */
if ((ch = (*read)(fp)) == EOF) return EOF;
number++;
if (!asflag) {
#ifdef LARGE
if (Nflag) fptr = va_arg(parms, char near*);
#else
if (Fflag) fptr = va_arg(parms, char far*);
#endif
else fptr = va_arg(parms, char*);
*fptr = ch;
++count;
}
if (width > 0) {
width--;
while (width > 0) {
if ((ch = (*read)(fp)) == EOF) return EOF;
number++;
width--;
if (!asflag) *(++fptr) = ch;
}
}
break;
case 'n':
if (lflag) {
#ifdef LARGE
if (Nflag) *(va_arg(parms, int near*)) = number;
#else
if (Fflag) *(va_arg(parms, int far*)) = number;
#endif
else *(va_arg(parms, int*)) = number;
}
else {
#ifdef LARGE
if (Nflag) *(va_arg(parms, long near*)) = number;
#else
if (Fflag) *(va_arg(parms, long far*)) = number;
#endif
else *(va_arg(parms, long*)) = number;
}
break;
case 'p':
while (isspace(ch=(*read)(fp))) number++;
if (ch == EOF) return EOF;
number++;
width--;
base = 16;
accum.half.segment = 0;
accum.i = _digit();
if (accum.i == -1) {
(*ungetc)(ch,fp);
return count;
}
while (width) {
ch = (*read)(fp);
if ((value = _digit()) == -1) {
(*ungetc)(ch, fp);
break;
}
width--;
number++;
accum.l = (accum.l << 4) + value;
}
#ifdef LARGE
if (!Nflag && ch == ':') {
#else
if (Fflag && ch == ':') {
#endif
(*read)(fp); /* consume the ':' */
accum.half.segment = accum.half.offset;
accum.half.offset = 0;
while (width) {
ch = (*read)(fp);
if ((value = _digit()) == -1) {
(*ungetc)(ch, fp);
break;
}
width--;
number++;
accum.half.offset=(accum.half.offset << 4) + value;
}
}
if (!asflag) {
#ifdef LARGE
if (Nflag) *(va_arg(parms, char near**)) = accum.nptr;
#else
if (Fflag) *(va_arg(parms, char far**)) = accum.fptr;
#endif
else *(va_arg(parms, char **)) = accum.ptr;
count++;
}
break;
case 'e':
case 'E':
case 'f': /* floating point */
case 'g':
case 'G':
while (isspace(ch=(*read)(fp))) number++;
if (ch == EOF) return EOF;
valid = 0;
bufptr = buffer;
if (ch == '+' || ch == '-') {
*bufptr++ = ch;
ch = (*read)(fp);
number++;
width--;
}
while ((ch >= '0' && ch <= '9') && width) {
*bufptr++ = ch;
valid++;
ch = (*read)(fp);
number++;
width--;
}
if (ch == '.' && width) {
*bufptr++ = ch;
ch = (*read)(fp);
number++;
width--;
}
while ((ch >= '0' && ch <= '9') && width) {
*bufptr++ = ch;
valid++;
ch = (*read)(fp);
number++;
width--;
}
if ((ch == 'E' || ch == 'e') && valid && width) {
*bufptr++ = 'E';
ch = (*read)(fp);
number++;
width--;
if ((ch == '+' || ch == '-') && width) {
*bufptr++ = ch;
ch = (*read)(fp);
number++;
width--;
}
while ((ch >= '0' && ch <= '9') && width) {
*bufptr++ = ch;
ch = (*read)(fp);
number++;
width--;
}
}
(*ungetc)(ch, fp);
if (!valid) return count;
*bufptr = '\0';
if (!asflag) {
if (lflag) {
#ifdef LARGE
if (Nflag)
*(va_arg(parms, double near*)) = atof(buffer);
#else
if (Fflag)
*(va_arg(parms, double far*)) = atof(buffer);
#endif
else
*(va_arg(parms, double*)) = atof(buffer);
}
else {
#ifdef LARGE
if (Nflag)
*(va_arg(parms, float near*)) = atof(buffer);
#else
if (Fflag)
*(va_arg(parms, float far*)) = atof(buffer);
#endif
else
*(va_arg(parms, float*)) = atof(buffer);
}
++count;
}
break;
#ifdef DYNAMIC
case 'y': /* dynamic string */
while (isspace(ch=(*read)(fp))) number++;
if (ch == EOF) return EOF;
i = 0;
bufptr = buffer;
while (width && !isspace(ch) && ch != EOF) {
if (i < 255) *bufptr++ = ch;
ch = (*read)(fp);
number++;
width--;
}
*bufptr = '\0';
(*ungetc)(ch,fp);
if (!asflag) {
*(va_arg(parms, char**)) = stods(buffer);
++count;
}
break;
#endif
default :
number++;
if ((ch = (*read)(fp)) == *(format-1)) continue;
else {
if (ch == EOF) return EOF;
else {
(*ungetc)(ch,fp);
return count;
}
}
}
}
return count;
}
_digit() /* decode ch to binary */
{
int n;
if (ch >= '0' && ch <= '9') n = ch - 48;
else if (ch >= 'A' && ch <= 'F') n = ch - 55;
else if (ch >= 'a' && ch <= 'f') n = ch - 87;
else return -1;
if (n < base) return n;
else return -1;
}
_mread(s) /* read character from string */
char **s; /* pointer to string */
{
if (*(*s) != '\0') return *(*s)++;
else return EOF;
}
_mungetc(c,s) /* unget character to string */
int c; /* dumy parameter */
char **s; /* pointer to string pointer */
{
if (c != EOF) *(--(*s)) = c;
return c;
}
static _getche()
{
extern static int _un_getch;
int ch = _un_getch;
if (ch != EOF) {
_un_getch = EOF;
return ch;
}
else return getche();
}
static _un_getche(ch)
int ch;
{
extern static int _un_getch;
if (_un_getch != EOF) return EOF;
_un_getch = ch;
return ch;
}
static int _un_getch = EOF;

1571
Mix Power C v1/SCREEN.ASM Normal file

File diff suppressed because it is too large Load Diff

200
Mix Power C v1/SEEK.ASM Normal file
View File

@ -0,0 +1,200 @@
;
; Copyright (c) Mix Software 1988
;
; position a file
;
; int fseek(fp, offset, origin)
; FILE *fp;
; long offset;
; int origin;
;
IDT fseek
DEF fseek
REF _fileerr
FREF _fseek
fseek MOV BX,SP
PUSH [BX][%PARM4-2]
PUSH [BX][%PARM3-2]
PUSH [BX][%PARM2-2]
PUSH [BX][%PARM1-2]
CALLFAR _fseek
ADD SP,%8
CMP DX,-1
JNZ OK
CMP AX,-1
JNZ OK
RETFAR
OK XOR AX,AX
RETFAR
END
;
; position a file
;
; long _fseek(fp, offset, origin)
; FILE *fp;
; long offset;
; int origin;
;
IDT _fseek
DEF _fseek
REF _fileerr
FREF _fflush
FREF _rflush
_fseek MOV BX,SP
MOV SI,[BX][%PARM1-2]
TEST SI,SI
JZ NOFILE
TEST %[SI][%FD$DIRTY],%FL$WRITE+FL$READ
JNZ FLUSH
;
; fp->file.count = 0;
;
DOSEEK MOV [SI][%FD$COUNT],0
;
; if ((handle = fp->file.handle) == -1) handle = 2;
;
MOV BX,[SI][%FD$HNDL]
CMP BX,%-1
JZ USE2
;
; reg.byte.ah = 0x42;
; reg.byte.al = origin;
; reg.word.bx = handle;
; longword.longvalue = offset;
; reg.word.cx = longword.words.msword;
; reg.word.dx = longword.words.lsword;
; longword.words.msword = reg.word.dx;
; longword.words.lsword = reg.word.ax;
; return longword.longvalue;
;
HNDLSET MOV AH,>42
MOV SI,SP
MOV AL,[SI][%PARM3+2-2]
MOV DX,[SI][%PARM2-2]
MOV CX,[SI][%PARM2+2-2]
;
; if (bios(0x21,&reg) & 0x01) return (*_fileerr)(reg.word.ax,fp);
;
INT >21
JB ERROR
;
; longword.words.msword = reg.word.dx;
; longword.words.lsword = reg.word.ax;
; return longword.longvalue;
;
RETSEG
;
ERROR MOV SI,SP
PUSH [SI][%PARM1-2]
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%4
CWD
RETSEG
NOFILE MOV AX,-1
CWD
RETSEG
;
; if (fp->file.dirty & fdwrite) {
; if (_fflush(fp) != 0) return EOF;
; }
;
FLUSH TEST %[SI][%FD$DIRTY],%FL$WRITE
JZ FLUSHR
PUSH SI
CALLFAR _fflush
ENDFLUSH POP SI
TEST AX,AX
JZ DOSEEK
DEC AX
RETSEG
;
; else if (fp->file.dirty & fdread) {
; if (_rflush(fp) != 0) return EOF;
; }
;
FLUSHR PUSH SI
CALLFAR _rflush
JMPS ENDFLUSH
USE2 MOV BX,2
JMPS HNDLSET
END
;
; return the current file position
; long ftell(fp)
; FILE *fp;
;
IDT ftell
DEF ftell
FREF _seekend
REF _fileerr
ftell MOV BX,SP
MOV SI,[BX][%PARM1-2]
TEST SI,SI
JZ NULL
TEST %[SI][%FD$FLAGS],%FL$APPEN
JZ FIND
TEST %[SI][%FD$DIRTY],%FL$WRITE
JZ FIND
PUSH SI
CALLFAR _seekend
POP SI
FIND EQU $
;
; reg.byte.ah = 0x42;
; reg.byte.al = 1
; reg.word.bx = handle;
; reg.word.cx = 0
; reg.word.dx = 0
;
MOV AX,>4201
XOR CX,CX
XOR DX,DX
MOV BX,[SI][%FD$HNDL]
;
; if (bios(0x21,&reg) & 0x01) return (*_fileerr)(reg.word.ax,fp);
;
PUSH SI
INT >21
POP SI
JB ERROR
;
; longword.words.msword = reg.word.dx;
; longword.words.lsword = reg.word.ax;
; return longword.longvalue;
;
TEST %[SI][%FD$DIRTY],%FL$WRITE+FL$READ
JNZ BUFRUSED
RETSEG
;
; if (fp->file.dirty & fdwrite) {
; offset = fp->file.ptr - fp->file.bufr;
; }
;
BUFRUSED TEST %[SI][%FD$DIRTY],%FL$WRITE
JZ READBUFR
ADDOFF MOV CX,[SI][%FD$PTR]
SUB CX,[SI][%FD$BUFR]
ADD AX,CX
ADC DX,%0
RETSEG
;
; else if (fp->file.dirty & fdread) {
; offset = fp->file.bufr - fp->file.bufr;}
;
READBUFR SUB AX,[SI][%FD$COUNT]
SBB DX,0
RETSEG
;
ERROR MOV SI,SP
PUSH [SI][%PARM1-2]
PUSH AX
MOV BX,[_fileerr]
CALLSEG [BX]
ADD SP,%4
CWD
RETSEG
NULL MOV AX,-1
RETSEG
END

74
Mix Power C v1/SETBUF.C Normal file
View File

@ -0,0 +1,74 @@
/* File buffer functions */
/* Copyright (c) Mix Software 1988 */
setbufsiz(size)
int size;
{
extern int $$BUFSIZ;
int oldsize = $$BUFSIZ;
$$BUFSIZ = size;
return oldsize;
}
/* ------------------------------------------------------------ */
setbuf(fp, bufptr)
FILE *fp;
char *bufptr;
{
extern int (*_fclose)();
int fclose();
if (fp) {
_fclose = fclose;
fflush(fp);
if ((fp->file.flags & fdsetbuf) == 0) free(fp->file.bufr);
if (bufptr == 0) {
fp->file.flags |= fdunbufr;
fp->file.bufr = NULL;
fp->file.ptr = NULL;
fp->file.count = 0;
return;
}
fp->file.bufr = fp->file.ptr = bufptr;
fp->file.count = 0;
fp->file.flags &= ~fdunbufr;
fp->file.flags |= fdsetbuf;
}
}
/* ------------------------------------------------------------ */
setvbuf(fp, buf, type, size)
FILE *fp;
char *buf;
int type;
int size;
{
extern int (*_fclose)();
int fclose();
if (fp) {
_fclose = fclose;
if (type != _IONBF && type != _IOFBF && type != _IOLBF) return -1;
if (size < 0) return -1;
fflush(fp);
if ((fp->file.flags & fdsetbuf) == 0) free(fp->file.bufr);
if (type == _IONBF) {
fp->file.flags |= fdunbufr;
fp->file.bufr = NULL;
fp->file.ptr = NULL;
fp->file.count = 0;
return 0;
}
if (buf == NULL) buf = malloc(size);
if (buf == NULL) return -1;
fp->file.bufr = fp->file.ptr = buf;
fp->file.count = 0;
fp->file.bufsize = size;
fp->file.flags &= ~fdunbufr;
fp->file.flags |= fdsetbuf;
return 0;
}
else return -1;
}

124
Mix Power C v1/SETJMP.ASM Normal file
View File

@ -0,0 +1,124 @@
;
; Copyright (c) Mix Software 1988
;
; Setjmp - stores the current state to allow a
; global branch to be taken later.
;
; Declared in C as:
; struct JMP_BUF {
; int frame;
; long pc;
; int stacktop;
; char save[22];
; };
; int setjmp();
;
; Example of use in C:
;
; { JMP_BUF sjbuf;
; if (setjmp(&sjbuf)) {
; /* code that is jumped to */
; }
; else {
; /* code to execute after setting the jump */
; } }
;
;
FRAME EQU 0 ; Frame pointer in jmp_buf
PC EQU 2 ; Program counter in jmp_buf
STACKTOP EQU 6 ; Stack top in jmp_buf
SAVESIZE EQU 8 ; Size of parameter area
SAVE EQU 10 ; Save stack area in jmp_buf
MAXDATA EQU 22 ; Limit on top of stack data
IDT setjmp
DEF setjmp
IF UPPER
DEF SETJMP
ENDIF
setjmp equ $
SETJMP MOV BX,SP ; Point to return address
MOV DI,[BX][%PARM1-2] ; address of jmp_buf
MOV [DI][%FRAME],BP
MOV AX,[BX]
MOV [DI][%PC],AX ; First word of pc
MOV AX,[BX][%2]
MOV [DI][%PC+2],AX ; Second word of pc
LEA SI,[BX][%4] ; Top of stack
MOV [DI][%STACKTOP],SI
MOV CX,BP
SUB CX,SI ; Top of stack area
MOV [DI][%SAVESIZE],CX
CMP CX,MAXDATA
JBE SAVESTK
MOV CX,MAXDATA
SAVESTK ADD DI,%SAVE
MOV AX,DS
MOV ES,AX
JCXZ DONE
CLD
REP
MOVSB
DONE XOR AX,AX ; return 0
RETSEG
END
;
; Longjmp - transfers to the location previously
; set by a call to setjmp. The stack is
; also restored to its former state.
;
; Declared in C as:
; struct JMP_BUF {
; int frame;
; long pc;
; int stacktop;
; int save[22];
; }
; int longjmp();
;
; Example of use in C:
;
; longjmp(&sjbuf,result);
;
;
;
;
FRAME EQU 0 ; Frame pointer in jmp_buf
PC EQU 2 ; Program counter in jmp_buf
STACKTOP EQU 6 ; Stack top in jmp_buf
SAVESIZE EQU 8 ; Size of saved stack
SAVE EQU 10 ; Save stack area in jmp_buf
MAXDATA EQU 22 ; Limit on top of stack data
IDT longjmp
DEF longjmp
IF UPPER
DEF LONGJMP
ENDIF
longjmp equ $
LONGJMP MOV BX,SP ; parameter pointer
MOV SI,[BX][%PARM1-2] ; Address of sjbuf
CMP SP,[SI][%STACKTOP]
JA NOFRAME
MOV AX,[BX][%PARM2-2] ; result
MOV DI,[SI][%STACKTOP]
MOV CX,DS
MOV ES,CX
MOV CX,[SI][%SAVESIZE]
CMP CX,MAXDATA
JA TOOBIG
PUSH SI
ADD SI,%SAVE
JCXZ MOVED
CLD
REP
MOVSB
MOVED POP SI
MOV BP,[SI][%FRAME]
MOV SP,[SI][%STACKTOP]
PUSH [SI][%PC+2]
PUSH [SI][%PC]
RETSEG ; AX has result
NOFRAME MOV AX,-1
RETSEG
TOOBIG MOV AX,-2
RETSEG
END

72
Mix Power C v1/SETMEM.ASM Normal file
View File

@ -0,0 +1,72 @@
;
; Copyright (c) Mix Software 1988
;
; -------------------------------------------------------
; setmem(address,count,value) - fill memory with value
; memset(address,value,count)
; -------------------------------------------------------
;
IDT setmem
DEF setmem
IF UPPER
DEF SETMEM
ENDIF
;
SETMEM EQU $
setmem PUSH BP
MOV BP,SP
MOV CX,[BP][%PARM2]
MOV AX,[BP][%PARM3]
SETMEM1 MOV DI,[BP][%PARM1]
PUSH CX
SHR CX,1
JCXZ LASTCHAR
MOV AH,AL
MOV DX,DS
MOV ES,DX
CLD
REP
STOSW
LASTCHAR POP CX
AND CX,>0001
JCXZ DONE
STOSB
DONE MOV AX,[BP][%PARM1] ; Return pointer to destination
POP BP
RETSEG
memset equ $
MEMSET PUSH BP
MOV BP,SP
MOV AX,[BP][%PARM2]
MOV CX,[BP][%PARM3]
JMPS SETMEM1
END
;
; -------------------------------------------------------
; repmem(address,data,datasize, copies)
; fill memory with copies of a template
; -------------------------------------------------------
;
IDT repmem
DEF repmem
;
repmem PUSH BP
MOV BP,SP
MOV DX,[BP][%PARM4] ; number of copies
TEST DX,DX
JZ DONE
MOV CX,[BP][%PARM3] ; size of block
JCXZ DONE
MOV DI,[BP][%PARM1] ; address of data
MOV CX,DS
MOV ES,CX
CLD
FILL MOV SI,[BP][%PARM2] ; pattern data
MOV CX,[BP][%PARM3] ; size of block
REP
MOVSB
DEC DX
JNZ FILL
DONE POP BP
RETSEG
END

35
Mix Power C v1/SIEVE.C Normal file
View File

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

293
Mix Power C v1/SIGNAL.ASM Normal file
View File

@ -0,0 +1,293 @@
;
; Copyright (c) Mix Software 1988
;
IDT ssignal
DEF ssignal
FREF signal
ssignal JMPFAR signal
END
;
; Signal - set interrupt vectors
;
; int (*signal(sig,func))();
; int sig;
; int (*func)()
;
IDT signal
DEF signal
DEF _signal_
DREF errno
DREF _SIGTBL
SIGMAX EQU 8
SIGINT EQU 2
SIGFPE EQU 8
signal MOV %[CTLBRK],%0
signal2 PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1]
CMP BX,%SIGMAX ; in range?
JBE OK1
INVALID MOV [errno],EINVAL
MOV AX,-1
POP BP
RETSEG
OK1 ADD BX,BX ; index table
MOV AX,[BP][%PARM2]
XCHG AX,[BX][_SIGTBL] ; save pointer & return previous
CMP BX,SIGINT*2
JZ FIXINT23
CMP BX,SIGFPE*2
JZ FIX8087
EXIT POP BP
RETSEG
FIX8087 JMPS EXIT ;
;
; Setting vector for control C
;
FIXINT23 MOV AL,%[CTLBRK]
MOV %[KEEP23],AL
CMP [OLD23S],0
JNZ EXIT
CMP [OLD23O],0
JNZ EXIT
PUSH AX
MOV AX,>3523 ; Read prior vector
INT >21
MOV [OLD23S],ES
MOV [OLD23O],BX
MOV DX,INT23
PUSH DS
MOV AX,CS
MOV DS,AX
MOV AX,>2523 ; Set new interrupt
INT >21
POP AX
MOV DS,AX
SEGCS
MOV [INT23DS],AX
POP AX
JMPS EXIT
_signal_ MOV %[CTLBRK],%1
JMP signal2
;
; Enter from interrupt >23 (control C)
;
INT23 PUSHF
STI
PUSH BX
PUSH AX
PUSH DS
MOV AX,SS
MOV DS,AX
MOV BX,_SIGTBL
MOV AX,[BX][%SIGINT*2]
CMP AX,0
JZ DEFAULT
CMP AX,1
JZ IGNORE
XOR AX,AX
XCHG AX,[BX][%SIGINT*2]
CMP %[KEEP23],%0
JZ SAVEREG
MOV [BX][%SIGINT*2],AX
SAVEREG MOV BX,AX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH ES
MOV AX,SS
MOV DS,AX
MOV AX,SIGINT
PUSH AX
CALLSEG [BX]
INC SP
INC SP
POP ES
POP BP
POP DI
POP SI
POP DX
POP CX
CMP %[KEEP23],%0
JZ IGNORE
TEST AX,AX
JZ DEFAULT
IGNORE POP DS
POP AX
POP BX
POPF
CLC
RETFAR
DEFAULT POP DS
POP AX
POP BX
POPF
STC
RETFAR
INT23DS DW 0-0
;
DORG 0
OLD23O DW 0
OLD23S DW 0
KEEP23 DB 0
CTLBRK DB 0
END
;
IDT gsignal
DEF gsignal
FREF raise
gsignal JMPFAR raise
END
;
;
; Raise - cause a signal
;
; int raise(sig)
; int sig;
;
IDT raise
DEF raise
DREF _SIGTBL
DREF errno
FREF _exit
SIGMAX EQU 8
SIGINT EQU 2
SIGFPE EQU 8
raise PUSH BP
MOV BP,SP
MOV BX,[BP][%PARM1]
CMP BX,%SIGMAX ; in range?
JBE OK1
INVALID MOV [errno],EINVAL
MOV AX,-1
POP BP
RETSEG
OK1 ADD BX,BX ; index table
MOV AX,0
XCHG AX,[BX][_SIGTBL] ; save pointer & return previous
; CMP BX,SIGINT*2
; JZ CALL23
; CMP BX,SIGFPE*2
; JZ CALL87
CMP AX,0
JZ DFLT
CMP AX,1
JZ IGNORE
PUSH [BP][%PARM1]
MOV BX,AX
CALLSEG [BX]
ADD SP,%2
EXIT XOR AX,AX
POP BP
RETSEG
IGNORE MOV [BX][_SIGTBL],1
JMPS EXIT
DFLT MOV AX,[BP][%PARM1]
PUSH AX
CALLFAR _exit
POP AX
; MOV AH,>4C
; INT >21
JMPS EXIT
END
;
IDT _SIGTBL
DDEF _SIGTBL
DORG 0
_SIGTBL DW 0
DW 1 ; 1 = sigabrt
DW 0 ; 2 = sigint
DW 0 ; 3 = sigill
DW 0
DW 0
DW 0 ; 6 = sigsegv
DW 0 ; 7 = sigterm
DW 1 ; 8 = sigfpe
END
;
;
; harderr - establish interrupt 24 handler
;
; void harderr(fptr)
; int (*fptr)()
;
IDT harderr
DEF harderr
LDEF hardresume
DEF hardretn
harderr PUSH BP
MOV BP,SP
MOV AX,DS
SEGCS
MOV [INT24DS],AX
MOV AX,[BP][PARM1]
MOV [INT24V],AX
MOV DX,INT24
PUSH DS
MOV AX,CS
MOV DS,AX
MOV AX,>2524 ; Set new interrupt
INT >21
POP AX
MOV DS,AX
POP BP
RETFAR
INT24DS DW 0-0
;
; Enter from interrupt >24 (control C)
;
INT24 STI
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
PUSH BP
PUSH DS
PUSH ES
SEGCS
MOV AX,[INT24DS]
MOV DS,AX
MOV [INT24SP],SP
PUSH SI ; arguments to user function
PUSH BP
PUSH AX
PUSH DI
MOV BX,[INT24V]
CALLSEG [BX]
ADD SP,%8
EXIT MOV [INT24SP],0
POP DX
MOV ES,DX
POP DX
MOV DS,DX
POP BP
POP DI
POP SI
POP DX
POP CX
POP BX
IRET
;
hardresu CMP [INT24SP],0
JZ NOT24
MOV BP,SP
MOV AX,[BP][%PARM1-2]
MOV SP,[INT24SP]
JMPS EXIT
NOT24 MOV AX,-1
RETSEG
;
hardretn CMP [INT24SP],0
JZ NOT24
MOV BP,SP
MOV AX,[BP][%PARM1-2]
MOV SP,[INT24SP]
JMPS EXIT
;
DORG 0
INT24SP DW 0
INT24V DW 0
END

104
Mix Power C v1/SORT.C Normal file
View File

@ -0,0 +1,104 @@
/* Searching and sorting */
/* Copyright (c) Mix Software 1988 */
char *bsearch(key, base, num, width, compare)
char *key; /* search key */
char *base; /* start of array */
unsigned num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
char *here;
int cmp;
int i, j, k;
i = 0;
j = num-1;
do {
k = (j+i)>>1;
here = base + width*k;
cmp = (*compare)(key,here);
if (cmp == 0) { /* found - now scan down for first */
while ((here > base) && ((*compare)(key,here-width) == 0))
here -= width;
return here;
}
if (cmp < 0) j = k-1; else i=k+1;
}
while (j >= i);
return NULL;
} /* bsearch */
/* ------------------------------------------------------------ */
void qsort(base, num, width, compare)
char *base; /* start of array */
unsigned num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
char *key;
char *first, *last, *max;
int memswap();
last = max = base+(num-1)*width;
first = base;
key = base + width*(num >> 1);
do {
while ((*compare)(first,key,width) < 0) first += width;
while ((*compare)(key,last,width) < 0) last -= width;
if (first <= last) {
if (first != last) {
memswap(first,last,width);
if (first == key) key = last;
else if (last == key) key = first;
}
first += width;
last -= width;
}
}
while (first <= last);
if (base < last) qsort(base,(last-base)/width+1,width,compare);
if (first < max) qsort(first,(max-first)/width+1,width,compare);
}
/* ------------------------------------------------------------ */
char *lsearch(key, base, num, width, compare)
char *key; /* search key */
char *base; /* start of array */
unsigned *num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
char *result;
result = lfind(key,base,num,width,compare);
if (result == NULL) {
result = base+(*num)*width;
memcpy(result,key,width);
(*num)++;
}
return result;
} /* lsearch */
/* ------------------------------------------------------------ */
char *lfind(key, base, num, width, compare)
char *key; /* search key */
char *base; /* start of array */
unsigned *num; /* number of elements */
unsigned width; /* size of an element */
int (*compare)(); /* function to compare two elements */
{
unsigned number = *num;
while (number != 0) {
if ((*compare)(key,base) == 0) return base;
else {
if (--number == 0) return NULL;
else base += width;
}
}
return NULL;
} /* lfind */

62
Mix Power C v1/SOUND.ASM Normal file
View File

@ -0,0 +1,62 @@
;
; Copyright (c) Mix Software 1988
;
; ------------------------------------------------------------
;
idt sound
def sound
;
; sound(int freq, int duration)
;
ROMDATA EQU 40H
TIMER_LOW EQU 6CH
TIMER EQU 40H
PORTB EQU 61H
;
freq EQU 6
duration EQU freq+2
;
sound push bp
mov bp,sp
mov cx,[bp][%duration]
mov bx,[bp][%freq]
cmp bx,0
je LENGTH
mov ax,13532
mov dx,18
div bx
call BEEPER
LENGTH jcxz EXIT
mov bx,ROMDATA
mov ds,bx
mov bx,[TIMER_LOW]
TICKLOOP cmp bx,[TIMER_LOW]
je TICKLOOP
inc bx
loop TICKLOOP
EXIT xor ax,ax
call BEEPER
mov ax,ss
mov ds,ax
pop bp
retfar
;
BEEPER push ax
in al,PORTB
and al,0FCH ;mask off lower 3 bits
out PORTB,al
mov al,0B6H
out TIMER+3,al
pop ax
cmp ax,0
je DONE
out TIMER+2,al
mov al,ah
out TIMER+2,al
in al,PORTB
or al,3
out PORTB,al
DONE ret
;
END

75
Mix Power C v1/STACK.ASM Normal file
View File

@ -0,0 +1,75 @@
;
; Copyright (c) Mix Software 1988
;
; --------------------------------------------------
; alloca - allocate from the stack
; returns null if not enough memory
; char *_alloca(size)
; unsigned size;
; --------------------------------------------------
;
IDT alloca
DEF alloca
DREF $$LIMIT
DREF $$MAXS
;
alloca MOV SI,SP
MOV AX,[SI][%PARM1-2] ; Requested size
SUB SI,[$$LIMIT] ; Stack boundary
CMP SI,AX
JB NOSPACE
POP BX ; Remove return
POP CX
POP DX ; argument
SUB SP,AX
MOV AX,SP
DEC AX
AND AX,>FFFE
MOV SP,AX
PUSH DX
PUSH CX
PUSH BX
CMP AX,[$$MAXS]
JAE EXIT
MOV [$$MAXS],AX
EXIT RETSEG
NOSPACE XOR AX,AX
RETSEG
END
;
; --------------------------------------------------
; stackavail - return available stack
; returns amount of stack space available
; unsigned stackavail()
; --------------------------------------------------
;
IDT stackava
IF LONGNAME
LDEF stackavail
ENDIF
IF SHORTNAM
DEF stackava
ENDIF
DREF $$LIMIT
DREF $$MAXS
;
stackavail MOV AX,SP
SUB AX,[$$LIMIT] ; Stack boundary
RETSEG
END
;
; --------------------------------------------------
; stacksiz - return available stack
; returns amount of stack space available
; unsigned stacksiz()
; --------------------------------------------------
;
IDT stacksiz
DEF stacksiz
DREF $$LIMIT
DREF $$MAXS
;
stacksiz MOV AX,SP
SUB AX,[$$LIMIT] ; Stack boundary
RETSEG
END

37
Mix Power C v1/STAT.H Normal file
View File

@ -0,0 +1,37 @@
/*$no list*//*$no trace <<< stat.h >>> */
/* Copyright (c) Mix Software 1988 */
#define dev_t short
#define ino_t unsigned short
#define off_t long
#define time_t long
#define S_IFMT 0xf000 /* type mask */
#define S_IFDIR 0x4000
#define S_IFCHR 0x2000
#define S_IFREG 0x8000
#define S_IREAD 0x0100
#define S_IWRITE 0x0080
#define S_IEXEC 0x0040
#if !defined(stat)
struct stat
{
dev_t st_dev;
ino_t st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
dev_t st_rdev;
off_t st_size;
time_t st_atime;
time_t st_mtime;
time_t st_ctime;
};
#endif
int fstat(int fd, struct stat *buffer);
int stat(char *pathname, struct stat *buffer);
/*$list*//*$trace <<< stat.h >>> */

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