home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Datafile PD-CD 4
/
DATAFILE_PDCD4.iso
/
utilities
/
utilst
/
virtual
/
!Virtual
/
c
/
control
next >
Wrap
Text File
|
1993-07-05
|
33KB
|
1,260 lines
/* includes */
#include "swis.h"
#include "swiv.h"
#include "wimp.h"
#include "virtual.h"
#include "lib.h"
#include "pager.h"
#include "output.h"
#include "asm.h"
#include "poll.h"
#include "xswis.h" /* Some RO3 swis */
/* constants */
/*#define DEBUG*/
#define N_bit 0x80000000
#define Z_bit 0x40000000
#define C_bit 0x20000000
#define V_bit 0x10000000
#define PSW_bits 0xF0000000
static int * const swivec=(int*)8;
static int ingos = 0;
static int incallback = 0;
/* errors */
#define ERR(x) ((struct Error *)(x))
static char BadMemory[] = { "XXXXNo memory at this address" };
static char Failed[] = { "XXXXMisc Virtual swi failed" };
static char NotAllowed[] = { "XXXXThis swi not allowed under virtual" };
/* module wrapping */
struct Error *Cinit(private **p) /* */
{ /* called with C stack a 1K bit out of svcstack. */
struct Error *err;
if (!*p)
*p=alloc(sizeof(private));
(*p)->uses = 0;
(*p)->w = 0;
worksemaphore = 1;
err = swix(OS_CallEvery,IN(R0|R1|R2),15,&OurCallEvery,*p);
if (err)
free(*p),*p=0;
return err;
}
struct Error *Cfinish(private **p)
{ /* called with C stack a 1K bit out of svcstack. */
/* should check (*p)->uses */
return swix(OS_RemoveTickerEvent,IN(R0|R1),&OurCallEvery,*p);
}
struct Error *CDoPhysical(int task, int addr, int len, int k[3],private *priv)
{ /* called with C stack a 1K bit out of svcstack. */
WKSP *w=priv->w;
RANGE r;
if (w->ourtask!=task)
return 0;
r = Locate(w,addr,addr+len);
k[0]=r.start; k[1]=r.end; k[2]=w->pagefile;
return 0;
}
/* ******************** mode changers */
void ClaimVVecs(WKSP *w)
{ int oldswi;
workptr=w;
swi(OS_ChangeEnvironment,IN(R0|R1)|OUT(R1),2,&VPrefetchAbort,&w->OldPrefetchAbort);
swi(OS_ChangeEnvironment,IN(R0|R1)|OUT(R1),3,&VDataAbort,&w->OldDataAbort);
swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3)|OUT(R1|R2|R3),7,&VCallBack,w,&w->regs,
&w->OldCallBack,&w->OldCallBackR12,&w->OldCallBackRegs);
swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&VError,&w->errnum,&w->errPC);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&VUpCall,w);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&VExit,w);
oldswi=*swivec;
if (oldswi>>24==0xEA)
; /* B */
oldswi=8+(int)swivec+(oldswi<<8>>6);
w->OldSWIV=oldswi;
workOldSWIV=oldswi;
*swivec=(int)&VSWIV-8-(int)swivec>>2|0xEA000000;
}
void ReleaseVVecs(WKSP *w)
{
*swivec=w->OldSWIV-8-(int)swivec>>2|0xEA000000;
swi(OS_ChangeEnvironment,IN(R0|R1),2,w->OldPrefetchAbort);
swi(OS_ChangeEnvironment,IN(R0|R1),3,w->OldDataAbort);
swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),7,w->OldCallBack,w->OldCallBackR12,w->OldCallBackRegs);
swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&NormError,w,&w->errPC);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&NormUpCall,w);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&NormExit,w);
}
void ClaimExtVecs( WKSP *w )
{ swi(OS_Claim,IN(R0|R1|R2),3,&ExtWriteC,w);
swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&ExtError,w,&w->errPC);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&ExtUpCall,w);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&ExtExit,w);
}
void ReleaseExtVecs( WKSP *w )
{ swi(OS_Release,IN(R0|R1|R2),3,&ExtWriteC,w);
swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&NormError,w,&w->errPC);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&NormUpCall,w);
swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&NormExit,w);
}
void Virtual(WKSP *w)
{
virtualmem(w);
ClaimVVecs(w);
}
void Normal(WKSP *w)
{
ReleaseVVecs(w);
normalmem(w);
}
void V2Ext( WKSP *w )
{
ReleaseVVecs(w);
ClaimExtVecs(w);
}
void Ext2V( WKSP *w )
{
ReleaseExtVecs(w);
ClaimVVecs(w);
}
void Ext2Norm( WKSP *w)
{
ReleaseExtVecs(w);
normalmem(w);
}
void Norm2Ext( WKSP *w)
{
virtualmem(w);
ClaimExtVecs(w);
}
/* ******************** Virtual mode handlers */
WKSP *CVWantAddr(WKSP *w, int start, int len)
{
if (len<0)
start += len, len= -len;
if (w->regs[15]&3)
{ Normal(w);
printf("***** CWantAddr called from non-user mode. Disaster! *****\n");
RealDoOff(w);
}
if (!WriteRange(w,start,start+len))
{ Normal(w);
printf("***** CWantAddr can't get desired area: %08x+%08x****\n",start,len);
RealDoOff(w);
}
return w;
}
void doeschand(WKSP *w,int n)
{ w->EscapeCondition = n;
#ifndef FIXED_SYSTEMCALL_VERSION_FO
if (w->Escape)
{ Normal(w);
printf("(should call escape handler at %08x)",w->Escape);
Virtual(w);
}
#else
if (w->Escape != -1) {
int result, * ruser = w->regs;
if (w->EscapeR12 != -1)
WriteRange(w, w->EscapeR12, w->EscapeR12+512);
ReadRange(w, w->Escape, w->Escape+8);
result = CallEscapeHandler(w->Escape, w->EscapeR12, (w->EscapeCondition == 2) ? 0x40 : 0);
if (result == 1) {
int j, * rcallback = (int *) w->CallBackBuf;
/* call back flag is set */
WriteRange(w, w->CallBackR12, w->CallBackR12 + 512);
WriteRange(w, w->CallBackBuf, w->CallBackBuf + 16 * 4);
ReadRange(w, w->CallBack, w->CallBack + 8);
for (j = 0; j < 16; j++)
rcallback[j] = ruser[j]; /* save user registers into callback buffer */
ruser[12] = w->CallBackR12;
ruser[15] = w->CallBack;
incallback = 1;
}
}
#endif
}
WKSP *CVCallBack(WKSP *w)
{ Normal(w);
Poll(w);
Virtual(w);
if (1==w->EscapeCondition)
doeschand(w,2);
worksemaphore=1; /* Ready to reenable when we exit */
return w;
}
WKSP *CVSWIV(WKSP *w,int instr)
{
int *r=w->regs;
char s[256];
struct Error *err=0;
int psw,i;
int swinum=instr&~(XOS_Bit|0xFF000000);
r[15]&=~V_bit;
#if 0
Normal(w);
swi(OS_SWINumberToString,IN(R0|R1|R2),instr&0xFFFFFF,s,256);
printf("Swi %s PC=%08x ",s,r[15]);
for (i=0;i<=14;i++)
printf("R%d=%08x ",i,r[i]);
printf("...");
Virtual(w);
#endif
switch(swinum) {
/* input/output */
/*
* OS SWIs
*/
case OS_WriteC:
outc(w,r[0]);
break;
case OS_Write0:
{ char *p;
ReadRange(w,r[0],r[0]+1);
for (p=(char *)r[0];*p;p++)
{ ReadPtr(w,(int)p);
outc(w,*p);
}
r[0]=(int)++p;
}
break;
case OS_WriteS:
{ char *p=(char *)(r[15]&~0xfc000003);
char *q=p;
for (;*p;p++)
{ ReadPtr(w,(int)p);
outc(w,*p);
}
r[15]+=(((p+1)-q)|3)+1;
}
break;
case OS_WriteN:
{ int n;
for ( n=0; n<r[1]; n++ )
{ ReadPtr(w,r[0]+n);
outc(w,((char *)r[0])[n]);
}
}
break;
case OS_NewLine:
outc(w,'\r'); outc(w,'\n');
break;
case OS_ReadC:
r[0]=getc(w);
if (-1==r[0])
{ r[0] = 27;
r[15]|=C_bit;
}
else
r[15]&=~C_bit;
if (1==w->EscapeCondition)
doeschand(w,2);
break;
case OS_ReadLine:
{ char buf[256];
int n=0,c;
r[15]&=~C_bit;
for (;;)
{ c=getc(w);
switch (c)
{
case 13: case 10:
buf[n]=13;
break;
case 27: case -1:
r[15]|=C_bit;
break;
case 127: case 8:
if (n>0)
{ outc(w,127); n--; }
else
outc(w,7);
continue;
case 21:
while (n>0)
{ outc(w,127); n--; }
continue;
default:
if (r[2]<=c && c<=r[3])
{ if (n<r[1]-1 && n<255)
{ buf[n++]=c;
outc(w,c);
}
else
outc(w,7);
}
else
outc(w,7);
continue;
}
outc(w,'\r'); outc(w,'\n');
break;
}
WriteRange(w,r[0],r[0]+n+1);
memcpy((void *)r[0],buf,n+1);
r[1]=n;
}
if (1==w->EscapeCondition)
doeschand(w,2);
break;
case OS_Byte:
switch (r[0])
{ default: goto uk;
case 0: /* display os version */
Normal(w);
err = swix(OS_Byte,IN(R0|R1)|OUT(R1),0,r[1],&r[1]);
Virtual(w);
break;
case 2: /* switch input streams */
#ifdef DEBUG
Normal(w);
prin