|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 61440 (0xf000) Types: TextFile Names: »t290xasm«
└─⟦667bb35d6⟧ Bits:30007480 RC8000 Dump tape fra HCØ. └─⟦4334b4c0b⟧ └─⟦this⟧ »t290xasm«
begin message version 790505; algol copy.tcgproclib; integer elements_pr_line, length_of_code, half_words_pr_instr,no_of_bits_in_code, HEAP_length, search_table_length, no_of_errors, name_table_length,index, code_kind,start_addrs; integer field refference_first_free,refference_last_free; integer comma_class,illegal_class,star_class,left_par_class, right_par_class,period_class,plus_class,minus_class, colon_class,semi_colon_class,equal_class,delim_class, apost_class, <* apostrof used as address identf. in micro code *> quote_class, <* same as above *> double_quote_class, slash_class, <* indicate special print for label def *> text_class,long_text_class,number_class, illegal_number_class, unknown_name_class,stop_line_class,eof_class, class,type, class1,type1, class2,type2, nil, <* end off refference chain *> label_type, <* a generel type *> mask_type, <* type value used by type definitions value 101 *> not_used; <* a general value used for indicating dummy, nil and not used conditioning initialized to max negative integer + 10 *> long array param_name, <* used for gettting abitrary parameters *> find_name, <* to find and list lines with specific contents *> current_out_name(1:2); integer current_out_mode_and_kind; integer array tail(1:20); <* used to change the entry of the object code *> boolean test, test_label_ref, test_label_bit, find, <* list mode is only to special lines *> found, <* if a special line is found ( detected in get next element) *> list, <* a listing of relewant lines *> line_num, <* if listning is wanted then is line numbers wanted default is yes *> dec_code, <* if listning then is code numbers in decimal wanted , default is yes *> octal_code, <* if listning thenis code numbers wnted in octal ( basis 8) wanted, defaulst is yes, the parameter can be set to octal.only, which will set line_num and dec_code to false *> entry_list_wanted, <* list all entryes marked with slash *> return_from_skip, <* the return to the main loop is from some skip logic *> list_all, <* a listing of all lines , also lines which is skipped *> help_wanted; <* used with parameter check *> boolean procedure lookup_name(name_table,short_name,index); <**********************************************************> value short_name; long array name_table; long short_name,index; begin integer table_length,hash_index,prim_index; table_length := nametable(0,0); hash_index := (short_name extract 12) + ( short_name shift (-12) extract 12) + (short_name shift (-24) extract 12) + (short_name shift (-36) extract 12); prim_index:=hash_index mod table_length +1; if false then write(out,<:<10>***look::>,<<_dddd>,tablelength,<:index: :>, hashindex,<:prim: :>,primindex,<:name: :>,string shortname); for hash_index := hash_index mod table_length +1 while nametable(hash_index,0) > - 1 and name_table(hash_index,1) <> short_name and hash_index+1 <> prim_index do; index:=hash_index; lookup_name := if name_table(hash_index,1) = short_name then true else false; if false then write(out,<: index::>,<<_dddd>,hash_index, name_table(hashindex,0),<: :>,string nametable(hash_index,1)); end look_up_name; long present_code, <* the object code handled now *> name,number,name1, number1,name2,number2; <* variables for lookup in tables , and reading from source *> procedure present(func_value,func_mask); <**************************************> value func_value,func_mask; long func_value,func_mask; begin present_code := mask_in(present_code,func_value,func_mask); end present; long procedure mask_in(code,func_value,func_mask); <*************************************************> value code,func_value,func_mask; long func_value,func_mask, code; begin integer init_shift,func_bit,mask_bit; long instr,long_one,long_all; init_shift := 0; long_one := 1; long_all := -1; for mask_bit := func_mask extract 1 while func_mask <> 0 do begin if mask_bit = 1 then begin if func_value extract 1 = 1 then code := logor(code,long_one shift init_shift) else code := logand(code,exor(long_all,long_one shift init_shift)); func_value := func_value shift (-1); end; func_mask := func_mask shift (-1); init_shift := init_shift +1; end; mask_in := code; end mask_in; long procedure octal(number); value number; long number; begin integer index,tal; tal:=0; for index:=1,index*10 while number <> 0 do begin tal := tal + (index*(number extract 3 )); number := number shift (-3); end; octal := tal; end octal; integer array read_table(0:383); <* init of read classes *> illegal_class := 10; star_class := 11; comma_class := 12; <* ille_gal_class_2 := 13; *> left_par_class := 14; right_par_class :=15; period_class := 16; minus_class := 17; colon_class := 18; semi_colon_class := 19; equal_class := 20; plus_class := 21; quote_class := apost_class := 23; slash_class := 24; double_quote_class := 25; delim_class := 7; <* space and / is resent delim*> text_class := 6; long_text_class := 5; number_class := 2; illegal_number_class := 1; unknown_name_class := 9 ; <* short or long name *> stop_line_class := 8; eof_class := 22; <* this is not in read_table but is calc. in get_next_element *> not_used := -8388598 ; iso_table(read_table); <* 0 - 127 is modified std_table *> <* 128- 255 is comment shift table 256 - 383 is comment text table *> for index := 128 step 1 until 255 do read_table(index) := 1 shift 12 + 256; semi_colon_class := 19; read_table(128+59):=semi_colon_class shift 12 + 59; for index:= 256 step 1 until 383 do read_table(index):= 6 shift 12 + (index-256); read_table(256+0) := 0 shift 12 + 0; read_table(256+10) := 1 shift 12 + 0; read_table(256+12) := 1 shift 12 + 0; read_table(256+13) := 0 shift 12 + 0; read_table(256+25) := 1 shift 12 + 0; read_table(256+127) := 0 shift 12 + 127; for index := 33 step 1 until 39 do read_table(index):= illegal_class shift 12 + index; read_table(39) := apost_class shift 12 + 39; read_table('"'):=double_quote_class shift 12 + '"'; read_table(40):= left_par_class shift 12 + 40; read_table(41) := right_par_class shift 12 + 41; read_table(42) := star_class shift 12 + 42; read_table(44):= comma_class shift 12 + 44; read_table(46):= period_class shift 12 + 46; read_table(47):=slash_class shift 12 + 47; read_table(43):= plus_class shift 12 + 43; read_table(45):= minus_class shift 12 + 45; read_table(58):=colon_class shift 12 + 58; read_table(59) := 1 shift 12 + 128; <* semicolon shift table *> for index := 60 step 1 until 64 do read_table(index) := 10 shift 12 + index; read_table(61) := equal_class shift 12 + 61; for index:= 94 step 1 until 96,126 do read_table(index):= 10 shift 12 + index; intable(read_table); test := false; no_of_bits_in_code := 40; length_of_code := 1024; search_table_length := 253; name_table_length := 511; HEAP_length := 5000; nil := -8388608; <* min integer *> label_type := 97; mask_type := 101; <* search for the parameter help.yes *> get_bool_string(<:help:>,help_wanted); if help_wanted then help_string(<:micasmhelp:>); begin integer instr_index, last_instr_index, line_no,line_no1,line_pointer,line_pointer_1, line_pointer_2,line_pointer_3,char_value,char_value_1,char_value_2, char_class,char_class_1,element_no, no_of_elements, reg_op_type,alu_function_type,jump_addrs_type, jump_sekvens_type,load_counter_type,special_type, condition_type, condition_type_min,condition_type_max, special_min,special_max; boolean code_generated,eof,eol,alu_function_performed, jump_addrs_performed,jump_sekvens_performed, shift_condition_performed,addrs_performed, print_code,object_file_known, list_error_lines, message_list, list_bit_lines, line_listed, help_wanted, error_in_this_line; integer array format(0:no_of_bits_in_code); long array read_value(1:80); integer array read_kind(1:80); integer array search_table(0:search_table_length - 1); long array name_table(0:name_table_length,0:4); integer array HEAP(1:HEAP_length); long array field name_record; long field name_name, name_mask; integer field name_value, name_type, name_chain; integer name_record_length; long array field error_record; long field error_record_text; integer field error_record_line_no; integer field error_record_element_pos; integer field error_record_instr_index; integer field error_record_chain; integer error_record_length; long array field error_record_chain_head; long array field l_d_record, l_d_record_chain_head; long field l_d_name; integer spec_class,map_spec,vector_spec; <* and nil *> integer field l_d_spec, l_d_spec_class; integer field l_d_index; integer field l_d_line_no; integer field l_d_chain; integer l_d_record_length; long array field l_r_record; integer field l_r_chain; long field l_r_name; integer field l_r_index; integer field l_r_line_no; integer field l_r_element_no; integer l_r_record_length,l_r_record_chain_head; long array op_code(0:length_of_code-1); long array object_file_known_name(1:2); <* error text variables *> long plus_label_dec,declaration,operand_type,minus_delim,missing_operand, label_dec,illegal_type,plus_name_dec,name_unknown,directive, unknown,name_length,delimiter,undec_label,multiple_function, plus_addrs_def,minus_addrs_def,operand, special_def_type,illegal_source,illegal_dest, illegal_dest_and_source,save_file_name,load_file_name, termination; algol copy.1 <* schould be taken from m290xdec *>; <* fixed bit long values *> long array bits(0:48); long prom_code, <* the value not to destroy the used prom *> nop_code; <* the code which will perform nothing abd continue with the next micro instr.*> procedure init_HEAP; <******************************> begin integer index; refference_first_free := 2*2; for index := 2 step 2 until HEAP_length do begin HEAP(index-1) := index*2-4; <* points to previus element *> HEAP(index) := index*2+4; <* point to next element *> refference_last_free := index*2; end; end init_HEAP; integer procedure allocate(no_of_halfwords); <******************************************> value no_of_halfwords; integer no_of_halfwords; begin allocate := refference_first_free - 4; if ( no_of_halfwords mod 4) <> 0 then no_of_halfwords := no_of_half_words + (4 -(no_of_halfwords mod 4)); refference_first_free := refference_first_free + no_of_half_words; if refference_first_free > refference_last_free then fatal_error(<:REFFERENCE TABLE LENGTH EXEEDED:>); end allocate; procedure fatal_error(error_text); <********************************> string error_text; begin print_error_table; write(out,"nl",1,"*",5,"sp",1,error_text,"nl",1, "sp",7,<:RUN ABORT:>); fp_proc(7,0,0,0); end fatal_error; procedure error(error_text,line_no,element_pos); <**********************************************> value error_text,line_no,element_pos; long error_text; integer line_no,element_pos; begin error_in_this_line := true; no_of_errors := no_of_errors + 1; error_record := allocate(error_record_length); HEAP.error_record.error_record_chain := error_record_chain_head; error_record_chain_head := error_record; HEAP.error_record.error_record_text := error_text; HEAP.error_record.error_record_line_no := line_no; HEAP.error_record.error_record_element_pos := element_pos; HEAP.error_record.error_record_instr_index := instr_index; end error; boolean procedure new_lookup_name(name,name_record_index,name_type); value name; long name; integer name_record_index,name_type; begin long array field look_name_record; boolean found; found := false; name_record_index := calculate_hash_key(name); look_name_record := search_table(name_record_index); while look_name_record <> nil and -,found do begin if name = HEAP.look_name_record.name_name then found := true else look_name_record := HEAP.look_name_record.name_name; end; name_record_index := look_name_record; new_lookup_name := found; end new_lookup_name; integer procedure new_insert_name(name,reff_index,type,record_length); value name,type,record_length; long name; integer reff_index,type,record_length; begin integer array field insert_name_record; integer hash_key; hash_key := calculate_hash_key(name); insert_name_record := allocate(record_length); new_insert_name := insert_name_record; reff_index := insert_name_record; HEAP.insert_name_record.name_name := name; HEAP.insert_name_record.name_type := type; HEAP.insert_name_record.name_chain := search_table(hash_key); search_table(hash_key) := insert_name_record; end new_insert_name; integer procedure calculate_hash_key(name); value name; long name; begin calculate_hash_key := (( name extract 12) + ( name shift (-12) extract 12) + ( name shift (-24) extract 12) + ( name shift (-36) extract 12) + ( name shift (-40) extract 8) + ( name shift (-32) extract 8) + ( name shift (-24) extract 12) ) mod search_table_length; end calculate_hash_key; integer procedure insert_name_table(index,name,type,reff); value index,name,type,reff; long index,name; integer type,reff; begin name_table(index,1) := name; name_table(index,0) := type; name_table(index,4) := reff; end insert_name_table; integer procedure addrs_ref(name,instr_index,line_no,element_no); value name,instr_index,line_no,element_no; long name; integer instr_index,line_no,element_no; begin l_r_record := allocate(l_r_record_length); HEAP.l_r_record.l_r_chain := l_r_record_chain_head; l_r_record_chain_head := l_r_record; HEAP.l_r_record.l_r_name := name; HEAP.l_r_record.l_r_index := instr_index; HEAP.l_r_record.l_r_line_no := line_no; HEAP.l_r_record.l_r_element_no := element_no; addrs_ref := l_r_record; end addrs_ref; integer procedure new_insert_label_def(name,index,instr_index,line_no,spec,spec_class); value name,index,instr_index,spec,line_no,spec_class; long name,index; integer instr_index,spec,line_no,spec_class; begin l_d_record := allocate(l_d_record_length); insert_name_table(index,name,label_type,l_d_record); HEAP.l_d_record.l_d_chain := l_d_record_chain_head; l_d_record_chain_head := index; HEAP.l_d_record.l_d_index := instr_index; HEAP.l_d_record.l_d_line_no := line_no; HEAP.l_d_record.l_d_spec := spec; HEAP.l_d_record.l_d_spec_class := spec_class; new_insert_label_def := index; end new_insert_label_def; procedure resolve_labels; begin integer op_code_index; long name_table_index; long array wr_name(1:2); <* used for writing of a name *> wr_name(2):=0; l_r_record := l_r_record_chain_head; while l_r_record >-1 do begin if -, lookup_name(name_table,HEAP.l_r_record.l_r_name, name_table_index) then begin instr_index := HEAP.l_r_record.l_r_index; error(undec_label,HEAP.l_r_record.l_r_line_no, HEAP.l_r_record.l_r_element_no); end else begin l_d_record := name_table(name_table_index,4); op_code_index := HEAP.l_r_record.l_r_index; op_code(opcode_index) := mask_in(op_code(op_code_index), extend HEAP.l_d_record.l_d_index, addrs_mask); if test_label_bit or test_label_ref then begin wr_name(1) := HEAP.l_d_record.l_d_name; write(out,"nl",1,"sp",5,<<zddd>, octal(extend HEAP.l_r_record.l_r_index), <: label reff to: :>, octal(extend HEAP.l_d_record.l_d_index), <: name: :>,wr_name); end; if test_label_bit then begin write(out,"nl",1,"sp",11); print_formated(op_code(op_code_index)); end; end; l_r_record := HEAP.l_r_record.l_r_chain; end scan loop; end resolve_labels; procedure label_list(only_spec_wanted); value only_spec_wanted; boolean only_spec_wanted; begin integer no_of_spec,max_spec,max_index; long array wr_name(1:2),hex_number(1:2); integer index; no_of_spec := 0; wr_name(2) := 0; for index := 1 step 1 until name_table_length do begin if name_table(index,0) = label_type then begin l_d_record := name_table(index,4); if HEAP.l_d_record.l_d_spec <> nil or -, only_spec_wanted then begin wr_name(1) := name_table(index,1); write(out,"sp",15 - write(out,"nl",1,wr_name), "cr",1,"sp",7,<: reff. to address:>, <<_zddd>,HEAP.l_d_record.l_d_index, octal(extend HEAP.l_d_record.l_d_index), if HEAP.l_d_record.l_d_spec = nil then <::> else if HEAP.l_d_record.l_d_spec < 0 then <:_line_no_:> else <:_spec.____:>, if HEAP.l_d_record.l_d_spec <> nil then <<__dddd> else <<b>, if HEAP.l_d_record.l_d_spec = nil then 0 else abs HEAP.l_d_record.l_d_spec); no_of_spec := no_of_spec + 1; end; end; end for loop; if only_spec_wanted then begin for spec_class := nil,map_spec ,vector_spec do begin if no_of_spec > 0 then write(out,"nl",4, if spec_class = map_spec then <: MAP ENTRIES :> else if spec_class = vector_spec then <: VECTOR ENTIES :> else <::>,"nl",1, <:_name_____________spec.____instr.___octal____:>); repeat begin max_spec := nil; for index := 1 step 1 until name_table_length do begin if name_table(index,0) = label_type then begin l_d_record := name_table(index,4); if HEAP.l_d_record.l_d_spec > max_spec and HEAP.l_d_record.l_d_spec <> nil and HEAP.l_d_record.l_d_spec_class = spec_class then begin max_spec := HEAP.l_d_record.l_d_spec; max_index := index; end; end; end loop name_table; <* write spec *> if max_spec <> nil then begin wr_name(1) := name_table(max_index,1); l_d_record := name_table(max_index,4); write(out,"sp",15-write(out,"nl",1,wr_name), <<____dddd>,HEAP.l_d_record.l_d_spec, HEAP.l_d_record.l_d_index, octal(extend HEAP.l_d_record.l_d_index), HEAP.l_d_record.l_d_index shift (-8), HEAP.l_d_record.l_d_index extract 8); <* delete label entry in name table *> name_table(max_index,0) := nil; no_of_spec := no_of_spec-1; end; end; until max_spec = nil; end spec_class_loo; end only_spec_loop; end label_list; boolean procedure print_error_table; begin long array field previus,this,min_line; integer min_line_no; if error_record_chain_head = nil then print_error_table := true else begin print_error_table := false; while error_record_chain_head <> nil do begin min_line_no := 8388606; this := error_record_chain_head; previus := nil; while this <> nil do begin if HEAP.this.error_record_line_no <= min_line_no then begin min_line_no := HEAP.this.error_record_line_no; min_line:= previus; end; previus := this; this := HEAP.this.error_record_chain; end; <* remove record from list *> if min_line = nil then begin this := error_record_chain_head; error_record_chain_head := HEAP.this.error_record_chain; end else begin previus := min_line; this := HEAP.previus.error_record_chain; HEAP.previus.error_record_chain := HEAP.this.error_record_chain; end; write(out,"nl",1,<<_dddd>, HEAP.this.error_record_line_no, HEAP.this.error_record_instr_index, octal(extend HEAP.this.error_record_instr_index), HEAP.this.error_record_element_pos, "sp",2,string HEAP.this.error_record_text); end; end; end print_error_table; procedure print_formated(opcode); <********************************> value opcode; long opcode; begin integer from,to,number,index; from := 0; for index :=-47 step 1 until 0 do begin outchar(out,if opcode shift index extract 1 = 1 then 49 else 46); if format(from) extract 12 = 47 + index then begin outchar(out,32); from:=from+1; end; end for loop; <* for improving readability write an extra newline *> outchar(out,10); end print_format; algol copy.2 <* source should be m290xproc *>; integer procedure get_all_reg_operands(op_1,kind_1,op_2,kind_2,op_3,kind_3); <**********************************************************> integer op_1,kind_1,op_2,kind_2,op_3,kind_3; begin integer no_of_op; no_of_op := 0; op_1 := op_2 := op_3 := kind_1 := kind_2 := kind_3 := not_used; class := look_ahead_class; if class = left_par_class then begin next; get_a_reg_operand(op_1,kind_1); no_of_op := 1; if look_ahead_class = comma_class then begin next; get_a_reg_operand(op_2,kind_2); no_of_op := 2; if look_ahead_class = comma_class then begin next; get_a_reg_operand(op_3,kind_3); no_of_op := 3; end; end; next; if class <> right_par_class then error(termination,line_no,element_no); end else error(missing_operand,line_no,element_no); get_all_reg_operands := no_of_op; end get_all_reg_operands; <* procedure check_unknown_operands(op_kind_1,op_kind_2,op_kind_3,op_kind_4); value op_kind_1,op_kind_2,op_kind_3,op_kind_4; integer op_kind_1,op_kind_2,op_kind_3,op_kind_4; begin integer no_of_op; no_of_op := if op_kind_1 = not_used then 0 else if op_kind_2 = not_used then 1 else if op_kind_3 = not_used then 2 else if op_kind_4 = not_used then 3 else 4; if op_kind_1 = unknown_name_class then error(operand,line_no,element_no - 1 -(2*(no_of_op-1))); if op_kind_2 = unknown_name_class then error(operand,line_no,element_no -1-(2*(no_of_op-2))); if op_kind_3 = unknown_name_class then error(operand,line_no,element_no - 1 - 2*(no_of_op-3)); if op_kind_4 = unknown_name_class then error(operand,line_no,element_no -1); end check_unkown_operands; *> procedure get_a_reg_operand(op_value,kind); <*****************************************> integer op_value,kind; begin long lookup_index; next; if class = number_class then begin kind := number_class; op_value := number end else if class = apost_class then begin next; kind := 0; op_value := 0; if class = unknown_name_class or (class = text_class and type = label_type) then begin addrs_ref(name,instr_index,line_no,element_no); kind := number_class; end else error(operand_type,line_no,element_no); end else if class = text_class then begin if name_table(number,0) <> reg_op_type then begin kind := 0; error(operand_type,line_no,element_no) end else begin op_value := name_table(number,2); kind := text_class; end; end else begin kind := unknown_name_class; error(operand,line_no,element_no); end; end of get_a_reg_operand; procedure get_2_reg_operands(op_value_1,op_value_2); integer op_value_1,op_value_2; begin integer kind_1,kind_2; get_a_reg_operand(op_value_1,kind_1); next; if class <> comma_class then error(delimiter,line_no,element_no); get_a_reg_operand(op_value_2,kind_2); end of get_2_reg_operands; integer procedure look_ahead_class; begin integer to; long name,number; look_ahead_class := get_element(name,number,line_pointer,to); end look_ahead_class; procedure skip_until_delim_class; begin for class:=read_kind(line_pointer) while class <> delim_class and class <> eof_class and class <> stop_line_class do line_pointer:=line_pointer + 1; end skip_until_delim_class; integer procedure get_long_name(long_name); long array long_name; begin integer class,to; long name,number; class := get_element(name,number,line_pointer,to); if class = unknown_name_class or class = text_class then begin get_long_name := 1; long_name(1) := name; long_name(2) := 0; end else if class = long_text_class then begin long_name(1) := read_value(line_pointer); long_name(2) := read_value(line_pointer + 2); get_long_name := if read_kind(line_pointer + 3 ) = text_class then -2 else 2; end else get_long_name := 0; end get_long_name; <* the following procedures uses getnext element to get next element into class,name,number,type class1,name1,number1,type2 class2,name2,number2,type2 *> integer procedure next; begin next := class := get_next_element(name,number); type := if class = text_class then name_table(number,0) else class; end next; integer procedure next1; begin next1 := class1 := get_next_element(name1,number1); type1 := if class1 = text_class then name_table(number,0) else class1; end next1; integer procedure next2; begin next2:=class2:=get_next_element(name2,number2); type2 := if class2 = text_class then name_table(number,0) else class2; end next2; integer procedure skip_next; begin long dummyname,dummynumber; skip_next:=get_next_element(dummyname,dummynumber); end skip_next; integer procedure look; begin look := class := look_ahead_class; end look; integer procedure look1; begin look1 := class1 := look_ahead_class; end look1; integer procedure look2; begin look2:= class2 := look_ahead_class; end look2; integer procedure get_next_element(name,number); long name,number; begin integer to,testclass;; get_next_element := testclass := get_element(name,number,line_pointer,to); element_no:=element_no+1; line_pointer := if line_pointer = no_of_elements then line_pointer else to; end get_next_element; integer procedure get_element(name,number,from,to); value from; integer from,to; long name,number; begin integer class; for class:=read_kind(from) while class = delim_class do from := from + 1; if class = text_class then begin if read_kind(from+1) <> text_class or ( read_kind(from+1) = text_class and read_value(from+1) = 0) then begin <* short text *> name := read_value(from); if name = find_name(1) then found := true; get_element := if look_up_name(name_table,name,number) then text_class else unknown_name_class; end else get_element := unknown_name_class;; <* skip to 1. not text element *> for from := from+1 while read_kind(from) = text_class do; to := from; end else if class = plus_class then begin if get_integer(number,from+1,to) then get_element := 2 else get_element := 1; end else if class = minus_class then begin if get_integer(number,from+1,to) then get_element:=2 else get_element:=1; number:= number*(-1); end else if class = 2 then begin if get_integer(number,from,to) then get_element:=2 else get_element := 1; end else if class = stop_line_class then begin number := read_value(from); if number extract 24 = 25 <* eof value *> then get_element := eof_class else get_element :=class; to :=from+1; end else begin number:=read_value(from); to := from+1; get_element := class; end; end get_element; boolean procedure get_integer(number,from,to); value from; integer from,to; long number; begin long base; if read_kind(from)<> 2 then get_integer:=false else begin if read_kind(from+1) = period_class then begin base:=read_value(from); from:=from+2; if read_kind(from) <> 2 then begin get_integer := false; to := from-1; end else begin number:=read_value(from); get_integer:=base_convert(base,number); to := from + 1; end; end else begin number:=read_value(from); get_integer := true; to := from + 1; end; end; end get_integer; boolean procedure base_convert(base,number); long base,number; begin integer shift_index; long number1,number2; number2:=0; shift_index :=0; base_convert := true; if base = 8 then begin for number1 := number mod 10 while number <> 0 do begin number := number // 10; if number1>7 or number1 < 0 then base_convert := false; number2:=number2 + number1 shift shift_index; shift_index := shift_index+3; end; number := number2; end else base_convert:=false; end base_convert; boolean procedure read_and_set_bits(operand); <******************************************> long array operand; begin boolean error; error := false; repeat begin next; if class = left_par_class then begin if next1 <> number_class then error := true else if next<> colon_class then error := true else if next2 <> number_class then error := true else if next <> right_par_class then error := true; if number_1 <= number_2 and number_1 >= 0 and number_2 <= no_of_bits_in_code and -, error then error := -, set_bits(operand,number1 extract 24, number2 extract 24) else error := true; next; end else if class = number_class then begin if number >= 0 and number <= no_of_bits_in_code then error := -, set_bits(operand,number extract 24, number extract 24) else error := true; next; end; end; until class <> comma_class or error; read_and_set_bits := -, error; end read_and_set_bits; boolean procedure set_bits(operand,bit_low,bit_high); <****************************************************> value bit_low,bit_high; integer bit_low,bit_high; long array operand; begin integer index_low, index_high, bit_high_in_word, bit_low_in_word, word_index; if bit_high < bit_low then set_bits := false else begin index_low := case ( bit_low//48) + 1 of (1,2,3,4,5,6,7,8); index_high := case (bit_high//48) + 1 of (1,2,3,4,5,6,7,8); bit_low_in_word := bit_low mod 48; bit_high_in_word := bit_high mod 48; if index_low = index_high then begin operand(index_low) := log_or(operand(index_low), extend(-1) shift ((-48)+(bit_high_in_word+1-bit_low_in_word)) shift (47 - bit_high_in_word)); end else begin operand(index_low) := log_or(operand(index_low), extend (-1) shift ( - bit_low_in_word)); operand(index_high) := log_or(operand(index_high), extend(-1) shift (47 - bit_high_in_word)); for word_index := index_low+1 step 1 until index_low - 1 do operand(word_index) := -1; end; set_bits := true; end; end set_bits; long procedure init_mask(operand,from,to); <******************************************> value from,to,operand; long operand; integer from,to; init_mask:=mask_in(operand,extend (-1), extend (-1) shift ((-48)+(to+1-from)) shift (47-to)); <* ************************************************* directive procedures section ************************************************* *> procedure directive_skip_until; begin boolean until_condition_met; long skip_end_name; next1; if class1 = text_class or class1 = unknown_name_class then begin skip_end_name := name1; repeat if list_all then list_line; read_next_source_line; if class = star_class then begin next1; if name1 = long <:until:> then begin next1; if class1 = colon_class then next1; if name1 = skip_end_name then until_condition_met := true; end; end control of first token; until until_condition_met; end else error(directive,line_no,element_no); return_from_skip := true; end directive_skip_until; procedure directive_onlyin_logic(mode); <********************************> value mode; boolean mode; <* if mode is true then skip only in is performed else skip not in is performed *> begin <* check the param list to se the param mode.<text> , where <text> schall be equal the next element *> long array param_name,until_name,only_name(1:2); integer param_call_result; boolean until_condition_met; param_call_result := get_text_string(<:version:>,param_name); class1 := get_long_name(only_name); if param_call_result <> 0 or (param_call_result = 0 and (( mode and (param_name(1) <> only_name(1) or param_name(2) <> only_name(2))) or ( -, mode and param_name(1) = only_name(1) and param_name(2) = only_name(2) ))) then begin <* skip until a 'until' directive is met with with the version text as parameter. *> until_condition_met := false; repeat if list_all then list_line; read_next_source_line; if class = eof_class then until_condition_met := true; if class = star_class then begin next1; if name1 = long <:until:> then begin next1; if class1 = colon_class then class1 := get_long_name(until_name); if class1 > 0 and only_name(1) =until_name(1) and only_name(2) = until_name(2) then until_condition_met := true; end; end control of first token 'colon' ; until until_condition_met; end skip not this version ; return_from_skip := true; end directive_only_in; procedure include_source_file; <****************************> begin long array file_name(1:2); integer stack_result; class1 := get_long_name(file_name); if class1 > 0 then begin stack_result := stack_and_connect_in(file_name); if list then list_line; if stack_result <> 0 then write(out,"*",4,<: copy connect error: :>,file_name,"nl",1) else write(out,<: micasm source : :>,file_name,"nl",1); end else error(directive,line_no,element_no); end include_source_file; procedure list_line; <*******************> begin if -, line_listed then begin line_listed := true; if line_num then write(out,<<dddd>,line_no); if code_generated then begin if dec_code then write(out,<<_zddd>,instr_index); if octal_code then write(out,<<_zddd>,octal(extend instr_index)); outchar(out,'sp'); end else begin if dec_code then write(out,"sp",5); if octal_code then write(out,"sp",5); outchar(out,'sp'); end; line_pointer := 0; for line_pointer := line_pointer+1 while line_pointer <= no_of_elements do begin if read_kind(line_pointer) = 6 then begin write(out,string read_value(increase(line_pointer))); line_pointer := line_pointer - 1; end else if read_kind(line_pointer) = 2 then write(out,<<d>,read_value(line_pointer)) else outchar(out,read_value(line_pointer) extract 8); end; end; end list_line; procedure read_next_source_line; <******************************> begin <* reset boolean control *> error_in_this_line := false ; code_generated := false; alu_function_performed := false; jump_sekvens_performed := false; addrs_performed := false; shift_condition_performed := false; jump_addrs_performed := false; line_listed := false; line_pointer := 1; element_no := 0; no_of_elements := read_all(in,read_value,read_kind,1); line_no := line_no + 1; next; end read_next_source_line; plus_label_dec := long <:plus label dec.:>; declaration := long <:declaration:>; operand_type := long <:operand type:>; minus_delim := long <:minus delim.:>; missing_operand := long <:missing operand.:>; label_dec:= long <:label dec.:>; illegal_type := long <:illegal type:>; plus_name_dec := long <:plus name dec.:>; name_unknown := long <:name unknown:>; directive := long <:directive:>; unknown := long <:unknown:>; name_length := long <:name length exeedes 6 char.:>; delimiter := long <:delimiter:>; undec_label := long <:undec. label or addrs. :>; multiple_function := long <:multiple function.:>; plus_addrs_def := long <:plus addrs def.:>; minus_addrs_def := long <:minus addrs. def.:>; illegal_source := long <:illegal source:>; illegal_dest := long <:illegal destination:>; illegal_dest_and_source := long <:illegal destination and or source :>; save_file_name := long <:illegal save file name:>; load_file_name := long <:illegal load file name:>; termination := long <:termination:>; operand := long <:unknown operand:>; algol copy.3 <* schould be m290xinit *>; init_long_array(name_table,-1); init_HEAP; <* init of fields *> no_of_errors := 0; error_record_chain_head := nil; error_record_text := 4; error_record_line_no := 8; error_record_element_pos := 10; error_record_chain := 6; error_record_instr_index := 12; error_record_length := 12; l_d_record_chain_head := nil; l_d_name := 4; l_d_chain := 8; l_d_spec := 2; l_d_index := 4; l_d_line_no := 6; l_d_spec_class := 10; l_d_record_length := 10; map_spec := 1; vector_spec := 2; l_r_chain := 2; l_r_name := 6; l_r_index := 8; l_r_line_no := 10; l_r_element_no := 12; l_r_record_length := 12; l_r_record_chain_head :=nil; <* no label refference blocks *> name_name := 8; name_chain := 2; name_type := 4; name_record_length := 8; name_table(0,0) := name_table_length; <* asm. begin *> prom_code := -1; for index := 0 step 1 until length_of_code-1 do opcode(index):=prom_code; begin integer array tail(1:20); zone dummy(128,1,stderror); real r; integer i,j,lookup_result; long array mic_asm_prog_name,program_name(1:2); i:=system(2,j,program_name); open(dummy,4,programname,0); lookup_result:=monitor(42,dummy,0,tail); write(out,"ff",1,<:Micro asm.:__:>,true,12,program_name, <: version date.:>, <<zddddd.dddd>,systime(6,tail(6),r) + r/1000000,"nl",1); close(dummy,true); if connect_file_in(mic_asm_prog_name) = 4 then write(out,"nl",1,"*",5,<:Source file connect error::>, mic_asm_prog_name); get_connected_name(in,micasm_prog_name); lookup_result:=monitor(42,in,0,tail); write(out,"nl",1,<:Source file:_:>,true,12, mic_asm_prog_name,<: version date.:>, <<zddddd.dddd>,systime(6,tail(6),r)+r/1000000,"nl",1); <* control if any and get name of object file *> if get_left_side(object_file_known_name) = 0 then object_file_known := true else object_file_known := false; if object_file_known then begin open(dummy,0,object_file_known_name,0); lookup_result := monitor(42) lookup tail:(dummy,0,tail); if lookup_result <> 0 then object_file_known := false; write(out,"nl",1,if object_file_known then <:Object file:_:> else <:*** Unknown object file::>, true,12,object_file_known_name); if object_file_known then write(out,<: version date.:>, <<zddddd.dddd>,systime(6,systime(7,0,0.0),r)+r/1000000); outchar(out,'nl'); close(dummy,true); end; end block with control of files; <* get and control of other parameters, unknown parameters is ignored. *> get_bool_string(<:help:>,help_wanted); if help_wanted then help_string(<:micasmhelp:>); if get_bool_string(<:message:>,message_list) <> 0 then message_list := true; list_all := false; if get_bool_string(<:list:>,list) <> 0 then begin long array param_name(1:2); if get_text_string(<:list:>,param_name) = 0 then begin if param_name(1) = long <:all:> then list:=list_all := true; end; end; if get_bool_string(<:linenum:>,line_num) <> 0 then line_num:= true; if get_bool_string(<:deccode:>,dec_code) <> 0 then dec_code := true; if get_bool_string(<:octal:>,octal_code) <> 0 then begin octal_code := true; if get_text_string(<:octal:>,param_name) = 0 then begin if param_name(1) = long <:only:> then dec_code:= line_num := false; end; end; if get_text_string(<:find:>,find_name) = 0 then find := true; if get_bool_string(<:errors:>,list_error_lines) <> 0 and get_bool_string(<:errorlines:>,list_error_lines) <> 0 and get_bool_string(<:els:>,list_error_lines) <> 0 then list_error_lines := true; get_bool_string(<:code:>,print_code); get_bool_string(<:labelxref:>,test_label_ref); get_bool_string(<:labelbit:>,test_label_bit); get_bool_string(<:entry:>,entry_list_wanted); get_bool_string(<:bitlines:>,list_bit_lines); return_from_skip := false; <* initializing of counting variables and reading of first code line *> instr_index:=0; present_code := nop_code; error_in_this_line := false; line_no := 0; read_next_source_line; while class <> eof_class do begin if class = stop_line_class then begin <* end line , or comment . Commant wil be be created by get_next_element *> if (list or (error_in_this_line and list_error_lines ) or ( find and found )) and ( -, return_from_skip or list_all) then list_line; return_from_skip := false; found := false; if print_code and code_generated then begin if -, list and -, list_bit_lines and -, (error_in_this_line and list_error_lines) then write(out,<<-zddd>,instr_index, octal(extend instr_index),"sp",1) else if -, list and list_bit_lines and -, (error_in_this_line and list_error_lines) then begin list_line; write(out,<: :>); end else write(out,<: :>); print_formated(present_code); outchar(out,10); end; if code_generated then begin op_code(instr_index):=present_code; instr_index:=instr_index+1; present_code := nop_code; end; <* read next line of source text *> read_next_source_line; end class 2 new line else if class = text_class or class = unknown_name_class then begin class_2 := look_ahead_class; if class_2 = colon_class or class_2 = slash_class then begin spec_class := nil; if element_no = 1 and class = unknown_name_class then begin if class2 = slash_class then begin skip_next; look2; if class2 = quote_class or class2 = double_quote_class then begin spec_class := if class2 = quoteclass then map_spec else vectorspec; skip_next; <* skip quote or double quote *> look2; end; if class2 = number_class or class2 = colon_class then begin if class_2 = number_class then begin next1; class2 := look_ahead_class; end else number_1 := line_no; if class2 = colon_class then begin new_insert_label_def(name,number,instr_index,line_no, number1 extract 24,spec_class); end else error(directive,line_no,element_no); end else error(directive,line_no,element_no); end else begin new_insert_label_def(name,number,instr_index,line_no, nil,spec_class) end; next; end else error(label_dec,line_no,element_no); next; end else begin if class = unknown_name_class then begin error(name_unknown,line_no,element_no); skip_until_delim_class; next; end else if name_table(number,0) = alu_function_type then alu_function else if name_table(number,0) = jump_addrs_type then jump_addrs else if name_table(number,0) = jump_sekvens_type then jump_sekvens else if name_table(number,0) = load_counter_type then load_counter else if name_table(number,0) = special_type then special else begin error(illegal_type,line_no,element_no); next end; end; end type equal identifier else if class = star_class then begin <* After star is assm. directive, 1 direktive pr. line, after the direktive the rest of the line is skipped, the direktive schould be the first element in the line *> if code_generated then error(directive,line_no,element_no) else begin next1; next2; if (class1 <> 9 and class1 <> 6 ) or class2 <> colon_class <*colon*> then error(long <:test dir 1 :>,line_no,if class2 <> colon_class then element_no else element_no -1) else begin if name1 = long <:name:> then begin next1; if class1 <> 9 then error(if class1 <> 6 then long <:test dir 2.:> else plus_name_dec,line_no,element_no) else begin name_table(number1,1) := name1; index:=0; for class2 := next2 while class2 = comma_class and index < 5 do begin next2; if class2 = number_class then name_table(number1,index) := number2 else if class2 = 6 <* defined name *> then name_table(number1,index) := number_2 else begin error(long <:test dir. 3:>,line_no,element_no); index:=100; end; if index = 0 then index :=2 else if index<100 then index:=index+1; end; end; end else if name1 = long <:const:> then begin next1; if class1 <> 9 then error(if class1 <> 6 then directive else plus_name_dec,line_no,element_no) else begin next2; if class2 = comma_class then begin next2; if class2 = number_class then begin new_insert_label_def(name1,number1, number2 extract 12,line_no,nil,nil); end else error(directive,line_no,element_no); end else error(directive,line_no,element_no); end; end else if name1 = long <:mask:> then begin long array operand(1:1); <* only one word used *> boolean mask_succes; long mask_name,mask_number; operand(1) := 0; if next1 <> unknown_name_class then error(long <: directive 2:>,line_no,element_no) else if next2 <> comma_class then error(long <:directive 3:>,line_no,element_no) else begin mask_name := name1; mask_number := number1; mask_succes := read_and_set_bits(operand); if -, mask_succes then error(long <:directive 4:>,line_no,element_no) else begin name_table(mask_number,0) := mask_type; name_table(mask_number,1) := mask_name; name_table(mask_number,2) := operand(1); end; end; end else if name1 = long <:origo:> then begin if next1 <> number_class then error(long <:test dir. 4:>,line_no,element_no) else instr_index := number1; end else if name1 = long <:list:> then begin next1; if name1 = long <:on:> or name1 = long <:yes:> then list := true else if name1 = long <:off:> or name1 = long <:no:> then list := false else error(long <:test dir 5:>,line_no,element_no) end else if name1 = long <:page:> then begin if list then outchar(out,12); end else if name1 = long <:skip:> then begin <* procedure skip logic *> directive_skip_until; end else if name1 = long <:onlyi:> add 'n' then begin <* procedure skip if not in named mode *> directive_onlyin_logic(true); end else if name1 = long <:notin:> then begin <* skip if named mode *> directive_onlyin_logic(false <* invert the onlyin logic *>); end else if name1 = long <:until:> then begin <* a until directive met outside the performing of the skip logic is blind *> return_from_skip := true; end else if name1 = long <:load:> then begin zone zntb(128,1,stderror); long array long_name(1:2); integer move_count,no_of_halfwords; long array field move_index; move_index := -4; class1 := get_long_name(long_name); if class1 >0 then begin open(zntb,4,longname,0); movecount:=(name_table_length +1)* 5 <*dimension*> * 4 <*halfwords*>; for movecount :=movecount while movecount > 0 do begin no_of_halfwords := if move_count > 512 then 512 else move_count; move_count := move_count - no_of_halfwords; inrec6(zntb,no_of_halfwords); to_from(name_table.move_index,zntb,no_of_half_words); move_index := move_index + no_of_half_words; end read and move; end else error(load_file_name,0,0); if false then begin <******* test *******> write(out,<:<12>load contents of name table::>); for move_count :=0 step 1 until name_table_length do write(out,<:<10>:>,move_count,name_table(move_count,0), name_table(move_count,1), name_table(move_count,2), name_table(move_count,3), name_table(move_count,4)); end test; end else if name1 = long <:save:> then begin zone zntb(128,1,stderror); integer movecount,no_of_half_words; integer array field move_index; long array long_name(1:2); class1:=get_long_name(long_name); if class1>0 then begin open(zntb,4,long_name,0); if false then begin <***** test ***> write(out,<:<12>contents of saved name table::>); for move_count := 0 step 1 until name_table_length do write(out,<:<10>:>,movecount,name_table(move_count,0), name_table(move_count,1), name_table(move_count,2), name_table(move_count,3), name_table(move_count,4)); end test; movecount := (name_table_length +1)* 5 <*dimmension*> * 4 <*halfwords*>; move_index := -4; for movecount := movecount while movecount > 0 do begin no_of_halfwords := if movecount > 512 then 512 else movecount; movecount := movecount - no_of_half_words; outrec6(zntb,no_of_half_words); tofrom(zntb,name_table.move_index,no_of_half_words); move_index := moveindex + no_of_half_words; end move and write; close(zntb,true); end else error(save_file_name,0,0); end else if name1 = long <:end:> then begin class := eof_class; if list then list_line; end else if name1 = long <:copy:> then begin include_source_file; end else if name1 = long <:test:> then begin next; if class <> 9 and class <> 6 then error(long <:test dir t1:>,line_no,element_no) else begin if name = long <:on:> or name = long <:yes:> then test := true else if name = long <:off:> or name = long <:no:> then test := false else if name = long <:biton:> or name = long <:bitye:> add 115 then print_code := true else if name = long <:bitof:> add 102 or name = long <:bitno:> then print_code := false else if name = long <:labre:> add 102 then test_label_ref := true else if name = long <:labbi:> add 116 then test_label_bit := true else error(directive,line_no,element_no); end; end else error(long <:unknown directive:>,line_no,element_no-1); end; end; class := if class <> eof_class then stop_line_class else eof_class; end directive class else if class = semicolon_class then begin <* comment start *> class := stop_line_class; end else if class = long_text_class then begin error(name_length,line_no,element_no); next; end else begin <* class is something else *> error(delimiter,line_no,element_no); next; end; if class = eof_class then begin long array mic_asm_prog_name(1:2); integer result; result := connect_file_in(mic_asm_prog_name); if result = 0 then begin write(out,"nl",1,<: micasm source file: :>,mic_asm_prog_name); read_next_source_line; end; end; end scan loop; last_instr_index := instr_index ; resolve_labels; <* temp delete for index:=1 step 1 until label_ref_index do begin name := label_ref_table(index,0); if -, lookup_name(label_def_table,name,number) then begin instr_index := label_ref_table(index,2); error(undec_label,label_ref_table(index,1) extract 24, label_ref_table(index,3) extract 24) end else begin op_code(label_ref_table(index,2)):= mask_in(op_code(label_ref_table(index,2)), extend ( label_def_table(number,0) extract 24),addrs_mask); if test_label_bit or test_label_ref then begin write(out,"nl",1,"sp",5,<<zddd>, octal(label_ref_table(index,2)), <: label ref to: :>, octal(label_def_table(number,0))); if test_label_bit then begin write(out,<:<10> :>); print_formated(opcode(label_ref_table(index,2))); end; end; end; end label insert loop; if entry_list_wanted then begin <@ print label xref table @> procedure shellsort(n,file); value n; integer n; long array file; begin integer dist,i,k0,k,kmd; long a,fkmd,a_help,fkmd_help; dist:= -1; for dist:= dist shift(-1) while dist>0 do if dist<n then begin for k0:= dist+1 step 1 until n do begin a:= file(k0,1); a_help := file(k0,2); k:= k0; p: kmd:= k-dist; if kmd>0 then begin fkmd:= file(kmd,1); fkmd_help := file(kmd,2); if fkmd>a then begin file(k,2) := fkmd_help; file(k,1):= fkmd; k:= kmd; goto p end end; file(k,1):= a; file(k,2) := a_help; end end end; integer sort_index; long array wr_name(1:2); comment shell_sort(label_def_table_length,label_def_table); wr_name(2):=0; for index := 1 step 1 until label_def_table_length do begin l_d_record := ((index-1)*8)+4; if label_def_table(index,0) > 0 and (label_def_table.l_d_record.l_d_spec >0) then begin wr_name(1):= label_def_table(index,1); write(out,false add 32,15 - write(out,<:<10>:>,wr_name), <:<13> :>,<: ref. to addrs.::>, <<__zddd>, label_def_table.l_d_record.l_d_index, octal(extend label_def_table.l_d_record.l_d_index), <: spec or line no.::>,label_def_table.l_d_record.l_d_spec -1); end; end; end write xref label table loop; end of temp delete *> if test_label_ref then label_list(false); if entry_list_wanted then label_list(true); if print_error_table then write(out,<:<10>MIC. ASM. OK! :>) else write(out,<:<10>MIC. ASM. SORRY!:>,<<_ddd>,no_of_errors,<: error(s):>, <: found.:>); write(out,"nl",1,<:LAST INSTR. ADDRS.::>,<<_dddd>,last_instr_index, <: OCTAL INSTR. ADDRS.::>,octal(extend(last_instr_index))); if object_file_known then begin zone code_out(128,1,stderror); long array field code_block; integer short_clock; index :=1; open(code_out,4,object_file_known_name(increase(index)),0); setposition(code_out,0,1); <* start on segm 1. due to historic reasons *> for code_block :=-4,code_block + 512 while code_block < 4*length_of_code - 4 do begin outrec6(code_out,512); to_from(code_out,op_code.code_block,512); end; for index := 1 step 1 until 10 do tail(index):=0; tail(1) :=1 + ( length_of_code//128); tail(6) := systime(7)short clock:(0,0.0); tail(9) := code_kind shift 12 + start_addrs extract 12; tail(10) := length_of_code*4 + 512 <* first segm is dummy *>; monitor(44)change entry:(code_out,0,tail); close(code_out,true); end send object code to backing storage area; end dec of table block; write(out,<: TRANSLATOR BLOCKS::>,<<__d>,blocksread,"nl",1); fp_proc(7,0,0,0); <* end program *> end the whole prog; ▶EOF◀