home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v92.tgz
/
v92.tar
/
v92
/
src
/
runtime
/
fxmsdos.ri
< prev
next >
Wrap
Text File
|
1996-03-22
|
7KB
|
333 lines
/*
* fxmsdos.ri
*/
char *zptr = NULL;
/*
* Prototype.
*/
int getlist Params((struct b_lelem *bp,unsigned int *vals, int limit));
"Int86(a) - perform an interrupt"
#if MICROSOFT || TURBO || ZTC_386 || BORLAND_286 || BORLAND_386 || SCCX_MX
function{1} Int86(a)
/*
* Make sure that a is a list
*/
if !is:list(a) then
runerr(118,a)
abstract {
return list
}
body {
union REGS inreg,outreg;
struct SREGS insreg,outsreg;
#if BORLAND_386
#define ax eax
#define bx ebx
#define cx ecx
#define dx edx
#define si esi
#define di edi
#define int86x int386x
#endif /* BORLAND_386 */
unsigned int vals[9];
unsigned int flag;
word nslots;
struct b_list *hp;
struct b_lelem *bp;
/*
* Make sure that a only has 9 values, and all are ints.
*/
hp = (struct b_list *) BlkLoc(a);
if (hp->size != 9) {
runerr(205, a);
}
bp = (struct b_lelem *) hp->listhead;
if (getlist(bp, vals, 9) == Failed)
fail;
flag = vals[0];
inreg.x.ax = vals[1];
inreg.x.bx = vals[2];
inreg.x.cx = vals[3];
inreg.x.dx = vals[4];
inreg.x.si = vals[5];
inreg.x.di = vals[6];
segread(&insreg);
#if BORLAND_286 || BORLAND_386
/*
* Only set segment registers if caller provided a non-zero value.
* This probably should be done for all protected-mode versions, and
* instruct user to specify 0 for ds/es to use default ds/es.
* Unlike PharLap, Borland does not publish known selector values
* to use in ds or es. Loading a garbage value will result in a
* trap.
*/
if (vals[7])
insreg.es = vals[7];
if (vals[8])
insreg.ds = vals[8];
#endif /* BORLAND_286 || BORLAND_386 */
/* flag = int86x(flag,&inreg,&outreg,&insreg); */
int86x(flag,&inreg,&outreg,&insreg); /* ... this should work for */
flag = outreg.x.cflag; /* ... both MSC and Turbo C */
/*
* Return the values.
*/
nslots = 9;
Protect(hp = alclist((word)9), runerr(0));
Protect(bp = alclstb(nslots,(word)0,(word)9), runerr(0));
hp->listhead = hp->listtail = (union block *) bp;
/* returns [flags,ax,bx,cx,dx,si,di,es,ds] */
MakeInt((uword)flag,&(bp->lslots[0]));
MakeInt((uword)outreg.x.ax,&(bp->lslots[1]));
MakeInt((uword)outreg.x.bx,&(bp->lslots[2]));
MakeInt((uword)outreg.x.cx,&(bp->lslots[3]));
MakeInt((uword)outreg.x.dx,&(bp->lslots[4]));
MakeInt((uword)outreg.x.si,&(bp->lslots[5]));
MakeInt((uword)outreg.x.di,&(bp->lslots[6]));
MakeInt((uword)insreg.es,&(bp->lslots[7]));
MakeInt((uword)insreg.ds,&(bp->lslots[8]));
result.dword = D_List;
result.vword.bptr = (union block *) hp;
return result;
}
end
#endif /* MICROSOFT || TURBO || ZTC_386 ... */
"Peek(addr,len) - read from memory"
function{1} Peek(addr,len)
declare {
C_integer _len_;
}
if !def:C_integer(len,1,_len_) then
runerr(101,len)
abstract {
return string
}
body {
unsigned int vals[2];
struct b_list *hp;
struct b_lelem *bp;
union {
char *cptr;
struct {
unsigned int o;
unsigned int s;
} Word;
} unaddr;
type_case addr of {
integer: {
#ifdef LargeInts
if (Type(addr) == T_Lrgint)
runerr(205,addr);
#endif /* LargeInts */
return string(_len_,(char *) word2ptr(IntVal(addr)));
}
list: {
hp = (struct b_list *) BlkLoc(addr);
if (hp->size != 2) {
runerr(205, addr);
}
bp = (struct b_lelem *) hp->listhead;
if (getlist(bp, vals, 2) == Failed) fail;
unaddr.Word.s = vals[0];
unaddr.Word.o = vals[1];
return string(_len_,unaddr.cptr);
}
default: {
runerr(101,addr);
}
}
/* NOTREACHED */
}
end
"poke(addr,s) - write to memory"
function{1} Poke(addr,s)
if !cnv:string(s) then
runerr(103, s)
abstract {
return null
}
body {
unsigned int vals[2];
register char *s1,*s2;
register word l;
union {
char *cptr;
struct {
unsigned int o;
unsigned int s;
} Word;
} unaddr;
struct b_list *hp;
struct b_lelem *bp;
type_case addr of {
integer: {
#ifdef LargeInts
if (Type(addr) == T_Lrgint)
runerr(205, addr);
#endif /* LargeInts */
unaddr.cptr = (char *)word2ptr(addr.vword.integr);
}
list: {
hp = (struct b_list *) BlkLoc(addr);
if (hp->size != 2) {
runerr(205,addr);
}
bp = (struct b_lelem *) hp->listhead;
if (getlist(bp, vals, 2) == Failed) fail;
unaddr.Word.s = vals[0];
unaddr.Word.o = vals[1];
}
default: {
runerr(101,addr);
}
}
l = StrLen(s);
s1 = StrLoc(s);
s2 = unaddr.cptr;
memcopy(s2,s1,l); /* Copy... */
return nulldesc;
}
end
"GetSpace(i) - allocate memory block"
function{1} GetSpace(i)
if !cnv:C_integer(i) then /* should check for small */
runerr(101,i)
abstract {
return integer
}
body {
char *addr;
uword u;
addr = (char *)calloc((int)i,sizeof(char));
if (addr==NULL)
fail;
u = ptr2word(addr);
return C_integer u;
}
end
"FreeSpace(a) - free allocated memory block"
function{1} FreeSpace(a)
if !cnv:C_integer(a) then
runerr(101,a)
abstract {
return null
}
body {
uword u;
char *addr;
u = (uword)a;
addr = word2ptr(u);
free((pointer)addr);
return nulldesc;
}
end
/*
* getlist - copy integers from an Icon list to a C array.
*/
int getlist(bp,vals,limit)
unsigned int *vals;
int limit;
struct b_lelem *bp;
{
int i;
int count;
i = 0;
for(count = 0 ;count <limit;count++) {
int j;
if( ++i > bp->nused) {
i = 1;
bp = (struct b_lelem *) bp->listnext;
}
j = bp->first + i - 1; /* Get slot index */
if( j >= bp->nslots)
j -= bp->nslots;
switch(Type(bp->lslots[j])) {
case T_Integer: /* should check for small */
vals[count] = (int)IntVal(bp->lslots[j]);
break;
default:
RunErr(101,&bp->lslots[j]);
}
}
return 0;
}
"InPort(i) - return a value from port i"
function{1} InPort(i)
if !cnv:C_integer(i) then /* should check i's valid range */
runerr(101,i)
abstract {
return integer
}
inline {
return C_integer inp(i);
}
end
"OutPort(i1,i2) - write i2 to port i1"
function{1} OutPort(i1,i2)
if !cnv:C_integer(i1) then
runerr(101,i1)
if !cnv:C_integer(i2) then
runerr(101,i2)
abstract {
return null
}
body {
/*
* make sure that i2 is not just a C integer, it must fit in one byte
*/
if ((i2 < 0) || (i2 > 255)){
irunerr(205, i2);
}
outp(i1,i2);
return nulldesc;
}
end