home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilst / virtual / !Virtual / c / control next >
Text File  |  1993-07-05  |  33KB  |  1,260 lines

  1. /* includes */
  2. #include "swis.h"
  3. #include "swiv.h"
  4. #include "wimp.h"
  5.  
  6. #include "virtual.h"
  7. #include "lib.h"
  8. #include "pager.h"
  9. #include "output.h"
  10. #include "asm.h"
  11. #include "poll.h"
  12.  
  13. #include "xswis.h"      /* Some RO3 swis */
  14.  
  15. /* constants */
  16. /*#define DEBUG*/
  17.  
  18. #define N_bit 0x80000000
  19. #define Z_bit 0x40000000
  20. #define C_bit 0x20000000
  21. #define V_bit 0x10000000
  22. #define PSW_bits 0xF0000000
  23.  
  24. static int * const swivec=(int*)8;
  25. static int ingos = 0;
  26. static int incallback = 0;
  27.  
  28. /* errors */
  29. #define ERR(x) ((struct Error *)(x))
  30. static char BadMemory[] = { "XXXXNo memory at this address" };
  31. static char Failed[] = { "XXXXMisc Virtual swi failed" };
  32. static char NotAllowed[] = { "XXXXThis swi not allowed under virtual" };
  33.  
  34. /* module wrapping */
  35.  struct Error *Cinit(private **p) /* */
  36. { /* called with C stack a 1K bit out of svcstack. */
  37.   struct Error *err;
  38.   if (!*p)
  39.     *p=alloc(sizeof(private));
  40.   (*p)->uses = 0;
  41.   (*p)->w = 0;
  42.   worksemaphore = 1;
  43.   err = swix(OS_CallEvery,IN(R0|R1|R2),15,&OurCallEvery,*p);
  44.   if (err)
  45.     free(*p),*p=0;
  46.   return err;
  47. }
  48.  
  49.  struct Error *Cfinish(private **p)
  50. { /* called with C stack a 1K bit out of svcstack. */
  51.   /* should check (*p)->uses */
  52.   return swix(OS_RemoveTickerEvent,IN(R0|R1),&OurCallEvery,*p);
  53. }
  54.  
  55.  struct Error *CDoPhysical(int task, int addr, int len, int k[3],private *priv) 
  56. { /* called with C stack a 1K bit out of svcstack. */
  57.   WKSP *w=priv->w;
  58.   RANGE r;
  59.   if (w->ourtask!=task)
  60.     return 0;
  61.   r = Locate(w,addr,addr+len);
  62.   k[0]=r.start; k[1]=r.end; k[2]=w->pagefile;  
  63.   return 0;
  64. }
  65.  
  66.  
  67. /* ******************** mode changers */
  68.  void ClaimVVecs(WKSP *w) 
  69. { int oldswi;
  70.   workptr=w;
  71.   swi(OS_ChangeEnvironment,IN(R0|R1)|OUT(R1),2,&VPrefetchAbort,&w->OldPrefetchAbort);
  72.   swi(OS_ChangeEnvironment,IN(R0|R1)|OUT(R1),3,&VDataAbort,&w->OldDataAbort);
  73.   swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3)|OUT(R1|R2|R3),7,&VCallBack,w,&w->regs,
  74.                                    &w->OldCallBack,&w->OldCallBackR12,&w->OldCallBackRegs);
  75.   swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&VError,&w->errnum,&w->errPC);
  76.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&VUpCall,w);
  77.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&VExit,w);
  78.   oldswi=*swivec;
  79.   if (oldswi>>24==0xEA)
  80.     ; /* B */
  81.   oldswi=8+(int)swivec+(oldswi<<8>>6);
  82.   w->OldSWIV=oldswi;
  83.   workOldSWIV=oldswi;
  84.   *swivec=(int)&VSWIV-8-(int)swivec>>2|0xEA000000;
  85. }
  86.  
  87.  void ReleaseVVecs(WKSP *w) 
  88. {
  89.   *swivec=w->OldSWIV-8-(int)swivec>>2|0xEA000000;
  90.   swi(OS_ChangeEnvironment,IN(R0|R1),2,w->OldPrefetchAbort);
  91.   swi(OS_ChangeEnvironment,IN(R0|R1),3,w->OldDataAbort);
  92.   swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),7,w->OldCallBack,w->OldCallBackR12,w->OldCallBackRegs);
  93.   swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&NormError,w,&w->errPC);
  94.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&NormUpCall,w);
  95.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&NormExit,w);
  96. }
  97.  
  98.  void ClaimExtVecs( WKSP *w ) 
  99. { swi(OS_Claim,IN(R0|R1|R2),3,&ExtWriteC,w);
  100.   swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&ExtError,w,&w->errPC);
  101.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&ExtUpCall,w);
  102.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&ExtExit,w);
  103. }
  104.  
  105.  void ReleaseExtVecs( WKSP *w ) 
  106. { swi(OS_Release,IN(R0|R1|R2),3,&ExtWriteC,w);
  107.   swi(OS_ChangeEnvironment,IN(R0|R1|R2|R3),6,&NormError,w,&w->errPC);
  108.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),16,&NormUpCall,w);
  109.   swi(OS_ChangeEnvironment,IN(R0|R1|R2),11,&NormExit,w);
  110. }
  111.  
  112.  void Virtual(WKSP *w) 
  113. {
  114.   virtualmem(w);
  115.   ClaimVVecs(w);
  116. }
  117.  
  118.  void Normal(WKSP *w) 
  119. {
  120.   ReleaseVVecs(w);
  121.   normalmem(w);
  122. }
  123.  
  124.  void V2Ext( WKSP *w ) 
  125. {
  126.   ReleaseVVecs(w);
  127.   ClaimExtVecs(w);
  128. }
  129.  
  130.  void Ext2V( WKSP *w ) 
  131. {
  132.   ReleaseExtVecs(w);
  133.   ClaimVVecs(w);
  134. }
  135.  
  136.  void Ext2Norm( WKSP *w) 
  137. {
  138.   ReleaseExtVecs(w);
  139.   normalmem(w);
  140. }
  141.  
  142.  void Norm2Ext( WKSP *w) 
  143. {
  144.   virtualmem(w);
  145.   ClaimExtVecs(w);
  146. }
  147.  
  148.  
  149. /* ******************** Virtual mode handlers */
  150.  WKSP *CVWantAddr(WKSP *w, int start, int len) 
  151. {
  152.   if (len<0)
  153.     start += len, len= -len;
  154.   if (w->regs[15]&3)
  155.   { Normal(w);
  156.     printf("***** CWantAddr called from non-user mode. Disaster! *****\n");
  157.     RealDoOff(w);
  158.   }
  159.   if (!WriteRange(w,start,start+len))
  160.   { Normal(w);
  161.     printf("***** CWantAddr can't get desired area: %08x+%08x****\n",start,len);
  162.     RealDoOff(w);
  163.   }
  164.   return w;
  165. }
  166.  
  167.  void doeschand(WKSP *w,int n) 
  168. { w->EscapeCondition = n;
  169. #ifndef FIXED_SYSTEMCALL_VERSION_FO
  170.   if (w->Escape)
  171.   { Normal(w);
  172.     printf("(should call escape handler at %08x)",w->Escape);
  173.     Virtual(w);
  174.   }
  175. #else
  176.   if (w->Escape != -1) {
  177.     int result, * ruser = w->regs;
  178.     if (w->EscapeR12 != -1)
  179.         WriteRange(w, w->EscapeR12, w->EscapeR12+512);
  180.     ReadRange(w, w->Escape, w->Escape+8);
  181.     result = CallEscapeHandler(w->Escape, w->EscapeR12, (w->EscapeCondition == 2) ? 0x40 : 0);
  182.     if (result == 1) {
  183.         int j, * rcallback = (int *) w->CallBackBuf;
  184.         /* call back flag is set */
  185.         WriteRange(w, w->CallBackR12, w->CallBackR12 + 512);
  186.         WriteRange(w, w->CallBackBuf, w->CallBackBuf + 16 * 4);
  187.         ReadRange(w, w->CallBack, w->CallBack + 8);
  188.         for (j = 0; j < 16; j++)
  189.                 rcallback[j] = ruser[j];        /* save user registers into callback buffer */
  190.         ruser[12] = w->CallBackR12;
  191.         ruser[15] = w->CallBack;
  192.         incallback = 1;
  193.     }
  194.   }
  195. #endif
  196. }
  197.  
  198.  WKSP *CVCallBack(WKSP *w) 
  199. { Normal(w);
  200.   Poll(w);
  201.   Virtual(w);
  202.   if (1==w->EscapeCondition)
  203.     doeschand(w,2);
  204.   worksemaphore=1;      /* Ready to reenable when we exit */
  205.   return w;
  206. }
  207.  
  208.  WKSP *CVSWIV(WKSP *w,int instr) 
  209. {
  210.   int *r=w->regs;
  211.   char s[256];
  212.   struct Error *err=0;
  213.   int psw,i;
  214.   int swinum=instr&~(XOS_Bit|0xFF000000);
  215.   r[15]&=~V_bit;
  216. #if 0
  217.     Normal(w);
  218.     swi(OS_SWINumberToString,IN(R0|R1|R2),instr&0xFFFFFF,s,256);
  219.     printf("Swi %s PC=%08x ",s,r[15]);
  220.     for (i=0;i<=14;i++)
  221.       printf("R%d=%08x ",i,r[i]);
  222.     printf("...");
  223.     Virtual(w);
  224. #endif
  225.   switch(swinum) {
  226.   /* input/output */
  227.  
  228.    /*
  229.     * OS SWIs
  230.     */
  231.  
  232.    case OS_WriteC: 
  233.     outc(w,r[0]);
  234.     break;
  235.   
  236.    case OS_Write0: 
  237.     { char *p;
  238.       ReadRange(w,r[0],r[0]+1);
  239.       for (p=(char *)r[0];*p;p++)
  240.       { ReadPtr(w,(int)p);
  241.         outc(w,*p);
  242.       }
  243.       r[0]=(int)++p;
  244.     }
  245.     break;
  246.   
  247.    case OS_WriteS: 
  248.     { char *p=(char *)(r[15]&~0xfc000003);
  249.       char *q=p;
  250.       for (;*p;p++)
  251.       { ReadPtr(w,(int)p);
  252.         outc(w,*p);
  253.       }
  254.       r[15]+=(((p+1)-q)|3)+1;
  255.     }
  256.     break;
  257.   
  258.    case OS_WriteN: 
  259.     { int n;
  260.       for ( n=0; n<r[1]; n++ )
  261.       { ReadPtr(w,r[0]+n);
  262.         outc(w,((char *)r[0])[n]);
  263.       }
  264.     }
  265.     break;
  266.   
  267.    case OS_NewLine: 
  268.     outc(w,'\r'); outc(w,'\n');
  269.     break;
  270.   
  271.    case OS_ReadC: 
  272.     r[0]=getc(w);
  273.     if (-1==r[0])
  274.     { r[0] = 27;
  275.       r[15]|=C_bit;
  276.     }
  277.     else
  278.       r[15]&=~C_bit;
  279.     if (1==w->EscapeCondition)
  280.       doeschand(w,2);
  281.     break;
  282.   
  283.    case OS_ReadLine: 
  284.     { char buf[256];
  285.       int n=0,c;
  286.       r[15]&=~C_bit;
  287.       for (;;)
  288.       { c=getc(w);
  289.         switch (c)
  290.         {
  291.            case 13: case 10: 
  292.             buf[n]=13;
  293.             break;
  294.           
  295.            case 27: case -1: 
  296.             r[15]|=C_bit;
  297.             break;
  298.           
  299.            case 127: case 8: 
  300.             if (n>0)
  301.             { outc(w,127); n--; }
  302.             else
  303.               outc(w,7);
  304.             continue;
  305.           
  306.            case 21: 
  307.             while (n>0)
  308.             { outc(w,127); n--; }
  309.             continue;
  310.           
  311.            default: 
  312.             if (r[2]<=c && c<=r[3])
  313.             { if (n<r[1]-1 && n<255)
  314.               { buf[n++]=c;
  315.                 outc(w,c);
  316.               }
  317.               else
  318.                 outc(w,7);
  319.             }
  320.             else
  321.               outc(w,7);
  322.             continue;
  323.           
  324.         }
  325.         outc(w,'\r'); outc(w,'\n');
  326.         break;
  327.       }
  328.       WriteRange(w,r[0],r[0]+n+1);
  329.       memcpy((void *)r[0],buf,n+1);
  330.       r[1]=n;
  331.     }
  332.     if (1==w->EscapeCondition)
  333.       doeschand(w,2);
  334.     break;
  335.  
  336.    case OS_Byte: 
  337.     switch (r[0])
  338.     { default: goto uk;
  339.       case 0:           /* display os version */
  340.         Normal(w);
  341.         err = swix(OS_Byte,IN(R0|R1)|OUT(R1),0,r[1],&r[1]);
  342.         Virtual(w);
  343.         break;
  344.       case 2:           /* switch input streams */
  345. #ifdef DEBUG
  346.         Normal(w);
  347.         prin