home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / TIERRA40.ZIP / TIERRA / PARSE4.C < prev    next >
C/C++ Source or Header  |  1992-09-09  |  35KB  |  1,003 lines

  1. /* parse4.c   9-9-92  parser functions for instruction set 4 */
  2. /* Tierra Simulator V4.0: Copyright (c) 1991, 1992 Tom Ray & Virtual Life */
  3.  
  4. #if INST == 4
  5.  
  6. /* in INST == 4, the array of registers maps into the registers ax, bx, cx, dx
  7.    as follows:  c.re[0] = ax, c.re[1] = bx, c.re[2] = cx, c.re[3] = dx
  8.  
  9.     {0x00, "nop0", nop, pnop},
  10.     {0x01, "nop1", nop, pnop},
  11.     {0x02, "movdi", movdi, pmovdi},
  12.     {0x03, "movid", movid, pmovid},
  13.     {0x04, "movii", movii, pmovii},
  14.     {0x05, "pushax", push, ppushax},
  15.     {0x06, "pushbx", push, ppushbx},
  16.     {0x07, "pushcx", push, ppushcx},
  17.     {0x08, "pushdx", push, ppushdx},
  18.     {0x09, "popax", pop, ppopax},
  19.     {0x0a, "popbx", pop, ppopbx},
  20.     {0x0b, "popcx", pop, ppopcx},
  21.     {0x0c, "popdx", pop, ppopdx},
  22.     {0x0d, "put", put, pput},
  23.     {0x0e, "get", get, pget},
  24.     {0x0f, "inc", math, pinc},
  25.     {0x10, "dec", math, pdec},
  26.     {0x11, "add", math, padd},
  27.     {0x12, "sub", math, psub},
  28.     {0x13, "zero", movdd, pzero},
  29.     {0x14, "shl", shl, pshl},
  30.     {0x15, "not0", not0, pnot0},
  31.     {0x16, "ifz", ifz, pifz},
  32.     {0x17, "iffl", ifz, piffl},
  33.     {0x18, "jmp", adr, ptjmp},
  34.     {0x19, "jmpb", adr, ptjmpb},
  35.     {0x1a, "call", tcall, ptcall},
  36.     {0x1b, "adr", adr, padr},
  37.     {0x1c, "adrb", adr, padrb},
  38.     {0x1d, "adrf", adr, padrf},
  39.     {0x1e, "mal", malchm, pmal},
  40.     {0x1f, "divide", divide, pdivide}
  41. */
  42.  
  43. void pnop(ce) /* do nothing */
  44. Pcells  ce;
  45. {   is.iip = is.dib = 1; }
  46.  
  47. /* void movdi(ce) is.dins->inst = is.sval + flaw(ce);
  48.  * is.dval  = address of destination instruction
  49.  * is.dins  = pointer to destination instruction
  50.  * is.sval  = value to be moved to destination instruction
  51.  * is.sval2 = original value of destination instruction
  52.  */
  53. void pmovdi(ce) /* soup [AX + CX] = BX */
  54. Pcells  ce;
  55. {   I32s  tval, tval2;
  56.  
  57.     is.iip = is.dib = 1;
  58.     if (is.eins->exec)
  59.         return ;
  60.     tval  = flaw(ce); /* AX */
  61.     tval  = ce->c.re[mo(tval,NUMREG)] + flaw(ce);
  62.     tval2 = 2 + flaw(ce); /* CX */
  63.     tval2 = ce->c.re[mo(tval2,NUMREG)] + flaw(ce);
  64.     is.dval = ad(tval + tval2);
  65.     tval = 1 + flaw(ce); /* BX */
  66.     is.sval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  67. #if PLOIDY == 1
  68.     is.dins = &soup[is.dval];
  69. #else /* PLOIDY > 1 */
  70.     is.dins = &soup[is.dval][ce->d.tr];
  71. #endif /* PLOIDY > 1 */
  72.     is.sval2 = is.dins->inst;
  73. }
  74.  
  75. /* void movid(ce) *(is.dreg) = is.sins->inst + flaw(ce);
  76.  * is.sins = pointer to source instruction
  77.  * is.sval = address of source instruction
  78.  * is.dreg = destination register, where moved value will be placed
  79.  * is.dmod = value by which to modulus destination register
  80.  * is.dran = range within which to contain destination register
  81.  */
  82. void pmovid(ce) /* AX = soup [BX + CX] */
  83. Pcells  ce;
  84. {   I32s  tval, tval2;
  85.  
  86.     is.iip = is.dib = 1;
  87.     if (is.eins->exec)
  88.         return ;
  89.     tval = flaw(ce); /* AX */
  90.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  91.     tval = 1 + flaw(ce); /* BX */
  92.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  93.     tval2 = 2 + flaw(ce); /* CX */
  94.     tval2 = ce->c.re[mo(tval2, NUMREG)] + flaw(ce);
  95.     is.sval = ad(tval + tval2);
  96. #if PLOIDY == 1
  97.     is.sins = &soup[is.sval];
  98. #else /* PLOIDY > 1 */
  99.     is.sins = &soup[is.sval][ce->d.tr];
  100. #endif /* PLOIDY > 1 */
  101.     is.dran = SoupSize;
  102. }
  103.  
  104. /* void movii(ce) is.dins->inst = is.sins->inst;
  105.  * is.dval  = address of destination instruction
  106.  * is.sval  = address of source instruction
  107.  * is.dins  = pointer to destination instruction
  108.  * is.sins  = pointer to source instruction
  109.  * is.dtra  = track of destination instruction
  110.  * is.sval2 = original value of destination instruction
  111.  */
  112. void pmovii(ce) /* soup [AX + CX] = soup [BX + CX] */
  113. Pcells  ce;
  114. {   I32s  tval, tval2;
  115.  
  116.     is.iip = is.dib = 1;
  117.     if (is.eins->exec)
  118.         return ;
  119.     tval2 = 2 + flaw(ce); /* CX */
  120.     tval2 = ce->c.re[mo(tval2, NUMREG)] + flaw(ce);
  121.     tval  = flaw(ce); /* AX */
  122.     tval  = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  123.     is.dval = ad(tval + tval2);
  124.     tval = 1 + flaw(ce); /* BX */
  125.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  126.     is.sval = ad(tval + tval2);
  127. #if PLOIDY == 1
  128.     is.dins = &soup[is.dval];
  129.     is.sins = &soup[is.sval];
  130. #else /* PLOIDY > 1 */
  131.     is.dins = &soup[is.dval][ce->d.tr];
  132.     is.sins = &soup[is.sval][ce->d.tr];
  133. #endif /* PLOIDY > 1 */
  134.     is.dtra = ce->d.tr;
  135.     is.sval2 = is.dins->inst;
  136. #ifdef HSEX
  137.     if (ce->d.x_over_addr)
  138.     {   if ((!ce->d.mov_daught) && (!FindMate(ce)))
  139.             ce->d.x_over_addr = ce->d.mate_addr = 0;
  140.         else UseMate(ce);
  141.     }
  142. #endif
  143. }
  144.  
  145. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  146.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  147.  * is.sval = value to be pushed onto the stack
  148.  */
  149. void ppushax(ce) /* push AX onto stack */
  150. Pcells  ce;
  151. {   I32s  tval;
  152.  
  153.     is.iip = is.dib = 1;
  154.     if (is.eins->exec)
  155.         return ;
  156.     tval = flaw(ce); /* AX */
  157.     is.sval = ce->c.re[mo(tval, NUMREG)];
  158. }
  159.  
  160. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  161.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  162.  * is.sval = value to be pushed onto the stack
  163.  */
  164. void ppushbx(ce) /* push BX onto stack */
  165. Pcells  ce;
  166. {   I32s  tval;
  167.  
  168.     is.iip = is.dib = 1;
  169.     if (is.eins->exec)
  170.         return ;
  171.     tval = 1 + flaw(ce); /* BX */
  172.     is.sval = ce->c.re[mo(tval, NUMREG)];
  173. }
  174.  
  175. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  176.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  177.  * is.sval = value to be pushed onto the stack
  178.  */
  179. void ppushcx(ce) /* push CX onto stack */
  180. Pcells  ce;
  181. {   I32s  tval;
  182.  
  183.     is.iip = is.dib = 1;
  184.     if (is.eins->exec)
  185.         return ;
  186.     tval = 2 + flaw(ce); /* CX */
  187.     is.sval = ce->c.re[mo(tval, NUMREG)];
  188. }
  189.  
  190. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  191.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  192.  * is.sval = value to be pushed onto the stack
  193.  */
  194. void ppushdx(ce) /* push DX onto stack */
  195. Pcells  ce;
  196. {   I32s  tval;
  197.  
  198.     is.iip = is.dib = 1;
  199.     if (is.eins->exec)
  200.         return ;
  201.     tval = 3 + flaw(ce); /* DX */
  202.     is.sval = ce->c.re[mo(tval, NUMREG)];
  203. }
  204.  
  205. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  206.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  207.  * is.dreg = destination register, where value popped off stack will go
  208.  * is.dmod = value by which to modulus destination register
  209.  * is.dran = range within which to contain destination register
  210.  */
  211. void ppopax(ce) /* pop AX off of stack */
  212. Pcells  ce;
  213. {   I32s  tval;
  214.  
  215.     is.iip = is.dib = 1;
  216.     if (is.eins->exec)
  217.         return ;
  218.     tval = flaw(ce); /* AX */
  219.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  220.     is.dran = SoupSize;
  221. }
  222.  
  223. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  224.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  225.  * is.dreg = destination register, where value popped off stack will go
  226.  * is.dmod = value by which to modulus destination register
  227.  * is.dran = range within which to contain destination register
  228.  */
  229. void ppopbx(ce) /* pop BX off of stack */
  230. Pcells  ce;
  231. {   I32s  tval;
  232.  
  233.     is.iip = is.dib = 1;
  234.     if (is.eins->exec)
  235.         return ;
  236.     tval = 1 + flaw(ce); /* BX */
  237.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  238.     is.dran = SoupSize;
  239. }
  240.  
  241. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  242.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  243.  * is.dreg = destination register, where value popped off stack will go
  244.  * is.dmod = value by which to modulus destination register
  245.  * is.dran = range within which to contain destination register
  246.  */
  247. void ppopcx(ce) /* pop CX off of stack */
  248. Pcells  ce;
  249. {   I32s  tval;
  250.  
  251.     is.iip = is.dib = 1;
  252.     if (is.eins->exec)
  253.         return ;
  254.     tval = 2 + flaw(ce); /* CX */
  255.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  256.     is.dran = SoupSize;
  257. }
  258.  
  259. /* void pop(ce) *(is.dreg) = ce->c.st[ce->c.sp] + flaw(ce);
  260.  *              if (!ce->c.sp) ce->c.sp = STACK_SIZE - 1; else --ce->c.sp;
  261.  * is.dreg = destination register, where value popped off stack will go
  262.  * is.dmod = value by which to modulus destination register
  263.  * is.dran = range within which to contain destination register
  264.  */
  265. void ppopdx(ce) /* pop DX off of stack */
  266. Pcells  ce;
  267. {   I32s  tval;
  268.  
  269.     is.iip = is.dib = 1;
  270.     if (is.eins->exec)
  271.         return ;
  272.     tval = 3 + flaw(ce); /* DX */
  273.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  274.     is.dran = SoupSize;
  275. }
  276.  
  277. /* void put(ce) write a value to the output buffer
  278.  * ce->c.pb[PUTBUFSIZ]     == pointer to next output value to be written
  279.  * ce->c.pb[PUTBUFSIZ + 1] == pointer to next output value to be read
  280.  * ce->c.pb[PUTBUFSIZ + 2] == number of unread output values
  281.  *
  282.  * is.dcel  = destination cell, in whose buffer the value will be put
  283.  * is.dreg  = destination "register" in the put buffer
  284.  * is.dval3 = destination for address returned by adr()
  285.  * is.mode3 = #ifdef ICC:  0 = broadcast to other cells' get buffer
  286.  *                         1 = write to other cell's get buffer
  287.  *            #ifndef ICC: write to own put buffer (prayer)
  288.  * is.sval  = value to be placed in the dest reg
  289.  *
  290.  * #ifndef ICC specify the values used by movdd():
  291.  * is.dreg = destination register, where moved value will be placed
  292.  * is.sval = value to be placed in the dest reg
  293.  * is.dmod = value by which to modulus destination register
  294.  * is.dran = range within which to contain destination register
  295.  *
  296.  * #ifdef ICC specify the values used by adr():
  297.  * void adr(ce) find address of a template
  298.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  299.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  300.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  301.  * is.dval  = starting address for forward search
  302.  * is.dval2 = starting address for backward search
  303.  * is.dreg  = destination register where target address will be stored
  304.  * is.dreg2 = destination register where template size will be stored
  305.  * is.dreg3 = destination register where offset of target will be stored
  306.  * is.sval  = return address if template size = 0
  307.  * is.sval2 = template size, 0 = no template
  308.  * is.sval3 = search limit, and return for distance actually searched
  309.  * is.dmod  = modulus value for is.dreg
  310.  * is.dmod2 = modulus value for is.dreg2
  311.  * is.dmod3 = modulus value for is.dreg3
  312.  * is.dran  = range to maintain for is.dreg
  313.  * is.dran2 = range to maintain for is.dreg2
  314.  * is.dran3 = range to maintain for is.dreg3
  315.  */
  316. void pput(ce) /* write DX to output port; or if put template, put to input */
  317. Pcells  ce;   /* port of creature(s) with complementary get template */
  318. {   I32s    a, s = 0, adre, tval;
  319.     Pcells  dc;
  320.     I8s     md;
  321.  
  322.     is.iip = is.dib = 1;
  323.     if (is.eins->exec)
  324.         return ;
  325. #ifdef ICC
  326.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  327.     while(1) /* find size of template, s = size */
  328.     {
  329. #if PLOIDY == 1
  330.         if(soup[ad(a + s)].inst != Nop0 &&
  331.            soup[ad(a + s)].inst != Nop1)
  332. #else /* PLOIDY > 1 */
  333.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  334.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  335. #endif /* PLOIDY > 1 */
  336.             break;
  337.         s++;
  338.     }
  339.     tval = 3 + flaw(ce); /* DX */
  340.     is.sval = ce->c.re[mo(tval, NUMREG)];
  341.     if (s)
  342.     {   is.dreg  = &is.dval3;  /* dest register for address */
  343.         is.dreg2 = &BitBucket; /* dest reg for template size */
  344.         is.dreg3 = &BitBucket; /* dest reg for offset */
  345.         is.sval2 = s;
  346.         is.sval3 = Put_limit;
  347.         is.dval  = ce->mm.p + ce->mm.s;
  348.         is.dval2 = ce->mm.p - 1;
  349.         is.mode  = 0;
  350.         is.mode2 = 1;
  351.         is.mode3 = 0;
  352.         is.iip   = s + 1;
  353.     }
  354.     else
  355.     {   tval = 2 + flaw(ce); /* CX */
  356.         tval = ce->c.re[mo(tval, NUMREG)];
  357.         tval = ad(tval);
  358.         if (!IsFree(tval))
  359.             WhichCell(tval, &is.dcel, &md);
  360.         else
  361.             is.dreg = &BitBucket;
  362.         is.mode3 = 1;
  363.     }
  364. #else  /* ICC */
  365.     tval = 3 + flaw(ce); /* DX */
  366.     is.sval = ce->c.re[mo(tval, NUMREG)];
  367.     is.dreg = &ce->c.pb[ce->c.pb[PUTBUFSIZ]];
  368. #endif /* ICC */
  369. }
  370.  
  371. /* void get(ce) *(is.dreg) = is.sval + flaw(ce);
  372.  * ce->c.gb[GETBUFSIZ]     == pointer to next input value to be read
  373.  * ce->c.gb[GETBUFSIZ + 1] == pointer to next input value to be written
  374.  * ce->c.gb[GETBUFSIZ + 2] == number of unread input values
  375.  *
  376.  * specify the values used by movdd():
  377.  * void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  378.  * is.dreg = destination register, where moved value will be placed
  379.  * is.sval = value to be placed in the dest reg
  380.  * is.dmod = value by which to modulus destination register
  381.  * is.dran = range within which to contain destination register
  382.  */
  383. void pget(ce) /* read from input port into DX */
  384. Pcells  ce;
  385. {   I32s    a, tval;
  386.  
  387.     is.iip = is.dib = 1;
  388.     if (is.eins->exec)
  389.         return ;
  390.     tval = 3 + flaw(ce); /* DX */
  391.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  392.     is.sval = ce->c.gb[ce->c.gb[GETBUFSIZ]];
  393.     is.dran = SoupSize;
  394.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  395.     while(1) /* find size of template, s = size */
  396.     {
  397. #if PLOIDY == 1
  398.         if(soup[ad(a)].inst != Nop0 &&
  399.            soup[ad(a)].inst != Nop1)
  400. #else /* PLOIDY > 1 */
  401.         if(soup[ad(a)][ce->d.tr].inst != Nop0 &&
  402.            soup[ad(a)][ce->d.tr].inst != Nop1)
  403. #endif /* PLOIDY > 1 */
  404.             break;
  405.         a++; is.iip++;
  406.     }
  407. }
  408.  
  409. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  410.  * is.dreg  = destination register, where calculation will be stored
  411.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  412.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  413.  * is.dmod  = value by which to modulus destination register
  414.  * is.dran  = range within which to contain destination register
  415.  */
  416. void pinc(ce) /* CX++ */
  417. Pcells  ce;
  418. {   I32s  tval;
  419.  
  420.     is.iip = is.dib = 1;
  421.     if (is.eins->exec)
  422.         return ;
  423.     tval = 2 + flaw(ce); /* CX */
  424.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  425.     tval = 2 + flaw(ce); /* CX */
  426.     is.sval = ce->c.re[mo(tval, NUMREG)];
  427.     is.sval2 = 1;
  428.     is.dran = SoupSize;
  429. }
  430.  
  431. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  432.  * is.dreg  = destination register, where calculation will be stored
  433.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  434.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  435.  * is.dmod  = value by which to modulus destination register
  436.  * is.dran  = range within which to contain destination register
  437.  */
  438. void pdec(ce) /* CX-- */
  439. Pcells  ce;
  440. {   I32s  tval;
  441.  
  442.     is.iip = is.dib = 1;
  443.     if (is.eins->exec)
  444.         return ;
  445.     tval = 2 + flaw(ce); /* CX */
  446.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  447.     tval = 2 + flaw(ce); /* CX */
  448.     is.sval = ce->c.re[mo(tval, NUMREG)];
  449.     is.sval2 = -1;
  450.     is.dran = SoupSize;
  451. }
  452.  
  453. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  454.  * is.dreg  = destination register, where calculation will be stored
  455.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  456.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  457.  * is.dmod  = value by which to modulus destination register
  458.  * is.dran  = range within which to contain destination register
  459.  */
  460. void padd(ce) /* CX = CX + DX */
  461. Pcells  ce;
  462. {   I32s  tval;
  463.  
  464.     is.iip = is.dib = 1;
  465.     if (is.eins->exec)
  466.         return ;
  467.     tval = 2 + flaw(ce); /* CX */
  468.     is.dreg  = &(ce->c.re[mo(tval, NUMREG)]);
  469.     tval = 2 + flaw(ce); /* CX */
  470.     is.sval  = ce->c.re[mo(tval, NUMREG)];
  471.     tval = 3 + flaw(ce); /* DX */
  472.     is.sval2 = ce->c.re[mo(tval, NUMREG)];
  473.     is.dran = SoupSize;
  474. }
  475.  
  476. /* void math(ce) *(is.dreg) = is.sval + is.sval2 + flaw(ce);
  477.  * is.dreg  = destination register, where calculation will be stored
  478.  * is.sval  = a value that will be added to is.sval2 and placed in dest reg
  479.  * is.sval2 = a value that will be added to is.sval  and placed in dest reg
  480.  * is.dmod  = value by which to modulus destination register
  481.  * is.dran  = range within which to contain destination register
  482.  */
  483. void psub(ce) /* CX = CX - DX */
  484. Pcells  ce;
  485. {   I32s  tval;
  486.  
  487.     is.iip = is.dib = 1;
  488.     if (is.eins->exec)
  489.         return ;
  490.     tval = 2 + flaw(ce); /* CX */
  491.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  492.     tval = 2 + flaw(ce); /* CX */
  493.     is.sval  =  ce->c.re[mo(tval, NUMREG)];
  494.     tval = 3 + flaw(ce); /* DX */
  495.     is.sval2 = -ce->c.re[mo(tval, NUMREG)];
  496.     is.dran = SoupSize;
  497. }
  498.  
  499. /* void movdd(ce) *(is.dreg) = is.sval + flaw(ce);
  500.  * is.dreg = destination register, where moved value will be placed
  501.  * is.sval = value to be placed in the dest reg
  502.  * is.dmod = value by which to modulus destination register
  503.  * is.dran = range within which to contain destination register
  504.  */
  505. void pzero(ce) /* CX = 0 */
  506. Pcells  ce;
  507. {   I32s  tval;
  508.  
  509.     is.iip = is.dib = 1;
  510.     if (is.eins->exec)
  511.         return ;
  512.     tval = 2 + flaw(ce); /* CX */
  513.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  514.     is.sval = 0;
  515. }
  516.  
  517. /* void not0(ce) *(is.dreg) ^= (1 + flaw(ce));
  518.  * is.dreg = destination register, whose bit will be flipped
  519.  * is.dmod = value by which to modulus destination register
  520.  * is.dran = range within which to contain destination register
  521.  */
  522. void pnot0(ce) /* flip low order bit of CX */
  523. Pcells  ce;
  524. {   I32s  tval;
  525.  
  526.     is.iip = is.dib = 1;
  527.     if (is.eins->exec)
  528.         return ;
  529.     tval = 2 + flaw(ce); /* CX */
  530.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  531.     is.dran = SoupSize;
  532. }
  533.  
  534. /* void shl(ce) *(is.dreg) <<= (Reg) (1 + flaw(ce));
  535.  * is.dreg = destination register, whose bits will be shifted left
  536.  * is.dmod = value by which to modulus destination register
  537.  * is.dran = range within which to contain destination register
  538.  */
  539. void pshl(ce) /* shift left all bits of CX */
  540. Pcells  ce;
  541. {   I32s  tval;
  542.  
  543.     is.iip = is.dib = 1;
  544.     if (is.eins->exec)
  545.         return ;
  546.     tval = 2 + flaw(ce); /* CX */
  547.     is.dreg = &(ce->c.re[mo(tval, NUMREG)]);
  548.     is.dran = SoupSize;
  549. }
  550.  
  551. /* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2;
  552.  * is.sval  = value to test for zero
  553.  * is.sval2 = amount to increment IP if is.sval == 0
  554.  * is.iip   = amount to increment IP if is.sval != 0
  555.  */
  556. void pifz(ce) /* execute next instruction, if CX == 0 */
  557. Pcells  ce;
  558. {   I32s  tval;
  559.  
  560.     is.iip = is.dib = 1;
  561.     if (is.eins->exec)
  562.         return ;
  563.     tval = 2 + flaw(ce); /* CX */
  564.     is.sval = ce->c.re[mo(tval, NUMREG)];
  565.     is.sval2 = 2;
  566. }
  567.  
  568. /* void ifz(ce) if (is.sval + flaw(ce)) is.iip = is.sval2;
  569.  * is.sval  = value to test for zero
  570.  * is.sval2 = amount to increment IP if is.sval == 0
  571.  * is.iip   = amount to increment IP if is.sval != 0
  572.  */
  573. void piffl(ce) /* skip next instruction, if flag == 0 */
  574. Pcells  ce;
  575. {   is.iip = is.dib = 1;
  576.     if (is.eins->exec)
  577.         return ;
  578.     is.sval = ce->c.fl;
  579.     is.sval2 = 1;
  580.     is.iip = 2;
  581.     is.dib = 1;
  582. }
  583.  
  584. /* void adr(ce) find address of a template
  585.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  586.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  587.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  588.  * is.dval  = starting address for forward search
  589.  * is.dval2 = starting address for backward search
  590.  * is.dreg  = destination register where target address will be stored
  591.  * is.dreg2 = destination register where template size will be stored
  592.  * is.dreg3 = destination register where offset of target will be stored
  593.  * is.sval  = return address if template size = 0
  594.  * is.sval2 = template size, 0 = no template
  595.  * is.sval3 = search limit, and return for distance actually searched
  596.  * is.dmod  = modulus value for is.dreg
  597.  * is.dmod2 = modulus value for is.dreg2
  598.  * is.dmod3 = modulus value for is.dreg3
  599.  * is.dran  = range to maintain for is.dreg
  600.  * is.dran2 = range to maintain for is.dreg2
  601.  * is.dran3 = range to maintain for is.dreg3
  602.  */
  603. void ptjmp(ce) /* outward template jump */
  604. Pcells  ce;
  605. {   I32s    a, s = 0, tval;
  606.  
  607.     is.iip = is.dib = 1;
  608.     if (is.eins->exec)
  609.         return ;
  610.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  611.     while(1) /* find size of template, s = size */
  612.     {   
  613. #if PLOIDY == 1
  614.         if(soup[ad(a + s)].inst != Nop0 &&
  615.            soup[ad(a + s)].inst != Nop1)
  616. #else /* PLOIDY > 1 */
  617.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  618.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  619. #endif /* PLOIDY > 1 */
  620.             break;
  621.         s++;
  622.     }
  623.     is.dreg  = &(ce->c.ip); /* destination register for address */
  624.     is.dreg2 = &BitBucket; /* destination register for template size */
  625.     is.dreg3 = &BitBucket; /* dest reg for offset */
  626.     tval = flaw(ce); /* AX */
  627.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  628.     is.sval  = ad(tval); /* target for IP if s == 0 */
  629.     is.sval2 = s;  /* size of template */
  630.     is.sval3 = Search_limit;
  631.     is.dmod  = SoupSize;
  632.     is.dval  = ad(a + s + 1); /* start address for forward search */
  633.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  634.     is.mode  = 0; /* outward jump */
  635.     is.mode2 = 1;
  636.     is.dib = 1;
  637.     is.iip = 0;
  638. }
  639.  
  640. /* void adr(ce) find address of a template
  641.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  642.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  643.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  644.  * is.dval  = starting address for forward search
  645.  * is.dval2 = starting address for backward search
  646.  * is.dreg  = destination register where target address will be stored
  647.  * is.dreg2 = destination register where template size will be stored
  648.  * is.dreg3 = destination register where offset of target will be stored
  649.  * is.sval  = return address if template size = 0
  650.  * is.sval2 = template size, 0 = no template
  651.  * is.sval3 = search limit, and return for distance actually searched
  652.  * is.dmod  = modulus value for is.dreg
  653.  * is.dmod2 = modulus value for is.dreg2
  654.  * is.dmod3 = modulus value for is.dreg3
  655.  * is.dran  = range to maintain for is.dreg
  656.  * is.dran2 = range to maintain for is.dreg2
  657.  * is.dran3 = range to maintain for is.dreg3
  658.  */
  659. void ptjmpb(ce) /* backward template jump */
  660. Pcells  ce;
  661. {   I32s    a, s = 0, tval;
  662.  
  663.     is.iip = is.dib = 1;
  664.     if (is.eins->exec)
  665.         return ;
  666.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  667.     while(1) /* find size of template, s = size */
  668.     {   
  669. #if PLOIDY == 1
  670.         if(soup[ad(a + s)].inst != Nop0 &&
  671.            soup[ad(a + s)].inst != Nop1)
  672. #else /* PLOIDY > 1 */
  673.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  674.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  675. #endif /* PLOIDY > 1 */
  676.             break;
  677.         s++;
  678.     }
  679.     is.dreg  = &(ce->c.ip); /* destination register for address */
  680.     is.dreg2 = &BitBucket; /* destination register for template size */
  681.     is.dreg3 = &BitBucket; /* dest reg for offset */
  682.     tval = flaw(ce); /* AX */
  683.     tval = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  684.     is.sval  = ad(tval); /* target for IP if s == 0 */
  685.     is.sval2 = s;  /* size of template */
  686.     is.sval3 = Search_limit;
  687.     is.dmod  = SoupSize;
  688.     is.dval  = ad(a + s + 1); /* start address for forward search */
  689.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  690.     is.mode  = 2; /* backward jump */
  691.     is.mode2 = 2;
  692.     is.dib = 1;
  693.     is.iip = 0;
  694. }
  695.  
  696. /* void tcall(ce) adr(ce); push(ce); */
  697. /* void adr(ce) find address of a template
  698.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  699.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  700.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  701.  * is.dval  = starting address for forward search
  702.  * is.dval2 = starting address for backward search
  703.  * is.dreg  = destination register where target address will be stored
  704.  * is.dreg2 = destination register where template size will be stored
  705.  * is.dreg3 = destination register where offset of target will be stored
  706.  * is.sval  = return address if template size = 0
  707.  * is.sval2 = template size, 0 = no template
  708.  * is.sval3 = search limit, and return for distance actually searched
  709.  * is.dmod  = modulus value for is.dreg
  710.  * is.dmod2 = modulus value for is.dreg2
  711.  * is.dmod3 = modulus value for is.dreg3
  712.  * is.dran  = range to maintain for is.dreg
  713.  * is.dran2 = range to maintain for is.dreg2
  714.  * is.dran3 = range to maintain for is.dreg3
  715.  */
  716. /* void push(ce) ce->c.sp = ++ce->c.sp % STACK_SIZE;
  717.  *               ce->c.st[ce->c.sp] = is.sval + flaw(ce);
  718.  * is.sval = value to be pushed onto the stack
  719.  */
  720. void ptcall(ce) /* push ip to stack, outward template jump */
  721. Pcells  ce;
  722. {   I32s    a, s = 0;
  723.  
  724.     is.iip = is.dib = 1;
  725.     if (is.eins->exec)
  726.         return ;
  727.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  728.     while(1) /* find size of template, s = size */
  729.     {
  730. #if PLOIDY == 1
  731.         if(soup[ad(a + s)].inst != Nop0 &&
  732.            soup[ad(a + s)].inst != Nop1)
  733. #else /* PLOIDY > 1 */
  734.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  735.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  736. #endif /* PLOIDY > 1 */
  737.             break;
  738.         s++;
  739.     }
  740.     is.dreg  = &(ce->c.ip); /* destination register for address */
  741.     is.dreg2 = &BitBucket; /* destination register for template size */
  742.     is.dreg3 = &BitBucket; /* destination register for offset */
  743.     is.sval  = ad(ce->c.ip + s + 1); /* address to be pushed onto stack */
  744.     is.sval2 = s;  /* size of template */
  745.     is.sval3 = Search_limit;
  746.     is.dmod  = SoupSize;
  747.     is.dval  = ad(a + s + 1); /* start address for forward search */
  748.     is.dval2 = ad(a - s - 1); /* start address for backward search */
  749.     is.mode  = 0; /* outward jump */
  750.     is.mode2 = 1;
  751.     is.dib = 1;
  752.     is.iip = 0;
  753. }
  754.  
  755. /* void adr(ce) find address of a template
  756.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  757.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  758.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  759.  * is.dval  = starting address for forward search
  760.  * is.dval2 = starting address for backward search
  761.  * is.dreg  = destination register where target address will be stored
  762.  * is.dreg2 = destination register where template size will be stored
  763.  * is.dreg3 = destination register where offset of target will be stored
  764.  * is.sval  = return address if template size = 0
  765.  * is.sval2 = template size, 0 = no template
  766.  * is.sval3 = search limit, and return for distance actually searched
  767.  * is.dmod  = modulus value for is.dreg
  768.  * is.dmod2 = modulus value for is.dreg2
  769.  * is.dmod3 = modulus value for is.dreg3
  770.  * is.dran  = range to maintain for is.dreg
  771.  * is.dran2 = range to maintain for is.dreg2
  772.  * is.dran3 = range to maintain for is.dreg3
  773.  */
  774. /* search outward for template, put address in AX, template size in DX,
  775.    and offset in CX, start search at offset +- CX
  776. */
  777. void padr(ce)
  778. Pcells  ce;
  779. {   I32s    a, s = 0, tval;
  780.  
  781.     is.iip = is.dib = 1;
  782.     if (is.eins->exec)
  783.         return ;
  784.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  785.     while(1) /* find size of template, s = size */
  786.     {
  787. #if PLOIDY == 1
  788.         if(soup[ad(a + s)].inst != Nop0 &&
  789.            soup[ad(a + s)].inst != Nop1)
  790. #else /* PLOIDY > 1 */
  791.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  792.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  793. #endif /* PLOIDY > 1 */
  794.             break;
  795.         s++;
  796.     }
  797.     if (s)
  798.     {   tval = flaw(ce); /* AX */
  799.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  800.         tval = 3 + flaw(ce); /* DX */
  801.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  802.         tval = 2 + flaw(ce); /* CX */
  803.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  804.     }
  805.     else
  806.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  807.     is.sval2 = s;  /* size of template */
  808.     is.dmod  = SoupSize;
  809.     is.dran2 = SoupSize;
  810.     is.dmod3 = SoupSize;
  811.     tval = 2 + flaw(ce); /* CX */
  812.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  813.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  814.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  815.     is.sval3 = Search_limit - tval;
  816.     is.mode  = 0; /* outward search */
  817.     is.mode2 = 1;
  818.     is.iip = s + 1; is.dib = 1;
  819. }
  820.  
  821. /* void adr(ce) find address of a template
  822.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  823.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  824.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  825.  * is.dval  = starting address for forward search
  826.  * is.dval2 = starting address for backward search
  827.  * is.dreg  = destination register where target address will be stored
  828.  * is.dreg2 = destination register where template size will be stored
  829.  * is.dreg3 = destination register where offset of target will be stored
  830.  * is.sval  = return address if template size = 0
  831.  * is.sval2 = template size, 0 = no template
  832.  * is.sval3 = search limit, and return for distance actually searched
  833.  * is.dmod  = modulus value for is.dreg
  834.  * is.dmod2 = modulus value for is.dreg2
  835.  * is.dmod3 = modulus value for is.dreg3
  836.  * is.dran  = range to maintain for is.dreg
  837.  * is.dran2 = range to maintain for is.dreg2
  838.  * is.dran3 = range to maintain for is.dreg3
  839.  */
  840. /* search backward for template, put address in AX, template size in DX,
  841.    and offset in CX, start search at offset - CX
  842. */
  843. void padrb(ce)
  844. Pcells  ce;
  845. {   I32s    a, s = 0, tval;
  846.  
  847.     is.iip = is.dib = 1;
  848.     if (is.eins->exec)
  849.         return ;
  850.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  851.     while(1) /* find size of template, s = size */
  852.     {
  853. #if PLOIDY == 1
  854.         if(soup[ad(a + s)].inst != Nop0 &&
  855.            soup[ad(a + s)].inst != Nop1)
  856. #else /* PLOIDY > 1 */
  857.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  858.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  859. #endif /* PLOIDY > 1 */
  860.             break;
  861.         s++;
  862.     }
  863.     if (s)
  864.     {   tval = flaw(ce); /* AX */
  865.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  866.         tval = 3 + flaw(ce); /* DX */
  867.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  868.         tval = 2 + flaw(ce); /* CX */
  869.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  870.     }
  871.     else
  872.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  873.     is.sval2 = s;  /* size of template */
  874.     is.dmod  = SoupSize;
  875.     is.dran2 = SoupSize;
  876.     is.dmod3 = SoupSize;
  877.     tval = 2 + flaw(ce); /* CX */
  878.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  879.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  880.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  881.     is.sval3 = Search_limit - tval;
  882.     is.mode  = 2; /* backward search */
  883.     is.mode2 = 2;
  884.     is.iip = s + 1; is.dib = 1;
  885. }
  886.  
  887. /* void adr(ce) find address of a template
  888.  * is.mode  = search mode: 1 = forward, 2 = backward, 0 = outward
  889.  * is.mode2 =  preference: 1 = forward, 2 = backward, and return for
  890.  *        direction found: 1 = forward, 2 = backward, 3 = both, 0 = none
  891.  * is.dval  = starting address for forward search
  892.  * is.dval2 = starting address for backward search
  893.  * is.dreg  = destination register where target address will be stored
  894.  * is.dreg2 = destination register where template size will be stored
  895.  * is.dreg3 = destination register where offset of target will be stored
  896.  * is.sval  = return address if template size = 0
  897.  * is.sval2 = template size, 0 = no template
  898.  * is.sval3 = search limit, and return for distance actually searched
  899.  * is.dmod  = modulus value for is.dreg
  900.  * is.dmod2 = modulus value for is.dreg2
  901.  * is.dmod3 = modulus value for is.dreg3
  902.  * is.dran  = range to maintain for is.dreg
  903.  * is.dran2 = range to maintain for is.dreg2
  904.  * is.dran3 = range to maintain for is.dreg3
  905.  */
  906. /* search forward for template, put address in AX, template size in DX,
  907.    and offset in CX, start search at offset + CX
  908.  */
  909. void padrf(ce)
  910. Pcells  ce;
  911. {   I32s    a, s = 0, tval;
  912.  
  913.     is.iip = is.dib = 1;
  914.     if (is.eins->exec)
  915.         return ;
  916.     a = ad(ce->c.ip + 1); /* a = address of start of template */
  917.     while(1) /* find size of template, s = size */
  918.     {
  919. #if PLOIDY == 1
  920.         if(soup[ad(a + s)].inst != Nop0 &&
  921.            soup[ad(a + s)].inst != Nop1)
  922. #else /* PLOIDY > 1 */
  923.         if(soup[ad(a + s)][ce->d.tr].inst != Nop0 &&
  924.            soup[ad(a + s)][ce->d.tr].inst != Nop1)
  925. #endif /* PLOIDY > 1 */
  926.             break;
  927.         s++;
  928.     }
  929.     if (s)
  930.     {   tval = flaw(ce); /* AX */
  931.         is.dreg  = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for address */
  932.         tval = 3 + flaw(ce); /* DX */
  933.         is.dreg2 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for templ size */
  934.         tval = 2 + flaw(ce); /* CX */
  935.         is.dreg3 = &(ce->c.re[mo(tval, NUMREG)]); /* dest reg for offset */
  936.     }
  937.     else
  938.         is.dreg = is.dreg2 = is.dreg3 = &BitBucket;
  939.     is.sval2 = s;  /* size of template */
  940.     is.dmod  = SoupSize;
  941.     is.dran2 = SoupSize;
  942.     is.dmod3 = SoupSize;
  943.     tval = 2 + flaw(ce); /* CX */
  944.     tval = ce->c.re[mo(tval, NUMREG)]; /* start at offset */
  945.     is.dval  = ad(a + s + tval + 1); /* start address for forward search */
  946.     is.dval2 = ad(a - s - tval - 1); /* start address for backward search */
  947.     is.sval3 = Search_limit - tval;
  948.     is.mode  = 1; /* forward search */
  949.     is.mode2 = 1;
  950.     is.iip = s + 1; is.dib = 1;
  951. }
  952.  
  953. /* void malchm(ce) is.sval2 = mal(ce,&is.sval3,is.sval,is.mode2);
  954.  *                 *(is.dreg) = is.sval3;
  955.  *                 chmode(ce,is.sval3,is.sval2,is.mode);
  956.  * is.dreg  = destination register where allocated address is stored
  957.  * is.sval  = requested size of block for mal()
  958.  * is.sval2 = flawed size of block (assigned in instruct.c)
  959.  * is.sval3 = suggested address, and allocated address
  960.  * is.mode  = memory protection mode (rwx), probably MemModeProt
  961.  * is.mode2 = memory allocation mode for mal()
  962.  */
  963. void pmal(ce)  /* allocate space for a new cell */
  964. Pcells  ce;
  965. {   I32s  tval;
  966.  
  967.     is.iip = is.dib = 1;
  968.     if (is.eins->exec)
  969.         return ;
  970.     tval = flaw(ce); /* AX destination register */
  971.     is.dreg  = &(ce->c.re[mo(tval, NUMREG)]);
  972.     tval = 2 + flaw(ce); /* CX requested size */
  973.     is.sval  = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  974.     tval = flaw(ce); /* AX suggested address */
  975.     is.sval3 = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  976.     if (is.sval3 < 0)
  977.         is.mode2 = 1; /* better fit */
  978.     else
  979.         is.mode2 = 6; /* suggester address (is.sval3) */
  980.     is.mode = MemModeProt; /* only write privelage works at the moment */
  981. }
  982.  
  983. /* void divide(ce) cell division
  984.  * is.mode  = divide mode (3 steps)
  985.  * is.sval  = offset of IP into daughter's genome
  986.  * is.sval2 = eject genome from soup = 0, !0 = leave in soup
  987.  */
  988. void pdivide(ce)  /* give life to new cell by puting in queue */
  989. Pcells  ce;
  990. {   I32s  tval;
  991.  
  992.     is.iip = is.dib = 1;
  993.     if (is.eins->exec)
  994.         return ;
  995.     is.mode  = 2;  /* full division */
  996.     tval = 2 + flaw(ce); /* CX offset into daughter */
  997.     is.sval  = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  998.     tval = 3 + flaw(ce); /* DX eject? */
  999.     is.sval2 = ce->c.re[mo(tval, NUMREG)] + flaw(ce);
  1000. }
  1001.  
  1002. #endif  /* INST == 4 */
  1003.