home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / fish / 831-840 / ff833 / zip / zip-1.00.lha / interpre.c < prev    next >
C/C++ Source or Header  |  1992-10-09  |  7KB  |  179 lines

  1. /*
  2.  * interpre.c
  3.  *
  4.  * Main interpreter loop
  5.  *
  6.  * Mark Howell 28-Jul-1992 V1.0
  7.  *
  8.  */
  9.  
  10. #include "ztypes.h"
  11.  
  12. /*
  13.  * interpret
  14.  *
  15.  * Interpret Z code
  16.  *
  17.  */
  18.  
  19. #ifdef __STDC__
  20. void interpret (void)
  21. #else
  22. void interpret ()
  23. #endif
  24. {
  25.     zbyte_t opcode;
  26.     zword_t specifier, operand[8];
  27.     int maxoperands, count, i;
  28.  
  29.     /* Loop until HALT instruction executed */
  30.  
  31.     for ( ; ; ) {
  32.  
  33.         /* Load opcode and set operand count */
  34.  
  35.         opcode = read_code_byte ();
  36.         count = 0;
  37.  
  38.         /* Multiple operand instructions */
  39.  
  40.         if (opcode < 0x80 || opcode > 0xc0) {
  41.  
  42.             /* Two operand class, load both operands */
  43.  
  44.             if (opcode < 0x80) {
  45.                 operand[count++] = load_operand ((opcode & 0x40) ? 2 : 1);
  46.                 operand[count++] = load_operand ((opcode & 0x20) ? 2 : 1);
  47.                 opcode &= 0x1f;
  48.             } else {
  49.  
  50.                 /* Variable operand class, load operand specifier */
  51.  
  52.                 if (opcode == 0xec) { /* Extended CALL instruction */
  53.                     specifier = read_code_word ();
  54.                     maxoperands = 8;
  55.                 } else {
  56.                     specifier = read_code_byte ();
  57.                     maxoperands = 4;
  58.                 }
  59.  
  60.                 /* Load operands */
  61.  
  62.                 for (i = (maxoperands - 1) * 2; i >= 0; i -= 2)
  63.                     if (((specifier >> i) & 0x03) != 3)
  64.                         operand[count++] = load_operand ((specifier >> i) & 0x03);
  65.                     else
  66.                         i = 0;
  67.                 opcode &= 0x3f;
  68.             }
  69.             switch ((char) opcode) {
  70.  
  71.                 /* Two or multiple operand instructions */
  72.  
  73.                 case 0x01: compare_je (count, operand); break;
  74.                 case 0x02: compare_jl (operand[0], operand[1]); break;
  75.                 case 0x03: compare_jg (operand[0], operand[1]); break;
  76.                 case 0x04: decrement_check (operand[0], operand[1]); break;
  77.                 case 0x05: increment_check (operand[0], operand[1]); break;
  78.                 case 0x06: compare_parent_object (operand[0], operand[1]); break;
  79.                 case 0x07: test (operand[0], operand[1]); break;
  80.                 case 0x08: or (operand[0], operand[1]); break;
  81.                 case 0x09: and (operand[0], operand[1]); break;
  82.                 case 0x0a: test_attr (operand[0], operand[1]); break;
  83.                 case 0x0b: set_attr (operand[0], operand[1]); break;
  84.                 case 0x0c: clear_attr (operand[0], operand[1]); break;
  85.                 case 0x0d: store_variable (operand[0], operand[1]); break;
  86.                 case 0x0e: insert_object (operand[0], operand[1]); break;
  87.                 case 0x0f: load_word (operand[0], operand[1]); break;
  88.                 case 0x10: load_byte (operand[0], operand[1]); break;
  89.                 case 0x11: load_property (operand[0], operand[1]); break;
  90.                 case 0x12: load_property_address (operand[0], operand[1]); break;
  91.                 case 0x13: load_next_property (operand[0], operand[1]); break;
  92.                 case 0x14: add (operand[0], operand[1]); break;
  93.                 case 0x15: subtract (operand[0], operand[1]); break;
  94.                 case 0x16: multiply (operand[0], operand[1]); break;
  95.                 case 0x17: divide (operand[0], operand[1]); break;
  96.                 case 0x18: remainder (operand[0], operand[1]); break;
  97.                 case 0x19: call (count, operand); break;
  98.  
  99.                 /* Multiple operand instructions */
  100.  
  101.                 case 0x20: call (count, operand); break;
  102.                 case 0x21: store_word (operand[0], operand[1], operand[2]); break;
  103.                 case 0x22: store_byte (operand[0], operand[1], operand[2]); break;
  104.                 case 0x23: store_property (operand[0], operand[1], operand[2]); break;
  105.                 case 0x24: read_line (count, operand); break;
  106.                 case 0x25: print_character (operand[0]); break;
  107.                 case 0x26: print_number (operand[0]); break;
  108.                 case 0x27: random (operand[0]); break;
  109.                 case 0x28: push_var (operand[0]); break;
  110.                 case 0x29: pop_var (operand[0]); break;
  111.                 case 0x2a: set_status_size (operand[0]); break;
  112.                 case 0x2b: select_window (operand[0]); break;
  113.                 case 0x2c: call (count, operand); break;
  114.                 case 0x2d: erase_window (operand[0]); break;
  115.                 case 0x2e: erase_line (operand[0]); break;
  116.                 case 0x2f: set_cursor_position (operand[0], operand[1]); break;
  117.                 case 0x30: break;
  118.                 case 0x31: set_video_attribute (operand[0]); break;
  119.                 case 0x32: set_format_mode (operand[0]); break;
  120.                 case 0x33: set_print_modes (operand[0], operand[1]); break;
  121.                 case 0x34: break;
  122.                 case 0x35: sound (count, operand); break;
  123.                 case 0x36: read_character (count, operand); break;
  124.                 case 0x37: scan_word (operand[0], operand[1], operand[2]); break;
  125.  
  126.                 default: fatal ("Illegal operation");
  127.             }
  128.         } else {
  129.  
  130.             /* Single operand class, load operand and execute instruction */
  131.  
  132.             if (opcode < 0xb0) {
  133.                 operand[0] = load_operand ((opcode >> 4) & 0x03);
  134.                 switch ((char) opcode & 0x0f) {
  135.                     case 0x00: compare_zero (operand[0]); break;
  136.                     case 0x01: load_next_object (operand[0]); break;
  137.                     case 0x02: load_child_object (operand[0]); break;
  138.                     case 0x03: load_parent_object (operand[0]); break;
  139.                     case 0x04: load_property_length (operand[0]); break;
  140.                     case 0x05: increment (operand[0]); break;
  141.                     case 0x06: decrement (operand[0]); break;
  142.                     case 0x07: print_offset (operand[0]); break;
  143.                     case 0x08: call (1, operand); break;
  144.                     case 0x09: remove_object (operand[0]); break;
  145.                     case 0x0a: print_object (operand[0]); break;
  146.                     case 0x0b: ret (operand[0]); break;
  147.                     case 0x0c: jump (operand[0]); break;
  148.                     case 0x0d: print_address (operand[0]); break;
  149.                     case 0x0e: load (operand[0]); break;
  150.                     case 0x0f: not (operand[0]); break;
  151.                 }
  152.             } else {
  153.  
  154.                 /* Zero operand class, execute instruction */
  155.  
  156.                 switch ((char) opcode & 0x0f) {
  157.                     case 0x00: ret (TRUE); break;
  158.                     case 0x01: ret (FALSE); break;
  159.                     case 0x02: print_literal (); break;
  160.                     case 0x03: println_return (); break;
  161.                     case 0x04: break;
  162.                     case 0x05: save (); break;
  163.                     case 0x06: restore (); break;
  164.                     case 0x07: restart (); break;
  165.                     case 0x08: pop_ret (); break;
  166.                     case 0x09: pop (); break;
  167.                     case 0x0a: return;
  168.                     case 0x0b: new_line (); break;
  169.                     case 0x0c: display_status_line (); break;
  170.                     case 0x0d: verify (); break;
  171.  
  172.                     default: fatal ("Illegal operation");
  173.                 }
  174.             }
  175.         }
  176.     }
  177.  
  178. }/* interpret */
  179.