%ltrace %ptrace extern type char1000 = array [1..1000] of char; char2000 = array [1..2000] of char; char3000 = array [1..3000] of char; char4000 = array [1..4000] of char; char5000 = array [1..5000] of char; char6000 = array [1..6000] of char; char7000 = array [1..7000] of char; char8000 = array [1..8000] of char; char9000 = array [1..9000] of char; jgraf_interface = record command, plot_char : char; x_grid, y_grid : boolean; rows, columns : integer; x_lower, x_upper, y_lower, y_upper : real; filename : array [1..14] of char; graf_title : string; b : ^char9000; bufr_size, line_size, row_count : integer; x_spacing, y_spacing : real; end; procedure jgraf ( var jg : jgraf_interface; x, y : real ); var i : integer; f1 : file of char; procedure setup; var ai : integer; axis_labels : array [1..50] of record axis : char; ptr : integer; end; procedure allocate_buffer; label 99; var x : integer; b1 : ^char1000; b2 : ^char2000; b3 : ^char3000; b4 : ^char4000; b5 : ^char5000; b6 : ^char6000; b7 : ^char7000; b8 : ^char8000; b9 : ^char9000; begin jg.line_size:=jg.columns+16; jg.row_count:=jg.rows+5; jg.bufr_size:=jg.line_size * jg.row_count + 8; x := (jg.bufr_size div 1000) + 1; if (x < 1) or (x > 9) then begin writeln('JGRAF - graph size error:', jg.bufr_size); goto 99; end; case x of 1 : begin new(b1); jg.b:=b1 end; 2 : begin new(b2); jg.b:=b2 end; 3 : begin new(b3); jg.b:=b3 end; 4 : begin new(b4); jg.b:=b4 end; 5 : begin new(b5); jg.b:=b5 end; 6 : begin new(b6); jg.b:=b6 end; 7 : begin new(b7); jg.b:=b7 end; 8 : begin new(b8); jg.b:=b8 end; 9 : begin new(b9); jg.b:=b9 end; end; 99: end; (* allocate_buffer *) procedure crlfs; (* put crlfs in buffer *) var i, ptr : integer; cr, lf : char; begin cr:=chr(0dh); lf:=chr(0ah); ptr:=jg.line_size - 1; for i:=1 to jg.row_count-1 do begin jg.b^[ptr]:=cr; jg.b^[ptr+1]:=lf; ptr:=ptr + jg.line_size; end; ptr := ptr + 8; jg.b^[ptr]:=cr; jg.b^[ptr+1]:=lf; end; (* crlfs *) procedure xgrid; var x : integer; procedure x_axes ( r : integer; main : boolean ); var i,r1,ptr,count : integer; ll,ss,rr,xx : real; begin r1 := jg.row_count - r; ptr := (r1 * jg.line_size) + 13; (* update axis labels array and file *) axis_labels[ai].axis:='x'; axis_labels[ai].ptr:=ptr; ai:=ai+1; rr:=r; ss:=jg.y_spacing; ll:=jg.y_lower; xx := ((rr - 3.0) * ss) + ll; write(f1; xx); if jg.x_grid or main then count := jg.columns else count := 1; for i:=0 to count do jg.b^[ptr+i] := '-'; end; (* x_axes *) begin (* xgrid *) x_axes(3,true); x := 13; while x <= jg.row_count-1 do begin x_axes(x,false); x := x + 10; end; end; (* xgrid *) procedure ygrid; var y : integer; procedure y_axes ( c : integer; main : boolean ); var i, ptr : integer; cc,ll,ss,yy : real; begin if jg.y_grid or main then begin ptr := (2 * jg.line_size) + c; for i:=1 to jg.rows + 1 do begin jg.b^[ptr]:='I'; ptr:=ptr + jg.line_size; end; end else begin (* no ygrid *) ptr := (jg.line_size * (jg.rows+2)) + c; jg.b^[ptr]:='I'; end; (* update axis labels array and file *) axis_labels[ai].axis:='y'; axis_labels[ai].ptr:=ptr; ai:=ai+1; cc:=c; ss:=jg.x_spacing; ll:=jg.x_lower; yy := ((cc - 14.0) * ss) + ll; write(f1; yy); end; (* y_axes *) begin (* ygrid *) y_axes(14,true); y := 24; while y <= jg.columns + 14 do begin y_axes(y,false); y := y + 10; end; end; (* ygrid *) procedure clear_bufr; type buffer = array [1..20] of char1000; var a : char1000; i : integer; ptr : ^buffer; begin a:=' '; map(ptr,addr(jg.b^)); for i:=1 to (jg.bufr_size div 1000) + 1 do ptr^[i]:=a; end; procedure move_title; var s : string[20]; x,i : integer; begin s := 'JGRAF ver 2.2'; for i:=1 to 13 do jg.b^[i]:=s[i]; x := (jg.line_size div 2) - (length(jg.graf_title) div 2) + 2; for i:=1 to 4 do begin jg.b^[x] := '*'; x:=x+1; end; x:=x+1; (* skip 1 space *) for i:=1 to length(jg.graf_title) do begin jg.b^[x] := jg.graf_title[i]; x:=x+1; end; x:=x+1; (* skip 1 space *) for i:=1 to 4 do begin jg.b^[x] := '*'; x:=x+1; end; end; (* move_title *) procedure process_axis_labels; var hold : array [1..30] of char; i,j : integer; ch : char; procedure xlabels; var count,ptr,number_length,k : integer; begin number_length:=j-1; ptr := axis_labels[i].ptr; if number_length <= 8 then begin ptr := ptr - number_length; count:=number_length; end else begin ptr:=ptr - 8; count:=8; end; for k:=1 to count do begin jg.b^[ptr] := hold[k]; ptr := ptr + 1; end; end; (* xlabels *) procedure ylabels; var count, ptr, number_length, k : integer; begin number_length:=j-1; ptr:=axis_labels[i].ptr; if number_length <= 8 then begin ptr := ptr + jg.line_size - (number_length div 2) + 1; count:=number_length; end else begin ptr := ptr + jg.line_size - 4; count:=8; end; for k:=1 to count do begin jg.b^[ptr]:= hold[k]; ptr := ptr + 1; end; end; (* ylabels *) begin reset(f1,'jgraf.$$$',binary,128); read(f1; ch); (* skip over leading blank *) for i:=1 to ai-1 do begin hold:=' '; j:=1; repeat read(f1; ch); hold[j]:=ch; j:=j+1; until ch = ' '; case axis_labels[i].axis of 'x' : xlabels; 'y' : ylabels; end; end; close(f1); end; (* process_axis_labels *) begin (* setup *) jg.x_spacing := (jg.x_upper - jg.x_lower) / jg.columns; jg.y_spacing := (jg.y_upper - jg.y_lower) / jg.rows; allocate_buffer; clear_bufr; crlfs; ai := 1; (* axis labels array index *) rewrite(f1,'jgraf.$$$',text,128); xgrid; ygrid; write(f1; ' '); close(f1); process_axis_labels; move_title; end; (* setup *) procedure data; label 99; var x1, y1 : integer; procedure plot ( x,y : integer ); (* place char in graph area - origin 0 at lower left *) var ptr : integer; begin ptr := (jg.line_size * (jg.row_count - y - 3)) + (x + 14); if ptr > jg.bufr_size then writeln('plot computation error') else jg.b^[ptr] := jg.plot_char; end; (* plot *) begin if not ((x >= jg.x_lower) and (x <= jg.x_upper) and (y >= jg.y_lower) and (y <= jg.y_upper)) then goto 99; x1 := round((x - jg.x_lower) / jg.x_spacing); y1 := round((y - jg.y_lower) / jg.y_spacing); plot(x1,y1); 99: end; procedure display ( mode : char ); var bytes_remaining, len, start : integer; begin if mode = 'p' then system(list); if mode = 's' then rewrite(f1,jg.filename,binary,1024); bytes_remaining := jg.bufr_size; start:=1; repeat if bytes_remaining >= 1024 then len:=1024 else len:=bytes_remaining; if mode = 's' then write(f1; copy(jg.b^,start,len)) else write( copy(jg.b^,start,len)); start:=start+1024; bytes_remaining:=bytes_remaining-1024; until bytes_remaining <= 0; if mode = 'p' then system(nolist); if mode = 's' then close(f1); end; (* display *) begin (* jgraf *) case upcase(jg.command) of 'D' : data; 'I' : setup; 'S' : display('s'); 'C' : display('c'); 'P' : display('p'); 'X' : dispose(jg.b); else : writeln('JGRAF - unknown command: ', jg.command); end; (* case *) end; (* jgraf *).