Mix Power C v1
This commit is contained in:
parent
e875f4cae7
commit
c7aad48ec8
70
Mix Power C v1/ABSDISK.ASM
Normal file
70
Mix Power C v1/ABSDISK.ASM
Normal 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
47
Mix Power C v1/ALLOCMEM.C
Normal 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
460
Mix Power C v1/ARITH.C
Normal 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
470
Mix Power C v1/BESSEL.C
Normal 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
204
Mix Power C v1/BIOS.C
Normal 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, ®); /* 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, ®);
|
||||
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, ®);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
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.h.bh = 1;
|
||||
reg.h.bl = palette;
|
||||
bios(0x10, ®);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
int readch()
|
||||
{ /* read character at current cursor position */
|
||||
extern int _vapage;
|
||||
union REGS reg;
|
||||
reg.h.ah = 8;
|
||||
reg.h.bh = _vapage;
|
||||
bios(0x10, ®);
|
||||
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, ®);
|
||||
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, ®);
|
||||
poscurs(0,0);
|
||||
}
|
||||
|
||||
curscol()
|
||||
{
|
||||
extern int _vapage;
|
||||
union REGS reg;
|
||||
reg.h.ah = 3;
|
||||
reg.h.bh = _vapage;
|
||||
bios(0x10, ®);
|
||||
return reg.h.dl;
|
||||
}
|
||||
|
||||
cursrow()
|
||||
{
|
||||
extern int _vapage;
|
||||
union REGS reg;
|
||||
reg.h.ah = 3;
|
||||
reg.h.bh = _vapage;
|
||||
bios(0x10, ®);
|
||||
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, ®);
|
||||
}
|
||||
|
||||
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, ®);
|
||||
}
|
||||
|
||||
getvmode()
|
||||
{
|
||||
union REGS reg;
|
||||
reg.h.ah = 15;
|
||||
bios(0x10, ®);
|
||||
return reg.h.al;
|
||||
}
|
||||
|
||||
setvmode(mode)
|
||||
int mode;
|
||||
{
|
||||
union REGS reg;
|
||||
reg.h.ah = 0;
|
||||
reg.h.al = mode;
|
||||
bios(0x10, ®);
|
||||
}
|
||||
|
||||
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
166
Mix Power C v1/BIOSFN.ASM
Normal 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
304
Mix Power C v1/CHAIN.C
Normal 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
101
Mix Power C v1/CLOSE.C
Normal 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
224
Mix Power C v1/CONVERT.C
Normal 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
154
Mix Power C v1/DISABLE.ASM
Normal 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
35
Mix Power C v1/DIV.ASM
Normal 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
236
Mix Power C v1/DOS.H
Normal 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
237
Mix Power C v1/DOSETC.C
Normal 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
27
Mix Power C v1/DSTRING.C
Normal 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
89
Mix Power C v1/DTAFAT.ASM
Normal 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
51
Mix Power C v1/DUP.C
Normal 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
328
Mix Power C v1/DYSTRING.C
Normal 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
30
Mix Power C v1/E.C
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define DIGITS_TO_FIND 200 /*9009*/
|
||||
|
||||
int main() {
|
||||
|
||||
int N = DIGITS_TO_FIND;
|
||||
int x = 0;
|
||||
int a[ DIGITS_TO_FIND ];
|
||||
int n;
|
||||
|
||||
for (n = N - 1; n > 0; --n) {
|
||||
a[n] = 1;
|
||||
}
|
||||
|
||||
a[1] = 2, a[0] = 0;
|
||||
while (N > 9) {
|
||||
n = N--;
|
||||
while (--n) {
|
||||
a[n] = x % n;
|
||||
|
||||
x = 10 * a[n-1] + x/n;
|
||||
}
|
||||
printf("%d", x);
|
||||
}
|
||||
|
||||
printf( "\ndone\n" );
|
||||
|
||||
return 0;
|
||||
}
|
147
Mix Power C v1/ENVIR.ASM
Normal file
147
Mix Power C v1/ENVIR.ASM
Normal 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
130
Mix Power C v1/ENVIR.C
Normal 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
53
Mix Power C v1/ERROR.C
Normal 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
4
Mix Power C v1/ERRORS.C
Normal 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
128
Mix Power C v1/ETC.C
Normal 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
692
Mix Power C v1/EXEC.ASM
Normal 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
72
Mix Power C v1/EXIT.C
Normal 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
227
Mix Power C v1/FAR.ASM
Normal 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
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
374
Mix Power C v1/FARMEM.ASM
Normal 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
1045
Mix Power C v1/FARSTR.ASM
Normal file
File diff suppressed because it is too large
Load Diff
97
Mix Power C v1/FARSTR1.ASM
Normal file
97
Mix Power C v1/FARSTR1.ASM
Normal 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
47
Mix Power C v1/FATAL.ASM
Normal 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
15
Mix Power C v1/FCNTL.H
Normal 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
33
Mix Power C v1/FDB.H
Normal 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
344
Mix Power C v1/FILE.C
Normal 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
519
Mix Power C v1/FILLM.ASM
Normal 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
38
Mix Power C v1/FINDFIRS.C
Normal 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
104
Mix Power C v1/FLAGS.C
Normal 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
140
Mix Power C v1/FLUSH.ASM
Normal 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
219
Mix Power C v1/FREE.ASM
Normal 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
80
Mix Power C v1/FSTAT.C
Normal 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
245
Mix Power C v1/GET.ASM
Normal 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
50
Mix Power C v1/GETS.C
Normal 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
582
Mix Power C v1/GRAPHICS.C
Normal 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
380
Mix Power C v1/INIT.ASM
Normal 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
166
Mix Power C v1/INIT.C
Normal 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
63
Mix Power C v1/INOUT.ASM
Normal 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
230
Mix Power C v1/INTENT.ASM
Normal 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
70
Mix Power C v1/INTR.ASM
Normal 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
48
Mix Power C v1/INTRPT.ASM
Normal 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
16
Mix Power C v1/IO.ASM
Normal 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
34
Mix Power C v1/LIB.ASM
Normal 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
28
Mix Power C v1/LIB2.ASM
Normal 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
150
Mix Power C v1/LIBDEF.ASM
Normal 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
118
Mix Power C v1/LOCKING.C
Normal 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
10
Mix Power C v1/LOCKING.H
Normal 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
524
Mix Power C v1/LONG.ASM
Normal 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
21
Mix Power C v1/MEMORY.C
Normal 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
BIN
Mix Power C v1/MERGE.EXE
Normal file
Binary file not shown.
10
Mix Power C v1/MIXC.BAT
Normal file
10
Mix Power C v1/MIXC.BAT
Normal 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
BIN
Mix Power C v1/MIXC.MIX
Normal file
Binary file not shown.
277
Mix Power C v1/MIXC1.C
Normal file
277
Mix Power C v1/MIXC1.C
Normal 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
484
Mix Power C v1/MOVMEM.ASM
Normal 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
205
Mix Power C v1/MSDOS.C
Normal 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(®,®);
|
||||
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, ®) & 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(®,®);
|
||||
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(®,®);
|
||||
_pid = reg.x.dx;
|
||||
}
|
||||
return _pid;
|
||||
}
|
||||
|
270
Mix Power C v1/NEW.ASM
Normal file
270
Mix Power C v1/NEW.ASM
Normal 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
251
Mix Power C v1/NHEAP.ASM
Normal 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
254
Mix Power C v1/OPEN.C
Normal 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
BIN
Mix Power C v1/PC.EXE
Normal file
Binary file not shown.
BIN
Mix Power C v1/PC87.MIX
Normal file
BIN
Mix Power C v1/PC87.MIX
Normal file
Binary file not shown.
BIN
Mix Power C v1/PCA.EXE
Normal file
BIN
Mix Power C v1/PCA.EXE
Normal file
Binary file not shown.
BIN
Mix Power C v1/PCAUTO.MIX
Normal file
BIN
Mix Power C v1/PCAUTO.MIX
Normal file
Binary file not shown.
BIN
Mix Power C v1/PCDMY.MIX
Normal file
BIN
Mix Power C v1/PCDMY.MIX
Normal file
Binary file not shown.
BIN
Mix Power C v1/PCIEEE.MIX
Normal file
BIN
Mix Power C v1/PCIEEE.MIX
Normal file
Binary file not shown.
BIN
Mix Power C v1/PCL.EXE
Normal file
BIN
Mix Power C v1/PCL.EXE
Normal file
Binary file not shown.
10
Mix Power C v1/PCLIB.BAT
Normal file
10
Mix Power C v1/PCLIB.BAT
Normal 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
BIN
Mix Power C v1/PCLIB.MIX
Normal file
Binary file not shown.
25
Mix Power C v1/PCLIB.PRJ
Normal file
25
Mix Power C v1/PCLIB.PRJ
Normal 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
10
Mix Power C v1/PCLIB2.BAT
Normal 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
BIN
Mix Power C v1/PCLIB2.MIX
Normal file
Binary file not shown.
14
Mix Power C v1/PCLIB2.PRJ
Normal file
14
Mix Power C v1/PCLIB2.PRJ
Normal 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
BIN
Mix Power C v1/PCO.EXE
Normal file
Binary file not shown.
75
Mix Power C v1/PEEK.ASM
Normal file
75
Mix Power C v1/PEEK.ASM
Normal 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
95
Mix Power C v1/PERROR.C
Normal 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(®,®);
|
||||
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
589
Mix Power C v1/PRINTF.C
Normal 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
32
Mix Power C v1/PROCESS.H
Normal 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
222
Mix Power C v1/PUT.ASM
Normal 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
60
Mix Power C v1/PUTS.C
Normal 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
51
Mix Power C v1/RAND.C
Normal 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
360
Mix Power C v1/READ.ASM
Normal 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
555
Mix Power C v1/SCANF.C
Normal 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
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
200
Mix Power C v1/SEEK.ASM
Normal 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,®) & 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,®) & 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
74
Mix Power C v1/SETBUF.C
Normal 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
124
Mix Power C v1/SETJMP.ASM
Normal 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
72
Mix Power C v1/SETMEM.ASM
Normal 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
35
Mix Power C v1/SIEVE.C
Normal file
@ -0,0 +1,35 @@
|
||||
/* sieve.c */
|
||||
|
||||
/* Eratosthenes Sieve Prime Number Program in C from Byte Jan 1983
|
||||
to compare the speed. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define SIZE 8190
|
||||
typedef int bool;
|
||||
|
||||
char flags[SIZE+1];
|
||||
|
||||
int main()
|
||||
{
|
||||
int i,k;
|
||||
int prime,count,iter;
|
||||
|
||||
for (iter = 1; iter <= 10; iter++) { /* do program 10 times */
|
||||
count = 0; /* initialize prime counter */
|
||||
for (i = 0; i <= SIZE; i++) /* set all flags TRUE */
|
||||
flags[i] = TRUE;
|
||||
for (i = 0; i <= SIZE; i++) {
|
||||
if (flags[i]) { /* found a prime */
|
||||
prime = i + i + 3; /* twice index + 3 */
|
||||
for (k = i + prime; k <= SIZE; k += prime)
|
||||
flags[k] = FALSE; /* kill all multiples */
|
||||
count++; /* primes found */
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("%d primes.\n",count); /*primes found in 10th pass */
|
||||
return 0;
|
||||
}
|
293
Mix Power C v1/SIGNAL.ASM
Normal file
293
Mix Power C v1/SIGNAL.ASM
Normal 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
104
Mix Power C v1/SORT.C
Normal 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
62
Mix Power C v1/SOUND.ASM
Normal 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
75
Mix Power C v1/STACK.ASM
Normal 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
37
Mix Power C v1/STAT.H
Normal 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
Loading…
Reference in New Issue
Block a user