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 >
Wrap
Text File
|
1993-03-03
|
8KB
|
375 lines
/*
** File: jump.c
**
** (C)opyright 1987-1992 InfoTaskforce.
*/
#include "infocom.h"
Void
std_gosub ()
{
extern word pc_offset ;
extern word pc_page ;
extern word *stack_base ;
extern word *stack_var_ptr ;
extern word *stack ;
extern word param_stack[] ;
register word *param_ptr = ¶m_stack[0] ;
register word address ;
register word parameter ;
register int num_params ;
int vars ;
num_params = (int) *param_ptr++ ;
if (( address = *param_ptr++ ) == 0 )
store ( address ) ;
else
{
--num_params ;
*(--stack) = pc_page ;
*(--stack) = pc_offset ;
/*
** Push offset of old stack_var_ptr from stack_base onto stack
*/
*(--stack) = (word)(stack_var_ptr - stack_base) ;
pc_page = STD_PAGE ( address ) ;
pc_offset = STD_OFFSET ( address ) ;
fix_pc () ;
/*
** The value of the current stack pointer is the
** new value of stack_var_ptr.
*/
stack_var_ptr = stack ;
/*
** In interpreters prior to VERSION_5, the "stack_var_ptr"
** pointed to the first local variable on the z_code stack.
** In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
** points to the stack entry above the first local variable on
** the z_code stack.
**
** However, there is no reason for us not to adopt the VERSION_5
** method for all versions of the interpreter. This decision
** affects the following opcodes:
** gosub, std_rtn, load_var & put_var.
**
** Interpreters prior to VERSION_5 contained the following
** statement at this point:
**
** --stack_var_ptr ;
*/
/*
** Global variables 1 to 15 are Local variables, which
** reside on the stack (and so are local to each procedure).
**
** There are words reserved after the gosub opcode in the
** calling procedure to initialise all local variables.
** However, if there are any parameters on the parameter
** stack, these are used instead.
**
** The use of parameters also allows procedures to be
** passed variables by value.
*/
vars = (int) next_byte () ;
while ( vars-- )
{
parameter = next_word () ;
if ( (--num_params) >= 0 )
parameter = *param_ptr++ ;
*(--stack) = parameter ;
}
}
}
Void
plus_gosub ()
{
extern word pc_offset ;
extern word pc_page ;
extern word *stack_base ;
extern word *stack_var_ptr ;
extern word *stack ;
extern word param_stack[] ;
register word *param_ptr = ¶m_stack[0] ;
register word address ;
register word parameter ;
register int num_params ;
int vars ;
num_params = (int) *param_ptr++ ;
if (( address = *param_ptr++ ) == 0 )
store ( address ) ;
else
{
--num_params ;
*(--stack) = pc_page ;
*(--stack) = pc_offset ;
/*
** Push offset of old stack_var_ptr from stack_base onto stack
*/
*(--stack) = (word)(stack_var_ptr - stack_base) ;
pc_page = PLUS_PAGE ( address ) ;
pc_offset = PLUS_OFFSET ( address ) ;
fix_pc () ;
/*
** The value of the current stack pointer is the
** new value of stack_var_ptr.
*/
stack_var_ptr = stack ;
/*
** In interpreters prior to VERSION_5, the "stack_var_ptr"
** pointed to the first local variable on the z_code stack.
** In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
** points to the stack entry above the first local variable on
** the z_code stack.
**
** However, there is no reason for us not to adopt the VERSION_5
** method for all versions of the interpreter. This decision
** affects the following opcodes:
** gosub, std_rtn, load_var & put_var.
**
** Interpreters prior to VERSION_5 contained the following
** statement at this point:
**
** --stack_var_ptr ;
*/
/*
** Global variables 1 to 15 are Local variables, which
** reside on the stack (and so are local to each procedure).
**
** There are words reserved after the gosub opcode in the
** calling procedure to initialise all local variables.
** However, if there are any parameters on the parameter
** stack, these are used instead.
**
** The use of parameters also allows procedures to be
** passed variables by value.
*/
vars = (int) next_byte () ;
while ( vars-- )
{
parameter = next_word () ;
if ( (--num_params) >= 0 )
parameter = *param_ptr++ ;
*(--stack) = parameter ;
}
}
}
Void
adv_gosub ()
{
call ( FUNCTION ) ;
}
Void
std_rtn ( value )
word value ;
{
extern word pc_offset ;
extern word pc_page ;
extern word *stack_base ;
extern word *stack_var_ptr ;
extern word *stack ;
extern boolean stop ;
extern byte local_params ;
stack = stack_var_ptr ;
/*
** In interpreters prior to VERSION_5, the "stack_var_ptr"
** pointed to the first local variable on the z_code stack.
** In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
** points to the stack entry above the first local variable on
** the z_code stack.
**
** However, there is no reason for us not to adopt the VERSION_5
** method for all versions of the interpreter. This decision
** affects the following opcodes:
** gosub, std_rtn, load_var & put_var.
**
** Interpreters prior to VERSION_5 contained the following
** statement at this point:
**
** ++stack ;
*/
stack_var_ptr = stack_base + (signed_word)*stack++ ;
pc_offset = *stack++ ;
pc_page = *stack++ ;
/*
** Interpreters prior to VERSION_4 did not contain the following
** statements:
**
** if ( pc_page == EMPTY_PAGE )
** {
** stop = TRUE ;
** return ;
** }
**
** Only the "special_gosub ()" function pushes a value of EMPTY_PAGE
** onto the stack in place of "pc_page", and this function is never
** called by an interpreter prior to VERSION_4. Hence there is no
** reason for us not to include these statements in all versions.
*/
if ( pc_page == EMPTY_PAGE )
{
stop = TRUE ;
return ;
}
fix_pc () ;
store ( value ) ;
}
Void
adv_rtn ( value )
word value ;
{
extern word pc_offset ;
extern word pc_page ;
extern word *stack_base ;
extern word *stack_var_ptr ;
extern word *stack ;
extern boolean stop ;
extern byte local_params ;
register word type ;
stack = stack_var_ptr ;
/*
** In interpreters prior to VERSION_5, the "stack_var_ptr"
** pointed to the first local variable on the z_code stack.
** In VERSION_5 and subsequent interpreters, the "stack_var_ptr"
** points to the stack entry above the first local variable on
** the z_code stack.
**
** However, there is no reason for us not to adopt the VERSION_5
** method for all versions of the interpreter. This decision
** affects the following opcodes:
** gosub, std_rtn, load_var & put_var.
**
** Interpreters prior to VERSION_5 contained the following
** statement at this point:
**
** ++stack ;
*/
stack_var_ptr = stack_base + (signed_word)*stack++ ;
type = *stack++ ;
local_params = (byte)type ;
pc_offset = *stack++ ;
pc_page = *stack++ ;
/*
** Interpreters prior to VERSION_4 did not contain the following
** statements:
**
** if ( pc_page == EMPTY_PAGE )
** {
** stop = TRUE ;
** return ;
** }
**
** Only the "special_gosub ()" function pushes a value of EMPTY_PAGE
** onto the stack in place of "pc_page", and this function is never
** called by an interpreter prior to VERSION_4. Hence there is no
** reason for us not to include these statements in all versions.
*/
if ( pc_page == EMPTY_PAGE )
{
stop = TRUE ;
return ;
}
fix_pc () ;
if ( type & FUNCTION )
store ( value ) ;
}
Void
ret_true ()
{
extern proc_ptr jmp_op1[] ;
/*
** Call the current "rtn" opcode ...
*/
(*jmp_op1[0x0B])( TRUE ) ;
}
Void
ret_false ()
{
extern proc_ptr jmp_op1[] ;
/*
** Call the current "rtn" opcode ...
*/
(*jmp_op1[0x0B])( FALSE ) ;
}
Void
jump ( offset )
word offset ;
{
extern word pc_offset ;
pc_offset += offset - 2 ;
fix_pc () ;
}
Void
rts ()
{
extern proc_ptr jmp_op1[] ;
extern word *stack ;
/*
** Call the current "rtn" opcode ...
*/
(*jmp_op1[0x0B])( *stack++ ) ;
}
Void
std_pop_stack ()
{
extern word *stack ;
++stack ;
}
Void
adv_pop_stack ()
{
extern word *stack_base ;
extern word *stack_var_ptr ;
store ( (word)( stack_var_ptr - stack_base ) ) ;
}