home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / GAMES / infocom_src.lha / jump.c < prev    next >
Text File  |  1993-03-03  |  8KB  |  375 lines

  1. /*
  2. **    File:    jump.c
  3. **
  4. **    (C)opyright 1987-1992 InfoTaskforce.
  5. */
  6.  
  7. #include    "infocom.h"
  8.  
  9. Void
  10. std_gosub ()
  11. {
  12.     extern word        pc_offset ;
  13.     extern word        pc_page ;
  14.     extern word        *stack_base ;
  15.     extern word        *stack_var_ptr ;
  16.     extern word        *stack ;
  17.     extern word        param_stack[] ;
  18.  
  19.     register word    *param_ptr = ¶m_stack[0] ;
  20.     register word    address ;
  21.     register word    parameter ;
  22.     register int    num_params ;
  23.     int                vars ;
  24.  
  25.     num_params = (int) *param_ptr++ ;
  26.     if (( address = *param_ptr++ ) == 0 )
  27.         store ( address ) ;
  28.     else
  29.     {
  30.         --num_params ;
  31.         *(--stack) = pc_page ;
  32.         *(--stack) = pc_offset ;
  33.  
  34.         /*
  35.         **    Push offset of old stack_var_ptr from stack_base onto stack
  36.         */
  37.  
  38.         *(--stack) = (word)(stack_var_ptr - stack_base) ;
  39.  
  40.         pc_page = STD_PAGE ( address ) ;
  41.         pc_offset = STD_OFFSET ( address ) ;
  42.         fix_pc () ;
  43.  
  44.         /*
  45.         **    The value of the current stack pointer is the
  46.         **    new value of stack_var_ptr.
  47.         */
  48.  
  49.         stack_var_ptr = stack ;
  50.  
  51.         /*
  52.         **    In interpreters prior to VERSION_5, the "stack_var_ptr"
  53.         **    pointed to the first local variable on the z_code stack.
  54.         **    In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
  55.         **    points to the stack entry above the first local variable on
  56.         **    the z_code stack.
  57.         **
  58.         **    However, there is no reason for us not to adopt the VERSION_5
  59.         **    method for all versions of the interpreter. This decision
  60.         **    affects the following opcodes:
  61.         **                                gosub, std_rtn, load_var & put_var.
  62.         **
  63.         **    Interpreters prior to VERSION_5 contained the following
  64.         **    statement at this point:
  65.         **
  66.         **                                --stack_var_ptr ;
  67.         */
  68.  
  69.         /*
  70.         **    Global variables 1 to 15 are Local variables, which
  71.         **    reside on the stack (and so are local to each procedure).
  72.         **
  73.         **    There are words reserved after the gosub opcode in the
  74.         **    calling procedure to initialise all local variables.
  75.         **    However, if there are any parameters on the parameter
  76.         **    stack, these are used instead.
  77.         **
  78.         **    The use of parameters also allows procedures to be
  79.         **    passed variables by value.
  80.         */
  81.  
  82.         vars = (int) next_byte () ;
  83.         while ( vars-- )
  84.         {
  85.             parameter = next_word () ;
  86.             if ( (--num_params) >= 0 )
  87.                 parameter = *param_ptr++ ;
  88.             *(--stack) = parameter ;
  89.         }
  90.     }
  91. }
  92.  
  93. Void
  94. plus_gosub ()
  95. {
  96.     extern word        pc_offset ;
  97.     extern word        pc_page ;
  98.     extern word        *stack_base ;
  99.     extern word        *stack_var_ptr ;
  100.     extern word        *stack ;
  101.     extern word        param_stack[] ;
  102.  
  103.     register word    *param_ptr = ¶m_stack[0] ;
  104.     register word    address ;
  105.     register word    parameter ;
  106.     register int    num_params ;
  107.     int                vars ;
  108.  
  109.     num_params = (int) *param_ptr++ ;
  110.     if (( address = *param_ptr++ ) == 0 )
  111.         store ( address ) ;
  112.     else
  113.     {
  114.         --num_params ;
  115.         *(--stack) = pc_page ;
  116.         *(--stack) = pc_offset ;
  117.  
  118.         /*
  119.         **    Push offset of old stack_var_ptr from stack_base onto stack
  120.         */
  121.  
  122.         *(--stack) = (word)(stack_var_ptr - stack_base) ;
  123.  
  124.         pc_page = PLUS_PAGE ( address ) ;
  125.         pc_offset = PLUS_OFFSET ( address ) ;
  126.         fix_pc () ;
  127.  
  128.         /*
  129.         **    The value of the current stack pointer is the
  130.         **    new value of stack_var_ptr.
  131.         */
  132.  
  133.         stack_var_ptr = stack ;
  134.  
  135.         /*
  136.         **    In interpreters prior to VERSION_5, the "stack_var_ptr"
  137.         **    pointed to the first local variable on the z_code stack.
  138.         **    In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
  139.         **    points to the stack entry above the first local variable on
  140.         **    the z_code stack.
  141.         **
  142.         **    However, there is no reason for us not to adopt the VERSION_5
  143.         **    method for all versions of the interpreter. This decision
  144.         **    affects the following opcodes:
  145.         **                                gosub, std_rtn, load_var & put_var.
  146.         **
  147.         **    Interpreters prior to VERSION_5 contained the following
  148.         **    statement at this point:
  149.         **
  150.         **                                --stack_var_ptr ;
  151.         */
  152.  
  153.         /*
  154.         **    Global variables 1 to 15 are Local variables, which
  155.         **    reside on the stack (and so are local to each procedure).
  156.         **
  157.         **    There are words reserved after the gosub opcode in the
  158.         **    calling procedure to initialise all local variables.
  159.         **    However, if there are any parameters on the parameter
  160.         **    stack, these are used instead.
  161.         **
  162.         **    The use of parameters also allows procedures to be
  163.         **    passed variables by value.
  164.         */
  165.  
  166.         vars = (int) next_byte () ;
  167.         while ( vars-- )
  168.         {
  169.             parameter = next_word () ;
  170.             if ( (--num_params) >= 0 )
  171.                 parameter = *param_ptr++ ;
  172.             *(--stack) = parameter ;
  173.         }
  174.     }
  175. }
  176.  
  177. Void
  178. adv_gosub ()
  179. {
  180.     call ( FUNCTION ) ;
  181. }
  182.  
  183. Void
  184. std_rtn ( value )
  185. word    value ;
  186. {
  187.     extern word        pc_offset ;
  188.     extern word        pc_page ;
  189.     extern word        *stack_base ;
  190.     extern word        *stack_var_ptr ;
  191.     extern word        *stack ;
  192.     extern boolean    stop ;
  193.     extern byte        local_params ;
  194.  
  195.     stack = stack_var_ptr ;
  196.  
  197.     /*
  198.     **    In interpreters prior to VERSION_5, the "stack_var_ptr"
  199.     **    pointed to the first local variable on the z_code stack.
  200.     **    In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
  201.     **    points to the stack entry above the first local variable on
  202.     **    the z_code stack.
  203.     **
  204.     **    However, there is no reason for us not to adopt the VERSION_5
  205.     **    method for all versions of the interpreter. This decision
  206.     **    affects the following opcodes:
  207.     **                                gosub, std_rtn, load_var & put_var.
  208.     **
  209.     **    Interpreters prior to VERSION_5 contained the following
  210.     **    statement at this point:
  211.     **
  212.     **                                ++stack ;
  213.     */
  214.  
  215.     stack_var_ptr = stack_base + (signed_word)*stack++ ;
  216.     pc_offset = *stack++ ;
  217.     pc_page = *stack++ ;
  218.  
  219.     /*
  220.     **    Interpreters prior to VERSION_4 did not contain the following
  221.     **    statements:
  222.     **
  223.     **                if ( pc_page == EMPTY_PAGE )
  224.     **                {
  225.     **                    stop = TRUE ;
  226.     **                    return ;
  227.     **                }
  228.     **
  229.     **    Only the "special_gosub ()" function pushes a value of EMPTY_PAGE
  230.     **    onto the stack in place of "pc_page", and this function is never
  231.     **    called by an interpreter prior to VERSION_4. Hence there is no
  232.     **    reason for us not to include these statements in all versions.
  233.     */
  234.  
  235.     if ( pc_page == EMPTY_PAGE )
  236.     {
  237.         stop = TRUE ;
  238.         return ;
  239.     }
  240.  
  241.     fix_pc () ;
  242.     store ( value ) ;
  243. }
  244.  
  245. Void
  246. adv_rtn ( value )
  247. word    value ;
  248. {
  249.     extern word        pc_offset ;
  250.     extern word        pc_page ;
  251.     extern word        *stack_base ;
  252.     extern word        *stack_var_ptr ;
  253.     extern word        *stack ;
  254.     extern boolean    stop ;
  255.     extern byte        local_params ;
  256.  
  257.     register word    type ;
  258.  
  259.     stack = stack_var_ptr ;
  260.  
  261.     /*
  262.     **    In interpreters prior to VERSION_5, the "stack_var_ptr"
  263.     **    pointed to the first local variable on the z_code stack.
  264.     **    In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
  265.     **    points to the stack entry above the first local variable on
  266.     **    the z_code stack.
  267.     **
  268.     **    However, there is no reason for us not to adopt the VERSION_5
  269.     **    method for all versions of the interpreter. This decision
  270.     **    affects the following opcodes:
  271.     **                                gosub, std_rtn, load_var & put_var.
  272.     **
  273.     **    Interpreters prior to VERSION_5 contained the following
  274.     **    statement at this point:
  275.     **
  276.     **                                ++stack ;
  277.     */
  278.  
  279.     stack_var_ptr = stack_base + (signed_word)*stack++ ;
  280.     type = *stack++ ;
  281.     local_params = (byte)type ;
  282.     pc_offset = *stack++ ;
  283.     pc_page = *stack++ ;
  284.  
  285.     /*
  286.     **    Interpreters prior to VERSION_4 did not contain the following
  287.     **    statements:
  288.     **
  289.     **                if ( pc_page == EMPTY_PAGE )
  290.     **                {
  291.     **                    stop = TRUE ;
  292.     **                    return ;
  293.     **                }
  294.     **
  295.     **    Only the "special_gosub ()" function pushes a value of EMPTY_PAGE
  296.     **    onto the stack in place of "pc_page", and this function is never
  297.     **    called by an interpreter prior to VERSION_4. Hence there is no
  298.     **    reason for us not to include these statements in all versions.
  299.     */
  300.  
  301.     if ( pc_page == EMPTY_PAGE )
  302.     {
  303.         stop = TRUE ;
  304.         return ;
  305.     }
  306.  
  307.     fix_pc () ;
  308.     if ( type & FUNCTION )
  309.         store ( value ) ;
  310. }
  311.  
  312. Void
  313. ret_true ()
  314. {
  315.     extern proc_ptr    jmp_op1[] ;
  316.  
  317.     /*
  318.     **    Call the current "rtn" opcode ...
  319.     */
  320.  
  321.     (*jmp_op1[0x0B])( TRUE ) ;
  322. }
  323.  
  324. Void
  325. ret_false ()
  326. {
  327.     extern proc_ptr    jmp_op1[] ;
  328.  
  329.     /*
  330.     **    Call the current "rtn" opcode ...
  331.     */
  332.  
  333.     (*jmp_op1[0x0B])( FALSE ) ;
  334. }
  335.  
  336. Void
  337. jump ( offset )
  338. word    offset ;
  339. {
  340.     extern word        pc_offset ;
  341.  
  342.     pc_offset += offset - 2 ;
  343.     fix_pc () ;
  344. }
  345.  
  346. Void
  347. rts ()
  348. {
  349.     extern proc_ptr    jmp_op1[] ;
  350.     extern word        *stack ;
  351.  
  352.     /*
  353.     **    Call the current "rtn" opcode ...
  354.     */
  355.  
  356.     (*jmp_op1[0x0B])( *stack++ ) ;
  357. }
  358.  
  359. Void
  360. std_pop_stack ()
  361. {
  362.     extern word        *stack ;
  363.  
  364.     ++stack ;
  365. }
  366.  
  367. Void
  368. adv_pop_stack ()
  369. {
  370.     extern word        *stack_base ;
  371.     extern word        *stack_var_ptr ;
  372.  
  373.     store ( (word)( stack_var_ptr - stack_base ) ) ;
  374. }
  375.