/* ------------------------------------------------------------------------- */ /* "asm" : The Inform assembler */ /* */ /* Part of Inform release 5 */ /* ------------------------------------------------------------------------- */ #include "header.h" int in_routine_flag, no_stubbed; int ignoring_routine; int return_flag; static int stub_flags[32]; static int lower_strings_flag=0; static int ifdef_stack[MAX_IFDEF_DEPTH]; static int ifdef_sp=0; static int started_ignoring=0; #ifndef ALLOCATE_BIG_ARRAYS static long int pa_forwards[MAX_FORWARD_REFS]; #else static long int *pa_forwards; #endif extern void asm_allocate_arrays(void) { #ifdef ALLOCATE_BIG_ARRAYS pa_forwards = (long int *) my_calloc(sizeof(long int), MAX_FORWARD_REFS, "forward references"); #endif } extern void asm_free_arrays(void) { #ifdef ALLOCATE_BIG_ARRAYS my_free(&pa_forwards, "forward references"); #endif } /* ------------------------------------------------------------------------- */ /* Decode arguments as constants and variables */ /* (Gratuitous Space:1999 reference by Mr Dilip Sequeira of Edinburgh */ /* University) */ /* ------------------------------------------------------------------------- */ static int constant_was_string; extern int32 constant_value(char *b) { int32 i, j, k, action_flag=0, rv, base=10, moon, alpha, victor=0, eagle; constant_was_string=0; if (b[0]=='#') b++; if (b[0]=='\'') { if ((b[2]=='\'') && (b[3]==0)) return(translate_to_ascii(b[1])); i=strlen(b); if ((i>=4)&&(b[i-1]=='\'')) { b[i-1]=0; rv=dictionary_add(b+1,0x80,0,0); return(rv); } } if (b[0]=='#') { i=find_symbol(b+1); if ((i>=0)&&(stypes[i]==18)) return(svals[i]); if (strlen(b)>60) { error_named("Action name over 60 characters long:",b); return(0); } sprintf(b+strlen(b),"Sub"); action_flag=1; b++; goto actionfound; } if (b[0]=='\"') goto stringfound; if (*b=='$') { if (*++b=='$') { b++; base=2; } else base=16; } else if (*b=='-') { b++; victor=1; } else if (b[1]=='$') goto dollarform; else for (i=0; b[i]; i++) if (!isdigit(b[i])) goto nonumber; for(moon=0;*b;b++) { alpha=isalpha(*b)?(tolower(*b)-'a'+10):*b-'0'; if(alpha>=base || alpha<0) break; else moon=moon*base+alpha; } if (victor==0) return(moon); eagle=((int32) 0x10000L)-moon; return(eagle); dollarform: switch(b[0]) { case 'a': obsolete_warning("'#a$Action' is now superceded by '##Action'"); b+=2; action_flag=1; goto actionfound; case 'w': obsolete_warning("'#w$word' is now superceded by ''word''"); k=dictionary_find(b+2,2); rv=dictionary_offset+7+((version_number==3)?7:9)*(k-1); if ((k==0)&&(pass_number==2)) error_named("Dictionary word not found for constant",b); return(rv); case 'n': if (strlen(b)>3) obsolete_warning("'#n$word' is now superceded by ''word''"); rv=dictionary_add(b+2,0x80,0,0); return(rv); case 'r': i=find_symbol(b+2); if ((i<0)||(stypes[i]!=1)) { if (pass_number==2) error_named("No such routine as",b); return(256); } rv=svals[i]; goto constantfound; } error_named("There is no such # constant form as",b); return(0); nonumber: for (j=0,i=0; b[i]; i++) if (b[i]=='_') j=1; if (j==1) { if (strcmp(b,"adjectives_table")==0) return(adjectives_offset); if (strcmp(b,"preactions_table")==0) return(preactions_offset); if (strcmp(b,"actions_table")==0) return(actions_offset); if (strcmp(b,"version_number")==0) return(actual_version); if (strcmp(b,"largest_object")==0) return(256+max_no_objects-1); if (strcmp(b,"strings_offset")==0) return(strings_offset/scale_factor); if (strcmp(b,"code_offset")==0) return(code_offset/scale_factor); if (strcmp(b,"dict_par1")==0) return((version_number==3)?4:6); if (strcmp(b,"dict_par2")==0) return((version_number==3)?5:7); if (strcmp(b,"dict_par3")==0) return((version_number==3)?6:8); } actionfound: i=find_symbol(b); if (i<0) { if (pass_number==2) { if (action_flag==1) error_named("No such action routine as",b); else error_named("No such constant as",b); } return(0); } rv=svals[i]; constantfound: switch(stypes[i]) { case 1: rv=(rv+code_offset)/scale_factor; break; case 2: case 3: error_named("Not a constant:",b); return(0); case 4: case 10: error_named("Reserved word as constant:",b); return(0); } if (action_flag==0) return(rv); j=find_action(svals[i]); return(j); stringfound: dequote_text(b); constant_was_string=1; if (lower_strings_flag==1) { j=subtract_pointers(low_strings_p,low_strings); low_strings_p=translate_text(low_strings_p,b); i= subtract_pointers(low_strings_p,low_strings); if (i>MAX_LOW_STRINGS) memoryerror("MAX_LOW_STRINGS", MAX_LOW_STRINGS); return(0x21+(j/2)); } j= subtract_pointers(strings_p,strings); #ifdef USE_TEMPORARY_FILES { zip *c; c=translate_text(strings,b); i=subtract_pointers(c,strings); strings_p+=i; if (pass_number==2) for (c=strings; cMAX_STATIC_STRINGS) memoryerror("MAX_STATIC_STRINGS",MAX_STATIC_STRINGS); #endif while ((i%scale_factor)!=0) { i+=2; #ifdef USE_TEMPORARY_FILES strings_p+=2; if (pass_number==2) { fputc(0,Temp1_fp); fputc(0,Temp1_fp); } #else *(strings_p++)=0; *(strings_p++)=0; #endif } return((strings_offset+j)/scale_factor); } /* ------------------------------------------------------------------------- */ /* parse_argument returns: 1000+n Constant value n */ /* long_form_flag set if long form vital */ /* n Variable n */ /* ------------------------------------------------------------------------- */ static char known_unknowns[MAX_IDENTIFIER_LENGTH*16]; static int no_knowns; static long int pa_id; static int pa_ref; static int max_pa_ref; static int long_form_flag; static char one_letter_locals[16]; extern void args_begin_pass(void) { if (pass_number==2) max_pa_ref=pa_ref; pa_ref=0; pa_id=0; } static int32 parse_argument(char *b) { int i, j, flag=0; long_form_flag=0; i=b[0]; if (b[1]==0) { for (j=0;j<16;j++) if (i==one_letter_locals[j]) { used_local_variable[j]=1; return(j+1); } if (i=='0') return(1000); if (i=='1') return(1001); if (i=='2') return(1002); if (i=='3') return(1003); if (i=='4') return(1004); if (i=='5') return(1005); if (i=='6') return(1006); if (i=='7') return(1007); if (i=='8') return(1008); if (i=='9') return(1009); } if ((i=='#')||(i=='-')||(i=='$')||(i=='\"')||(i=='\'')) return(1000+constant_value(b)); for (i=0; b[i]!=0; i++) if (isdigit(b[i])==0) { flag=1; break; } if (flag==0) return(1000+constant_value(b)); if (in_routine_flag==1) { i=local_find_symbol(b); if (i>=0) return(1+svals[i]); } pa_id++; i=find_symbol(b); if (i>=0) { switch(stypes[i]) { case 1: return(1000+svals[i]); case 2: return(16+svals[i]); case 4: if (svals[i]==0) return(0); case 7: case 12: case 13: case 18: case 8: case 11: case 9: if (pass_number==2) { while ((pa_refpa_forwards[pa_ref])) pa_ref++; if ((pa_ref= MAX_ZCODE_SIZE) { memoryerror("MAX_ZCODE_SIZE",MAX_ZCODE_SIZE); } } static void write_operand(operand_t op) { int32 j; j=op.value; if (op.type!=0) byteout(j); else { byteout(j/256); byteout(j%256); } } static operand_t parse_operand(int32 number, opcode opco, char *b) { int32 j; int opt, type=opco.type1; operand_t oper; word(b,number+2); if (((type==CALL)||(type==NCALL))&&(number==0)) { if (pass_number==2) { j=find_symbol(b); if (j==-1) no_such_label(b); else if (stypes[j]!=1) error_named("Not a label:",b); else oper.value=(code_offset+svals[j])/scale_factor; oper.type=0; } else { oper.value=0x1000; oper.type=0; } return(oper); } if ((b[0]=='s')&&(b[1]=='p')&&(b[2]==0)) j=0; else j=parse_argument(b); if (j>=1256) { opt=0; j=j-1000; } else if (j>=1000) { opt=1; j=j-1000; } else opt=2; if ((opt==1) && (long_form_flag==1)) opt=0; if ((opco.type2==VAR)&&(opt==2)&&(number==0)) opt=1; oper.value=j; oper.type=opt; return(oper); } int a_from_one=0; int line_done_flag = 0; extern int assemble_opcode(char *b, int32 offset, int internal_number) { zip *opc, *opcname, *ac; int32 j, topbits, addr, cargs, ccode, ccode2, oldccode, oldccode2, multi, mask, flag, longf, branchword, offset_here; operand_t oper1, oper2; opcode opco; opco = opcs(internal_number); if (opco.type1==INVALID) { if (version_number==3) warning_named("Ignoring Advanced-game opcode",b); else warning_named("Ignoring Standard-game opcode",b); return(1); } return_flag=0; if ((opco.type1==RETURN) || (opco.type1==JUMP)) return_flag=1; if (opco.type1==INDIR) { byteout(0xE0); byteout(0xBF); byteout(0); byteout(0); goto Line_Done; } opcname=opco.name; switch(opco.no) { case MANY: case VARI: topbits=0xc0; break; case ZERO: topbits=0xb0; break; case ONE: topbits=0x80; break; case TWO: topbits=0x00; break; } opc=zcode_p; if (opco.no!=EXTD) { byteout(topbits+opco.code); } else { byteout(0xbe); byteout(opco.code); opco.no=VARI; } if (opco.type1==JUMP) { word(b,2); if (pass_number==1) addr=0; else { j=find_symbol(b); if (j<0) { no_such_label(b); return(1); } if ((stypes[j]!=6)&&(stypes[j]!=20)) { error_named("Not a label:",b); return(1); } addr=svals[j]-offset-1; if (addr<0) addr+=(int32) 0x10000L; } byteout(addr/256); byteout(addr%256); goto Line_Done; } if (opco.type2==TEXT) { zip *tmp; if (a_from_one==1) textword(b,1); else textword(b,2); tmp=zcode_p; zcode_p=translate_text(zcode_p,b); j=subtract_pointers(zcode_p,tmp); #ifdef USE_TEMPORARY_FILES utf_zcode_p+=j; #endif goto Line_Done; } switch(opco.no) { case VARI: ac=zcode_p; byteout(0); cargs= -1; ccode=0xff; while (word(b,(++cargs)+2),(b[0]!=0)) { if (b[0]=='?') { branchword=cargs+2; break; } switch(cargs) { case 0: multi=0x40; mask=0xc0; break; case 1: multi=0x10; mask=0x30; break; case 2: multi=0x04; mask=0x0c; break; case 3: multi=0x01; mask=0x03; break; case 4: multi=0; if ((opco.type1!=CALL)&&(opco.type1!=STORE)) error("Too many arguments"); break; default: error("Too many arguments"); break; } oper1=parse_operand(cargs, opco, b); write_operand(oper1); oldccode=ccode; ccode = (ccode & (~mask)) + oper1.type*multi; } if ((opco.type1==CALL)||(opco.type1==STORE)) { if (oper1.type!=2) { error("Can't store to that (no such variable)"); } *ac=oldccode; } else *ac=ccode; break; case MANY: ac=zcode_p; byteout(0); byteout(0); cargs= -1; ccode=0xff; ccode2=0xff; while (word(b,(++cargs)+2),(b[0]!=0)) { if (b[0]=='?') { branchword=cargs+2; break; } switch(cargs) { case 0: case 4: multi=0x40; mask=0xc0; break; case 1: case 5: multi=0x10; mask=0x30; break; case 2: case 6: multi=0x04; mask=0x0c; break; case 3: case 7: multi=0x01; mask=0x03; break; case 8: multi=0; if ((opco.type1!=CALL)&&(opco.type1!=STORE)) error("Too many arguments"); break; default: error("Too many arguments"); break; } oper1=parse_operand(cargs, opco, b); write_operand(oper1); oldccode=ccode; oldccode2=ccode2; if (cargs<4) ccode = (ccode & (~mask)) + oper1.type*multi; else ccode2 = (ccode2 & (~mask)) + oper1.type*multi; } if ((opco.type1==CALL)||(opco.type1==STORE)) { if (oper1.type!=2) { error("Can't store to that (no such variable)"); } *ac=oldccode; *(ac+1)=oldccode2; } else { *ac=ccode; *(ac+1)=ccode2; } break; case ONE: oper1=parse_operand(0,opco,b); *opc=(*opc) + oper1.type*0x10; write_operand(oper1); break; case TWO: oper1=parse_operand(0,opco,b); oper2=parse_operand(1,opco,b); if ((oper1.type==0)||(oper2.type==0)) { *opc=(*opc) + 0xc0; byteout(oper1.type*0x40 + oper2.type*0x10 + 0x0f); } else { if (oper1.type==2) *opc=(*opc) + 0x40; if (oper2.type==2) *opc=(*opc) + 0x20; } write_operand(oper1); write_operand(oper2); break; case ZERO: break; } if ((opco.no==ONE) || (opco.no==TWO)) { if ((opco.type1==STORE)||(opco.type1==CALL)) { if (opco.no==ONE) oper1=parse_operand(1,opco,b); if (opco.no==TWO) oper1=parse_operand(2,opco,b); if (oper1.type!=2) { error("Can't store to that (no such variable)"); } byteout(oper1.value); } } if ((opco.type1==BRANCH)||(opco.type2==OBJECT)) { int o=0; int32 pca; pca= subtract_pointers(zcode_p,opc) -1; switch(opco.no) { case ZERO: word(b,2); break; case ONE: if (opco.type2!=OBJECT) { word(b,3); break; } case TWO: word(b,4); break; case VARI: word(b,branchword); break; } if (b[0]=='?') { longf=1; o++; } else { int o2=0; if (b[0]=='~') o2=1; if (pass_number==1) { j=find_symbol(b+o2); if (j<0) longf=0; else longf=1; } else { j=find_symbol(b+o2); if (j<0) longf=0; else { if (offset-svals[j]>0) longf=1; else longf=0; if ((svals[j]-offset-pca)>30) { error("Branch too far forward: use '?'"); return(1); } } } } /* printf("Branch at %04x has longf=%d\n",offset,longf); */ if (pass_number==1) { byteout(0); if (longf==1) byteout(0); } else { if (b[o]=='~') { flag=0; o++; } else flag=1; j=find_symbol(b+o); if (j<0) { no_such_label(b+o); return(1); } switch(stypes[j]) { case 4: switch(svals[j]) { case 1: addr=1; longf=0; break; case 2: addr=0x20; longf=0; break; default: error("No such return condition for branch"); return(1); } break; case 1: error("Can't branch to a routine, only to a label"); return(1); case 6: case 20: if (longf==1) pca++; addr=svals[j]-offset-pca; if (addr<0) addr+=(int32) 0x10000L; break; default: error_named("Not a label:",b+o); return(1); } addr=addr&0x3fff; if (longf==1) { byteout(flag*0x80 + addr/256); byteout(addr%256); } else byteout(flag*0x80+ 0x40 + (addr&0x3f)); } } Line_Done: if (trace_mode==1) { printf("%04d %05lx %-14s ", current_source_line(), ((long int) offset)+((long int) code_offset),opcname); for (j=0;opc=i) condition=1; goto generic_if; } i=find_symbol(b); if (i>=0) condition=1; goto generic_if; case IFNDEF_CODE: word(b,2); if ((b[0]=='V')&&(b[1]=='N')&&(b[2]=='_')&&(strlen(b)==7)) { i=atoi(b+3); if (VNUMBER=2) { error("Two '#IFNOT's in the same '#IF'"); return; } ifdef_stack[ifdef_sp-1]+=2; if (ignoring_mode==1) { if (ifdef_sp==started_ignoring) ignoring_mode=0; } else { ignoring_mode=1; } return; case END_CODE: endofpass_flag=1; if (trace_mode==1) printf("\n"); if (ifdef_sp>0) { error("End of file reached inside '#IF...'"); } break; case OPENBLOCK_CODE: if (is_systemfile()==1) { strcpy(b,"Rep__"); word(b+5,2); i=find_symbol(b); if (i!=-1) { ignoring_routine=1; /* printf("Ignoring %s\n",b+5); */ break; } } word(b,2); ignoring_routine=0; debugged_routine=0; while ((offset%scale_factor)!=0) { byteout(0); offset++; } new_symbol(b,offset,1); if (trace_mode==1) printf("=MAX_ROUTINES) memoryerror("MAX_ROUTINES", MAX_ROUTINES); in_routine_flag=1; return_flag=0; word(b,3); if (strcmp(b,"*")==0) debugged_routine=1; while (word(b,(++no_locals)+3+debugged_routine),(b[0]!=0)) { if ( ((b[0]==',')&&(b[1]==0)) || ((b[0]==':')&&(b[1]==0))) { error("Expected local variable but found ',' or ':' \ (probably the ';' after the '[ ...' line was forgotten)"); break; } if ((b[0]=='s')&&(b[1]=='p')&&(b[2]==0)) { error("'sp' means the stack pointer, and can't be used \ as the name of a local variable"); break; } if (b[1]==0) one_letter_locals[no_locals]=b[0]; new_symbol(b,no_locals,3); if (debugging_file==1) write_debug_string(b); } if (debugging_file==1) { write_debug_byte(0); debug_pass=1; } byteout(no_locals); if (actual_version<5) { for (i=0; i\n",no_locals); if (no_locals>15) error("Routine has more than 15 local variables"); if ((no_routines==1)&&(pass_number==1)) { word(b,2); make_lower_case(b); if (strcmp(b,"main")!=0) { warning_named("Since it is defined before inclusion of the library, game-play \ will begin not at 'Main' but at the routine",b); } if (no_locals!=0) error("The earliest-defined routine is not allowed to have local variables"); } if (nowarnings_mode==0) for (i=0; i<16; i++) used_local_variable[i]=0; if ((withdebug_mode==1) || (debugged_routine==1)) { word(b,2); sprintf(sub_buffer,"print \"[%s\"",b); for (i=0; (i0) error_named( "Expected ',' or ';' after ']' but found", parse_buffer); else error_named( "Expected ';' after ']' but found", parse_buffer); } } if (trace_mode==1) printf("\n"); if (debugging_file==1) { debug_pass=2; write_debug_byte(14); write_debug_byte((no_routines-1)/256); write_debug_byte((no_routines-1)%256); write_re_linenum(); debug_pass=1; } if (return_flag==0) { if (resobj_flag==0) stack_line("@rtrue"); else stack_line("@rfalse"); } if (resobj_flag==1) resobj_flag=3; if (brace_sp>0) { error("Brace mismatch in previous routine"); brace_sp=0; } in_routine_flag=0; if ((nowarnings_mode==0)&&(pass_number==1)) { for (i=0; i0) { word(b,i); if (b[0]==0) break; textword(b,i); if (pass_number==1) { if (no_abbrevs==MAX_ABBREVS) { error("Too many abbreviations declared"); break; } if (almade_flag==1) { error("All abbreviations must be declared together"); break; } if (strlen(b)<2) { error_named("It's not worth abbreviating",b); break; } } strcpy((char *)abbreviations_at+no_abbrevs*MAX_ABBREV_LENGTH, b); word(b,i++); abbrev_mode=0; lower_strings_flag=1; abbrev_values[no_abbrevs]=constant_value(b); abbrev_quality[no_abbrevs++]=trans_length-2; abbrev_mode=1; lower_strings_flag=0; } break; case ATTRIBUTE_CODE: make_attribute(b); break; case CONSTANT_CODE: constant_made_flag=1; word(b,3); k=constant_value(b); word(b,2); IfPass2 { i=find_symbol(b); svals[i]=k; } else { if (constant_was_string==1) new_symbol(b,k,11); else new_symbol(b,k,8); } break; case LOWSTRING_CODE: word(b,3); lower_strings_flag=1; k=constant_value(b); lower_strings_flag=0; word(b,2); IfPass2 { i=find_symbol(b); } else { if (constant_was_string==1) new_symbol(b,k,11); else new_symbol(b,i,8); } break; case DEFAULT_CODE: word(b,3); IfPass2 { } else { i=constant_value(b); word(b,2); if (find_symbol(b)==-1) { if (constant_was_string==1) { error("Defaulted constants can't be strings"); return; } new_symbol(b,i,8); } } break; case STUB_CODE: i=0; IfPass2 { if (stub_flags[no_stubbed++]==1) i=1; } else { word(b,2); if (find_symbol(b)==-1) i=1; stub_flags[no_stubbed++]=i; } if (i==1) { word(b,3); i=constant_value(b); word(b,2); switch(i) { case 0: stack_sline("[ %s",b); stack_line("rfalse"); stack_line("]"); break; case 1: stack_sline("[ %s x1",b); stack_line("@store x1 0"); stack_line("rfalse"); stack_line("]"); break; case 2: stack_sline("[ %s x1 x2",b); stack_line("@store x1 0"); stack_line("@store x2 0"); stack_line("rfalse"); stack_line("]"); break; case 3: stack_sline("[ %s x1 x2 x3",b); stack_line("@store x1 0"); stack_line("@store x2 0"); stack_line("@store x3 0"); stack_line("rfalse"); stack_line("]"); break; default: error("Must specify 0 to 3 variables in 'stub' routine"); return; } } break; case DICTIONARY_CODE: obsolete_warning("use 'word' as a constant dictionary address"); textword(b,3); i=dictionary_add(b,4,0,0); word(b,2); IfPass2 { j=find_symbol(b); svals[j]=i; } else new_symbol(b,i,8); break; case FAKE_ACTION_CODE: make_fake_action(b); break; case GLOBAL_CODE: make_global(b,0); break; case ARRAY_CODE: make_global(b,1); break; case INCLUDE_CODE: word(b,3); if (b[0]!=0) error_named("Expected ';' after 'include ' but found",b); word(b,2); textword(b,2); if (b[0]!='>') load_sourcefile(b,0); else load_sourcefile(b+1,1); break; case NEARBY_CODE: make_object(b,1); break; case OBJECT_CODE: make_object(b,0); break; case CLASS_CODE: make_class(b); break; case PROPERTY_CODE: make_property(b); break; case RELEASE_CODE: word(b,2); release_number=constant_value(b); break; case SWITCHES_CODE: if (ignoreswitches_mode==0) { if ((pass_number==1)&&(constant_made_flag==1)) error("A 'switches' directive must \ must come before constant definitions"); word(b,2); switches(b,0); } break; case STATUSLINE_CODE: word(b,2); On_("score") { statusline_flag=0; break; } On_("time") { statusline_flag=1; break; } error_named("Expected 'score' or 'time' after 'statusline' but found", b); break; case SERIAL_CODE: textword(b,2); if (strlen(b)!=6) { error("The serial number must be a 6-digit date in double-quotes"); break; } for (i=0; i<6; i++) if (isdigit(b[i])==0) { error("The serial number must be a 6-digit date in double-quotes"); break; } strcpy(time_given,b); time_set=1; break; case SYSTEM_CODE: declare_systemfile(); break; case REPLACE_CODE: if (replace_sf(b)==1) break; sprintf(b, "Rep__"); word(b+5, 2); new_symbol(b, 0, 19); break; case VERB_CODE: make_verb(b); break; case EXTEND_CODE: extend_verb(b); break; case VERSION_CODE: if (override_version) break; word(b,2); actual_version=constant_value(b); if (actual_version==3) version_number=3; else version_number=5; if (version_number==3) scale_factor=2; else scale_factor=4; if ((actual_version==6)||(actual_version==8)) scale_factor=8; if (actual_version==7) extend_memory_map=1; if ((actual_version>=3)&&(actual_version<=8)) break; error("The version number must be in the range 3 to 8"); break; case TRACE_CODE: IfPass2 trace_mode=1; break; case NOTRACE_CODE: IfPass2 trace_mode=tracing_mode; break; case ETRACE_CODE: IfPass2 { word(b,2); if (b[0]==0) { etrace_mode=2; break; } if (strcmp(b,"full")==0) { etrace_mode=1; break; } error_named("Expected 'full' or nothing after 'etrace' but found", b); break; } case NOETRACE_CODE: IfPass2 etrace_mode=0; break; case BTRACE_CODE: trace_mode=1; break; case NOBTRACE_CODE: trace_mode=0; break; case LTRACE_CODE: IfPass2 ltrace_mode=1; break; case NOLTRACE_CODE: IfPass2 ltrace_mode=listing_mode; break; case ATRACE_CODE: IfPass2 ltrace_mode=2; break; case NOATRACE_CODE: IfPass2 ltrace_mode=listing_mode; break; case LISTSYMBOLS_CODE: IfPass2 list_symbols(); break; case LISTOBJECTS_CODE: IfPass2 list_object_tree(); break; case LISTVERBS_CODE: IfPass2 list_verb_table(); break; case LISTDICT_CODE: IfPass2 show_dictionary(); break; default: error("Internal error - unknown directive code"); } return; } extern void init_asm_vars(void) { lower_strings_flag = 0; ifdef_sp = 0; started_ignoring = 0; a_from_one = 0; line_done_flag = 0; lmoved_flag = 0; constant_made_flag = 0; #ifdef ALLOCATE_BIG_ARRAYS pa_forwards = NULL; #endif }