|
|
DataMuseum.dkPresents historical artifacts from the history of: RC3500 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC3500 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 13056 (0x3300)
Types: TextFileVerbose
Names: »texcept«
└─⟦2c55ea56f⟧ Bits:30001844 SW-save af projekt 1000, Alarm-system
└─⟦6b41451d2⟧
└─⟦this⟧ »texcept«
job jaba 9 600 size 92000 time 11 0 output 200000 perm mini 100 1
(
platonenv = set bs bblenv
pascal80 codelist.no stack.512 codesize.12000 spacing.12000 ,
debugenvir ioenvir
bprintexcep = set 1 mini
bprintexcep = move pass6code
if ok.yes
scope project bprintexcep
finis
)
process printexcept;
type
line_number_table = record
line_chain : addr;
start_line : integer;
first_delta, second_delta : byte;
end;
descriptor = record
compilation_date : coded_date;
compilation_time : coded_time;
length_of_code : integer;
length_of_last : integer;
last_line : integer;
line_spacing : integer;
start_of_chain : addr;
end;
routine_ident = record
routine_name : alfa;
descriptor_ptr : ^ descriptor;
end;
activation_record = record
static_link : ^ activation_record;
dynamic_link : addr;
return_point : addr;
routine_name_ptr : ^ routine_ident;
end;
function asgnptraddr ( address_to_convert : addr ) : ^ routine_ident;
(* convert own.plinetable from addr to pointer *)
external;
function asgnptradr ( address_to_convert : addr ) : ^ line_number_table;
(* convert line_number_table.line_chain from addr to pointer *)
external;
function asgnpntradr ( address_to_convert : addr ) : ^ activation_record;
(* covnert dynamic link from addr to pointer *)
external;
function ult ( a, b : integer ) : boolean;
(* compare a and b as unsigned integers *)
external;
function getoflowmask : boolean;
(* returns the current value of suppress overflow flag *)
external;
procedure setoflowmask ( overflow : boolean );
(* assigns the new suppress overflow mask *)
external;
const
no_overflow = true;
doomsday = false;
op_top = 5; (* number of words from stack to reserve *)
addr_length = 2; (* words !! *)
nul_address = addr(base_type(0, 0, 0, 0, 0), 0);
var
lf, lf_help, gf : addr;
routine_id : alfa;
temp_addr,
ic : addr;
descriptor_pointer : ^ descriptor;
routine_name_pointer : ^ routine_ident;
stack : reference;
cause_text : alfa;
tto_level : byte;
operands : array ( 0 .. op_top ) of integer; (* four topmost stack words after exception *)
last_used : integer; (* index of stacktop in operands, temporary !!!! *)
(* last_used may be a constant = op_top in the next revision of the microprogram !!!!!!!!!!! *)
opcode : byte;
step, excode : integer;
function usub ( a, b : integer ) : integer;
var
overflow : boolean;
begin
overflow := getoflowmask;
setoflowmask( no_overflow );
usub := a - b;
setoflowmask( overflow );
end;
function uadd ( a, b : integer ) : integer;
var
overflow : boolean;
begin
overflow := getoflowmask;
setoflowmask( no_overflow );
uadd := a + b;
setoflowmask( overflow );
end;
procedure printtext24 ( str24 : array ( 1 .. 24 ) of char );
var
step : integer;
begin
step := 1;
while str24 ( step ) <> '#' do
begin
printchar ( str24 ( step ) );
if step = 24 then str24 ( 24 ) := '#' else step := step + 1;
end;
end; (* printtext24 *)
procedure print_called_from( routine_name : alfa; where : addr );
const
max_line = 255; (* pass6 dependent !!!! *)
var
first_addr, top_addr, top_of_next : addr;
old_first_addr_disp, top_addr_disp : integer;
found : boolean := false;
last_page : boolean := false;
line_tab_ptr : ^ line_number_table;
line, line_increment, spacing : integer;
begin
printtext('called from:');
printchar(' ');
printtext( routine_name );
printtext(', ic = # ');
printaddr( where );
printtext(', line # ');
(* now compute the line interval *)
with descriptor_pointer ^ do
begin
top_addr := start_of_chain;
spacing := line_spacing;
end; (* with *)
repeat
line_tab_ptr := asgnptradr ( top_addr );
top_of_next := line_tab_ptr ^ . line_chain;
first_addr.base := top_addr.base;
if top_of_next = top_addr then
begin (* last page of code *)
first_addr.disp := usub ( top_addr.disp, descriptor_pointer^.length_of_last);
last_page := true;
end
else
first_addr.disp := usub ( top_addr.disp, descriptor_pointer^.length_of_code );
if (ult( first_addr.disp, where.disp ) and ult( where.disp, top_addr.disp )
and (first_addr.base = where.base))
or (first_addr = where) then
begin (* the page has been found *)
found := true;
line := line_tab_ptr^. start_line;
top_addr_disp := top_addr.disp;
old_first_addr_disp := first_addr.disp;
while ult( first_addr.disp, where.disp )
and not ult(first_addr.disp, old_first_addr_disp ) do
begin (* find lower line number of interval *)
with first_addr do
begin
old_first_addr_disp := disp;
disp := uadd ( disp, spacing );
end; (* with *)
line := line + line_tab_ptr^.first_delta;
(* now move the line table pointer in order to let first_delta be next delta *)
with top_addr do
disp := uadd( disp, 1 );
line_tab_ptr := asgnptradr ( top_addr );
end;
printnumber ( line, 1 );
printchar ('-');
(* find upper line number *)
repeat (* find first delta less than max line *)
line_increment := line_tab_ptr^.first_delta;
line := line + line_increment;
with first_addr do
begin
old_first_addr_disp := disp;
disp := uadd( disp, spacing);
end; (* with *)
(* advance line_tab_ptr, i.e. let first_delta be next delta *)
with top_addr do
disp := uadd( disp, 1 );
line_tab_ptr := asgnptradr ( top_addr );
until (line_increment <> max_line) (* i.e. 'real' linenumber ' *)
or not ult (first_addr.disp, top_addr_disp) (* i.e. passed top *)
or ult (first_addr.disp, old_first_addr_disp) (* i.e. wrap-around... *)
;
if line_increment = max_line then
begin (* upper line number is first line of next page ! *)
if last_page then
line := descriptor_pointer^.last_line
else
line := asgnptradr( top_of_next ) ^ . start_line;
end;
printnumber( line, 1 );
end (* printing interval *)
else
(* try the next page *)
top_addr := top_of_next;
if last_page and not found then
begin
printtext('not found, i'); printtext('c = # ');
printaddr(where);
found := true;
end;
until found;
end; (* print called from *)
procedure print_date( date : coded_date );
begin
with date do
begin
printnumber( year_after_1900 + 1900, 7);
printchar('.');
if month < 10 then printchar('0');
printnumber( month, 1);
printchar('.');
if day < 10 then printchar('0');
printnumber( day, 1 );
end;
end;
procedure print_time ( time : coded_time );
begin
with time do
begin
printchar( ' ' );
if hour < 10 then printnumber( 0 , 1 );
printnumber ( hour , 1 );
printchar( '.' );
if minute < 10 then printnumber( 0, 1 );
printnumber( minute , 1 );
end; (* with *)
end;
begin
repeat
wait ( stack, own.secret_pointer^ ( exceptionsem ) ^ );
readram( tto_level, 1 ); (* remember interrrupt level *)
writeram( 1, 0 ); (* clear interrupt level *)
lock stack as own : ext_incarnation_descriptor do
begin
gf := stack ^ . start; (* even displacement !! *)
lf.base := gf.base; (* local frame and global frame is in the same memory module *)
lf.disp := own.dumpsf (* odd displacement *) - 1; (* even displacement !! *)
(* detect how the procedure was entered, i.e. find out
whether the call was caused by an exception or it was
a programmed activation of the trace procedure *)
if (stack^ . u1 <> 0) or (own . exic = nul_address) then
(* trace *)
begin
ic := asgnpntradr ( lf ) ^ . return_point;
cause_text := 'trace # ';
last_used := op_top - 1; (* optop is the parameter of trace *)
end
else
begin
ic := own.exic;
cause_text := 'exception # ';
last_used := op_top - 2; (* nb the parameter and the resume bit is pushed on top before call
of the exception procedure !!!!!! *)
lf_help := asgnpntradr( lf ) ^ . dynamic_link;
lf_help . disp := lf_help . disp - 1; (* even address *)
if lf_help <> gf then
if asgnpntradr( lf_help ) ^ . routine_name_ptr ^ . routine_name = 'exception' then
begin (* system exception activated from user defined exception procedure *)
(* i.e. unstack routine level for exception procedure *)
lf := lf_help;
end;
end;
(* print process name and cause *)
printnl;
printtext ( asgnptraddr ( own.plinetable ) ^ . routine_name );
printtext ( '>> # ' );
printtext ( cause_text );
printtext ( ', excode = #' );
with stack ^ do
if u2 >= 128 then
excode := (u2 - 128) * 256 + (- 32768) + u3
else
excode := u2 * 256 + u3;
printhex( excode );
printchar(':'); printchar(' ');
(* get the opcode and the op_top top operands *)
temp_addr := lf; (* lf is a pointer to the bottom of the frame
pushed on the frame which caused the exception, i.e.
lf.disp - 2 is address of topoperand ... *)
for step := op_top downto 0 do
begin
with temp_addr do
disp := usub ( disp, 2 );
getinteger ( operands ( step ), temp_addr );
end; (* for ... *)
getbyte ( opcode, ic ); (* 'revsb 0 ' *)
if cause_text = 'exception # ' then
case excode of
1: printtext24 ( 'signal: reference = nil ');
5: begin
printtext24 ( ' reference = nil ' );
end;
6: printtext24 ( 'not channel message # ');
8: printtext24 ( 'not data message # ');
9: printtext24 ( 'size too small# ');
#ha: printtext24 ( 'last < first # ');
#hb: begin
printtext24 ( 'arithmetic overflow : # ');
if (opcode <> #h50) and (opcode <> #h51) then
printnumber ( operands ( last_used - 1 ) , 1 );
case opcode of
#h50: (* monadic minus *) printchar ( '-' );
#h51: (* abs *) printtext ( 'abs # ' );
#h44, #h42: (* add, uadd *) printchar ( '+' );
#h45, #h43: (* sub, usub *) printchar ( '-' );
#h49, #h46: (* mul, umul *) printchar ( '*' );
#h4a, #h47: (* div, udiv *) printtext ( ' div # ' );
#h4b, #h48: (* mod, umod *) printtext ( ' mod # ' );
otherwise
printchar ( "'" );
printhex ( opcode );
printchar ( "'" );
end; (* otherwise *)
printnumber ( operands ( last_used ), 1 );
end; (* #hb ... *)
#hc: (* index exception *)
begin
printtext24 ( 'index out of bounds: # ' );
(* top of stack: index value, addr_of ( dope vector ) *)
(* note: when after 'store in packed array': also 'value' to be stored *)
printnumber ( operands ( last_used - addr_length - ord ( opcode = #h6f (* inpss *) ) ), 1 );
end; (* #hc ... *)
#h10: printtext24 ( 'stack overflow # ' );
#h11: (* range exception *)
begin
printtext24 ( 'subrange out of bounds: ');
(* top of stack: range value, addr_of ( range descriptor ) *)
printnumber ( operands ( last_used - addr_length ), 1 );
end; (* #h11 ... *)
#h12: printtext24 ( 'pointer = nil # ' );
#h20..#h23: printtext24 ( 'shadow = nil # ' );
#h15: printtext24 ( 'identical arguments # ' );
#h7: printtext24( 'block i/o at level 0 #');
#h1a: printtext24( 'wait : reference <> nil #');
#h1f: printtext24 ( 'no core # ' );
#h16, #h19: printtext24 ( 'second param locked ' );
#h17: printtext24 ( 'first param <> nil ' );
#h18: printtext24 ( 'second param = nil ' );
#h13: printtext24 ( 'first param = nil ' );
#h14: printtext24 ( 'first param not empty ' );
#h1b: printtext24 ( 'reference locked' );
#h1c: printtext24 ( 'not data message # ' );
#h1d: printtext ( 'size error #' );
#h1e: begin
printtext24 ( 'multible wait on locked' );
printtext ( ' semaphore' );
end;
#h24: begin
printtext24 ( 'illegal switch in case c' );
printtext ( 'onstruction ' );
end;
#h25: begin
printtext24 ( 'upper limit in call of s' );
printtext ( 'ucc # ' );
end;
#h26 : begin
printtext24 ( 'lower limit in call of p' );
printtext ( 'red # ' );
end;
#h29: begin
printtext24 ( 'local reference variable' );
printtext24 ( ' not nil at routine exit' );
end;
otherwise
if (excode > 0) and (excode <= #h2f) then
printtext ( 'system error' );
end; (* case excode of ... *)
printnl;
printtext ( 'gf = # ' ); printaddr ( gf );
printtext ( ' , top = # ' ); printaddr ( lf );
printtext ( ' , code = # ' ); printhex ( opcode );
printnl; printnl;
while lf <> gf do
begin
lf := asgnpntradr ( lf ) ^ .dynamic_link; (* odd displacement *)
lf.disp := lf.disp - 1; (* even displacement !!! *)
if lf = gf then
begin
routine_id := own.incname;
descriptor_pointer := asgnptraddr( own.plinetable) ^ .descriptor_ptr;
end
else
begin
routine_name_pointer := asgnpntradr( lf ) ^ . routine_name_ptr;
with routine_name_pointer ^ do
begin
routine_id := routine_name;
descriptor_pointer := descriptor_ptr;
end;
end;
print_called_from ( routine_id, ic );
print_date ( descriptor_pointer^.compilation_date );
print_time ( descriptor_pointer^.compilation_time );
printnl;
ic := asgnpntradr ( lf ) ^ .return_point;
end; (* while lf <> gf *)
end; (* lock *)
printnl;
writeram( 1, tto_level ); (* reestablish interrupt level *)
printchar ( nul ); (* force interrupt *)
return ( stack );
until doomsday;
end (* process printexcept *)
.
«eof»