DataMuseum.dk

Presents historical artifacts from the history of:

Jet Computer Jet80

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Jet Computer Jet80

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦17500d44c⟧ TextFile

    Length: 25984 (0x6580)
    Types: TextFile
    Names: »CHECKS.PAS«

Derivation

└─⟦dd59903ef⟧ Bits:30005887 Klub diskette for udveksling af software
    └─ ⟦this⟧ »CHECKS.PAS« 

TextFile

PROGRAM checks;
æ Pascal/z version--This is an update from Disk #15 of CheckBk(alias
  NOW). The author sez the interesting improvements are the availability
  of on-line changes in code assignments, and ability to edit and
  reconform the data stored in the file. He has had a little bug in
  the 'Dump' portion of the program. If it is selected from the menu
  it may or may not lose some data . So if anyone traps that bug be
  sure and let us know.å


CONST max_items = 300;
      max_codes = 50;
      max_add_code = 10;
      disk_file = 'A:CHECK82';
      left = 7;     æ Number of digits to the left of the dp å
      right =  2;    æ   "    "    "     "  "  right "  "  "  å

  æ Number of bytes it takes to represent a fixed-point number  å
	bytes = (left + right + 1) div 2;

   æ  Length of a fixed-point converted string  å
	maxchars = ((left * 4) div 3) + right + 3;

TYPE
	signtyp = (plus, minus);
	carrytyp = 0..1;

æ The basic unit of a fixed-point number, takes 1 byte of storage. å
	byte = 0..255;

	modetyp = (none, suplzer, supltzer, wdollar, wcomma, wboth);

  æ This is the type around which this whole package is based.	 å
	fixed = record
		  sign: signtyp;
		  digits: arrayÆ1..bytesÅ of byte
		end;

æ This is a string type which holds a fixed-point number converted å
  æ to ASCII. å
	fixstr = string maxchars;

	$STRING0 = STRING 0;
	$STRING255 = STRING 255;
     	item_data = RECORD
			item_number : INTEGER;
			month : INTEGER;
			day : INTEGER;
			year : INTEGER;
			amount : FIXED;
			description : STRING 30;
			code : INTEGER;
		    END;
VAR command : CHAR;
	code_description : ARRAY Æ1..max_codesÅ OF STRING 15;
	items : ARRAY Æ1..max_itemsÅ OF item_data;
        item_last : 1..max_items;
	data_file : FILE of item_data;
	lines_printed : 0..80;
	code_amount : ARRAY Æ1..max_codesÅ OF FIXED;
	entry_year : INTEGER;
	swaped : BOOLEAN;
	answer : CHAR;
	result : INTEGER;

æ This is set by the fixed point functions. It is set true if there å
æ was an overflow. å
	fixederror: boolean;

æ This is the carry flag. It is used by the fixed point functions. å
æ The user's code doesn't play with it. å
	carry: carrytyp;

(****************************************************************)
(*								*)
(* Ithaca InterSystems' Pascal/Z Fixed-Point Package            *)
(*								*)
(* Written by Robert Bedichek	  August 1980			*)
(*								*)
(****************************************************************)

procedure setlength( var y:$string0; x: integer ); external;
function length( x:$string255 ): integer; external;

(* The next two external functions are in LIB.REL and are automatically *)
(* linked in when the library is being linked in.  They add and 	*)
(* subtract two decimal digits packed into a byte using Z-80 decimal	*)
(* arithmetic.								*)
function addbyte( var carry: carrytyp; a, b: byte ):byte; external;
function subbyte( var carry: carrytyp; a, b: byte ):byte; external;

function add( a, b: fixed ): fixed;
(************************************************************************)
(* The value of this function is the signed sum of the two value	*)
(* parameters.	The global variable 'fixederror' is set if there was	*)
(* an overflow. 							*)
(*									*)
(*									*)
(*									*)
(************************************************************************)
var
	carry: 0..1;
	i: integer;
	res: fixed;

begin
  carry := 0;
  if a.sign = b.sign then   (* Like signs, just add	*)
    begin
      add.sign := a.sign;
      for i := 1 to bytes do
	add.digitsÆ i Å := addbyte( carry, a.digitsÆ i Å, b.digitsÆ i Å );
      fixederror := (carry = 1)
    end
		     else   (* Unlike signs, subract negative op from pos.  *)
    begin
      fixederror := false;
      if a.sign = plus then
	for i := 1 to bytes do
	  res.digitsÆ i Å := subbyte(carry, a.digitsÆ i Å, b.digitsÆ i Å)
		       else
	for i := 1 to bytes do
	  res.digitsÆ i Å := subbyte(carry, b.digitsÆ i Å, a.digitsÆ i Å);
      if carry = 0 then res.sign := plus
		   else
		     begin
		       res.sign := minus;
		       carry := 0;

(* Take nines complement of the result by subtracting it from zero.	*)
		       for i := 1 to bytes do
		res.digitsÆ i Å := subbyte( carry, 0, res.digitsÆ i Å)
		     end;
      add := res
    end
end;

function sub( minuend, subtrahend: fixed ): fixed;
(************************************************************************)
(* The value of this function is the signed difference of the two	*)
(* value parameters.  The global variable 'fixederror' is set if the	*)
(* is an overflow.							*)
(*									*)
(*									*)
(*									*)
(************************************************************************)

begin

(* Just reverse the sign of the subtrahend and add.			*)
  if subtrahend.sign = plus then subtrahend.sign := minus
			    else subtrahend.sign := plus;
  sub := add( minuend, subtrahend )
end;



procedure shiftleft( var a: fixed );
(************************************************************************)
(* This procedure shifts all of the packed decimal digits in the	*)
(* passed parameter left one position.	A zero is shifted into the	*)
(* least significant position.	The digit shifted out is lost.		*)
(*									*)
(*									*)
(*									*)
(************************************************************************)
var
	i: integer;
	next: byte;

begin
  for i := bytes downto 1 do
    begin
      if i > 1 then next := (a.digitsÆ i - 1 Å div 16)
	       else next := 0;
      a.digitsÆ i Å := ((a.digitsÆ i Å * 16) + next) mod 256
    end
end;		(*	shiftleft	*)

procedure shiftright( var a: fixed );
(************************************************************************)
(* This procedure shifts all of the packed decimal digits in the passed *)
(* parameter right one position.  A zero is shifted into the most	*)
(* significant position.  The digits shifted out is lost.		*)
(*									*)
(*									*)
(*									*)
(************************************************************************)
var
	i: integer;
	next: byte;

begin
  for i := 1 to bytes do
    begin
      if i < bytes then next := (a.digitsÆ i + 1 Å mod 16) * 16
		   else next := 0;
      a.digitsÆ i Å := (a.digitsÆ i Å div 16) + next
    end
end;		(*	shiftright	*)







function fixtostr( a: fixed; mode: modetyp; trailing: byte ): fixstr;
(************************************************************************)
(* This function returns a formatted string.  The 'mode' parameter	*)
(* specifies which formatting operation is to take place.  The		*)
(* 'trailing' parameter specifies the maximum number of digits to the	*)
(* right of the decimal point that are to appear.			*)
(*									*)
(*									*)
(************************************************************************)
var
	i, j: byte;
	result: fixstr;

begin
  if trailing > right then trailing := right;

(* Make the 'result' string have 'maxchars' spaces		*)
  setlength( result, 0 );
  for i := 1 to maxchars do append( result, ' ' );

  resultÆ maxchars - right Å := '.';

(* Put the digits to the right of the dp into the string	 *)
  for i := maxchars downto maxchars - (right - 1) do
    begin
      resultÆ i Å := chr((a.digitsÆ 1 Å mod 16) + ord('0'));
      shiftright( a )
    end;

(* Leave 'trailing' digits to the right of the decimal point	*)
  for i := maxchars downto (maxchars - (right - trailing)) + 1 do
    resultÆ i Å := ' ';

(* Put the digits to the left of the dp into the string 	*)
  j := maxchars - right - 1;
  for i := maxchars - right - 1 downto maxchars - left - right do
    begin

(* Put a comma between every third digit if 'mode' tells us to	*)
      if ((((maxchars - right - 1) - i) mod 3) = 0) and
	 (i < (maxchars - right - 1)) and
	 (mode >= wcomma) then
			    begin
			      resultÆ j Å := ',';
			      j := j - 1
			    end;
      resultÆ j Å := chr((a.digitsÆ 1 Å mod 16) + ord('0'));
      j := j - 1;
      shiftright( a )
    end;


(* Suppress leading zeros if mode is anything other than 'none' *)
  j := j + 1;
  if mode > none then
    while ((resultÆ j Å = '0') or (resultÆ j Å = ','))
	  and (j < maxchars - right - 1) do
      begin
	resultÆ j Å := ' ';
	j := j + 1
      end;

(* Put a dollar sign in front of the most significant digit if	*)
(* 'mode' is 'wdollar' or 'wboth'				*)
  j := j - 1;
  if (mode = wdollar) or (mode = wboth) then
    begin
      resultÆ j Å := '$';
      j := j - 1
    end;

(* If the number being converted is negative put a minus sign in	*)
(* front of the dollar sign or (if there is no dollar sign) the most	*)
(* most significant digit.						*)
  if a.sign = minus then resultÆ j Å := '-';

(* If we are supposed to suppress leading and trailing zeros	*)
(* (mode = supltzer), suppress the trailing ones here.		*)
  if mode = supltzer then
    begin
      j := maxchars - ( right - trailing );
      while resultÆ j Å = '0' do
	begin
	  resultÆ j Å := ' ';
	  j := j - 1
	end
    end;
  fixtostr := result
end;		(*	fixtostr	*)

function strtofix( a: fixstr ): fixed;
(************************************************************************)
(* This converts the passed string to fixed point.  All characters	*)
(* other than the minus sign (-), decimal point(.), and the decimal	*)
(* digits (0123456789) are skipped over and ignored.			*)
(*									*)
(*									*)
(*									*)
(************************************************************************)
var
	rightcount, i: byte;
	righthalf: boolean;	(* True when scanning digits to right of dp  *)
	result: fixed;

begin
  righthalf := false;
  rightcount := 0;
  for i := 1 to bytes do result.digitsÆ i Å := 0;
  result.sign := plus;
  for i := 1 to length( a ) do
    if aÆ i Å = '.' then righthalf := true
		    else
      if aÆ i Å = '-' then result.sign := minus
		      else
       if (rightcount < right) and (aÆ i Å <= '9') and (aÆ i Å >= '0')
	 then
	   begin
	     shiftleft( result );
	     result.digitsÆ1Å := result.digitsÆ1Å + ord(aÆiÅ) - ord('0');
	     if righthalf then rightcount := rightcount + 1
	   end;
    for i := rightcount to right - 1 do shiftleft( result );
  strtofix := result
end;		(*	strtofix	*)




PROCEDURE initialize;
æ set inital values å
VAR count : 0..max_items;
BEGIN
	item_last := 1;
	FOR count := 1 TO max_codes DO
	  code_descriptionÆcountÅ := '               ';
	code_descriptionÆ1Å  := 'Balance forward';
	code_descriptionÆ2Å  := 'Deposit        ';
	code_descriptionÆ3Å  := 'NOW interest   ';
        code_descriptionÆ4Å  := 'Misc. add      ';
	code_descriptionÆ11Å := 'House payment  ';
	code_descriptionÆ12Å := 'Car payment    ';
	code_descriptionÆ13Å := 'Gas & Electric ';
	code_descriptionÆ14Å := 'Gasoline       ';
	code_descriptionÆ15Å := 'Credit cards   ';
	code_descriptionÆ16Å := 'Auto insurance ';
	code_descriptionÆ17Å := 'Entertainment  ';
	code_descriptionÆ18Å := 'Telephone      ';
	code_descriptionÆ19Å := 'Auto maint.    ';
	code_descriptionÆ20Å := 'Subscriptions  ';
	code_descriptionÆ21Å := 'Clothing       ';
	code_descriptionÆ22Å := 'Computer parts ';
	code_descriptionÆ23Å := 'Travel/hotels  ';
	code_descriptionÆ24Å := 'Contributions  ';
	code_descriptionÆ25Å := 'Misc auto      ';
	code_descriptionÆ26Å := 'Investments    ';
        code_descriptionÆ27Å := 'Education      ';                         
        code_descriptionÆ28Å := 'Water & sewer  ';
        code_descriptionÆ29Å := 'Taxes          ';
        code_descriptionÆ30Å := 'Books          ';
        code_descriptionÆ31Å := 'Food           ';
        code_descriptionÆ32Å := 'Drugs          ';
        code_descriptionÆ33Å := 'Medical service';
        code_descriptionÆ34Å := 'Tyme withdrawl ';
        code_descriptionÆ35Å := 'Misc insurance ';
        code_descriptionÆ36Å := 'Dental         ';
        code_descriptionÆ37Å := 'Pro tools/equip';
        code_descriptionÆ38Å := 'Pro subscript. ';
        code_descriptionÆ39Å := 'Pro books      ';
        code_descriptionÆ40Å := 'Auto Registrat.';
        code_descriptionÆ41Å := 'Slip rent      ';
        code_descriptionÆ42Å := 'Boat expenses  ';
        code_descriptionÆ43Å := 'Sewing/knitting';
        code_descriptionÆ49Å := 'Misc. subtract ';
        code_descriptionÆ50Å := 'Misc. expenses ';
END;

PROCEDURE newpage;
æ print form-feed and 2 blank lines å
BEGIN
        WRITELN(CHR(12));
        WRITELN;
        WRITELN;
        lines_printed := 0;
END;

PROCEDURE instructions;
æ print description of program operation å
VAR answer : CHAR;
    count  : INTEGER;
BEGIN
        newpage;
        WRITELN(' Checkbook program - For Wesley & Shirley Jenkins ');
        WRITELN(' Version 1.23 ');
        WRITELN;
        WRITE(' Want instructions ? ');
        READ(answer);
        WRITELN;
        IF (answer = 'Y') OR (answer = 'y') THEN
          BEGIN          
             newpage;    
             WRITELN(' -- Commands --');
             WRITELN;
             WRITELN(' A - Add an item');
             WRITELN(' R - Remove an item');
             WRITELN(' P - Print all items');
             WRITELN(' B - Print by balance');
             WRITELN(' S - Sort by date');
             WRITELN(' D - Dump to disk');
             WRITELN(' L - Load from disk');
	     WRITELN(' M - Modify an item');
             WRITELN(' Q - Quit');
	     WRITELN(' H - Hardcopy all items');
	     WRITELN(' I - Hardcopy instructions and codes');
	     WRITELN(' J - Hardcopy balance');
             WRITELN;
             WRITELN;
             WRITELN('Code        Description');
             FOR count := 1 TO 27 DO
                WRITE('-');
             WRITELN;
             FOR count := 1 TO 50 DO
                IF code_descriptionÆcountÅ <> '              ' THEN
                   WRITELN(count:3,'        ',code_descriptionÆcountÅ);
             END;
END;

PROCEDURE heading;
æ print heading for new page of item printout å
VAR  count : 0..79;
BEGIN
        WRITE(' Item     Date         Amount           Description');
        WRITE('              Code');
        WRITELN;
        FOR COUNT := 1 TO 79 DO WRITE('-');
        WRITELN;
END;

PROCEDURE item_print(count : INTEGER);
æ print data on one item å
BEGIN
        WITH itemsÆcountÅ DO
        BEGIN
        WRITE(item_number:5);
        WRITE(month:5,'/');
        IF day < 10 THEN
             WRITE('0',day:1) 
        ELSE
             WRITE(day:2);
        WRITE('/',year:2);
        WRITE(FIXTOSTR(amount,WBOTH,2));
        WRITE(' ',description);
        WRITE('  ',code_descriptionÆcodeÅ);
        END;
END;


PROCEDURE print_instructions;
æ Output to printer, commands & codes å
VAR file_out : TEXT;
    count : INTEGER;
BEGIN
  REWRITE('Lst:',file_out);
  WRITELN(file_out,CHR(12));
  WRITELN(file_out,' ------Commands---------------------- ');
  WRITELN(file_out,' A - Add an item');
  WRITELN(file_out,' R - Remove an item');
  WRITELN(file_out,' P - Print all items');
  WRITELN(file_out,' B - Print by balance');
  WRITELN(file_out,' S - Sort by date');
  WRITELN(file_out,' D - Dump to disk');
  WRITELN(file_out,' L - Load from disk');
  WRITELN(file_out,' M - Modify an item');
  WRITELN(file_out,' Q - Quit');
  WRITELN(file_out,' H - Hardcopy all items');
  WRITELN(file_out,' I - Hardcopy instructions and codes');
  WRITELN(file_out,' J - Hardcopy balance');
  WRITELN(file_out);
  WRITELN(file_out,'Code    Description');
  WRITELN(file_out,CHR(9),'---------------------------');
  FOR count := 1 TO max_codes DO
      WRITELN(file_out,count:3,'     ',code_descriptionÆcountÅ);
  WRITELN(file_out);
  WRITELN;
END;

PROCEDURE print_all;
æ print data for all items in file å
VAR count : INTEGER;
BEGIN
        newpage;
        heading;
             FOR count := 1 TO item_last-1 DO
             BEGIN
             IF lines_printed = 20 THEN
                    BEGIN
                      newpage;
                      heading;
                    END;
             item_print(count);
             lines_printed := lines_printed +1;
	     WRITELN;
             END;	
        WRITELN;
END;

PROCEDURE hardcopy_heading;
æ prints hardcopy heading for printout å
VAR file_out : TEXT;
    count : INTEGER;
BEGIN
	REWRITE('Lst:',file_out);
        WRITELN(file_out,CHR(12));
	WRITE(file_out,' Item     Date        Amount           Description');
	WRITE(file_out,'              Code');
	WRITELN(file_out);
	FOR count := 1 TO 79 DO WRITE(file_out,'-');
	WRITELN(file_out);
	lines_printed := 3;
END;

PROCEDURE copy_all;
æ Hardcopys all items in file å
VAR count : 0..79;
    file_out : TEXT;
BEGIN
	hardcopy_heading;
         FOR count := 1 TO item_last-1 DO
         BEGIN
             IF lines_printed = 75 THEN
			hardcopy_heading;
             WITH itemsÆcountÅ DO  
	     BEGIN
		REWRITE('Lst:',file_out);
	     	WRITE(file_out,item_number:5);
		WRITE(file_out,month:5,'/');
		IF day < 10 THEN 
			WRITE(file_out,'0',day:1)
		ELSE
			WRITE(file_out,day:2);
		WRITE(file_out,'/',year:2);
		WRITE(file_out,FIXTOSTR(amount,WBOTH,2));
		WRITE(file_out,' ',description);
		WRITE(file_out,'  ',code_descriptionÆcodeÅ);
		WRITELN(file_out);
             END;	
        lines_printed := lines_printed +1;
        END;
END;

PROCEDURE print_balance;
æ Print totals by categories and net balance å
VAR item : 1..max_items;
    balance : FIXED;
BEGIN
        FOR item := 1 TO max_codes DO
          code_amountÆitemÅ := STRTOFIX('0');
        balance := STRTOFIX('0');
	FOR item := 1 TO item_last-1 DO
	  WITH itemsÆitemÅ DO
	    code_amountÆcodeÅ := ADD(code_amountÆcodeÅ, amount);
	FOR item := 1 TO max_add_code DO
	  balance := ADD(balance, code_amountÆitemÅ);
	FOR item := max_add_code+1 TO max_codes DO
	  balance := SUB(balance, code_amountÆitemÅ);
	newpage;
	WRITELN('   Category             Amount');
	FOR item := 1 TO 32 DO
	  WRITE('-');
	WRITELN;
	FOR item := 1 TO max_codes DO
	  IF code_amountÆitemÅ <> STRTOFIX('0') THEN	 
   WRITELN(code_descriptionÆitemÅ,'  -',FIXTOSTR(code_amountÆitemÅ,WBOTH, 2 ));
	FOR item := 1 TO 32 DO
	  WRITE('-');
	WRITELN;
	WRITELN('Balance          -',FIXTOSTR(balance, WBOTH, 2));
	WRITELN;
END;

PROCEDURE kopy_balance;
æ hardcopy balance sheet to printer å
VAR item : 1..max_items;
    balance : FIXED;
    file_out : TEXT;
BEGIN
        FOR item := 1 TO max_codes DO
          code_amountÆitemÅ := STRTOFIX('0');
        balance := STRTOFIX('0');
	FOR item := 1 TO item_last-1 DO
	  WITH itemsÆitemÅ DO
	      code_amountÆcodeÅ := ADD(code_amountÆcodeÅ, amount);
	FOR item := 1 TO max_add_code DO
	  balance := ADD(balance, code_amountÆitemÅ);
	FOR item := max_add_code+1 TO max_codes DO
	  balance := SUB(balance, code_amountÆitemÅ);
	REWRITE('Lst:',file_out);
	WRITELN(file_out,CHR(12));
	WRITELN(file_out,'   Category               Amount');
	FOR item := 1 TO 32 DO
	  WRITE(file_out,'-');
	WRITELN(file_out);
	FOR item := 1 TO max_codes DO
	  IF code_amountÆitemÅ <>STRTOFIX('0') THEN	 
	   BEGIN
       	     WRITE(file_out,code_descriptionÆitemÅ,'  -');
	     WRITELN(file_out,FIXTOSTR(code_amountÆitemÅ,WBOTH, 2 ));
	   END;
	FOR item := 1 TO 32 DO
	  WRITE(file_out,'-');
	WRITELN(file_out);
	WRITELN(file_out,'Balance          -',FIXTOSTR(balance, WBOTH, 2));
	WRITELN(file_out);
END;

PROCEDURE remove;
æ remove item from file å
VAR remove : CHAR;
    found,item : INTEGER;
    item_remove : INTEGER;
BEGIN
	found :=0;
	WRITELN;
	WRITE(' Remove item number - ');
	READ(item_remove);
	FOR item := 1 TO item_last-1 DO
	  IF itemsÆitemÅ.item_number = item_remove THEN
	    found := item;
	WRITELN;
	IF found <> 0 THEN
	  BEGIN
	    heading;
	    item_print(found);
	    WRITELN;
	    WRITELN;
	    WRITE(' Remove ? ');
	    READ(remove);
	    IF (remove = 'Y') OR (remove = 'y') THEN
		BEGIN
		  FOR item := found TO item_last-1 DO
		    itemsÆitemÅ := itemsÆitem+1Å;
		  item_last := item_last-1;
		END;
	  END;
  IF found = 0 THEN
    WRITELN(' Item not in list.....');
END;

PROCEDURE entry;
æ console entry of check/deposit data å
VAR ch : CHAR;
    number : STRING 20;
BEGIN          
  REPEAT
    WITH itemsÆitem_lastÅ DO
	BEGIN
	  description := '                          ';
	  WRITELN;
	  WRITE(' Item number ? ');
	  READLN(item_number);
	  WRITE(' Month ? ');
	  READ(month);
	  WRITE(' Date ? ');
	  READ(day);
	  WRITE(' Amount ? ');
	  READ(number);
	  amount := STRTOFIX(number);
	  WRITELN('               _____________________________');
	  WRITE(' Description ? ');
	  READLN(description);
	  WHILE LENGTH(description) <> 30 DO
	    APPEND(description,' ');
	  WRITE(' Code ? ');
	  READ(code);
	  year := entry_year;
	  WRITELN;
       END;
  heading;
  item_print(item_last);
  WRITELN;
  WRITELN;
  WRITE(' Correct ? ');
  READ(ch);
  UNTIL (ch ='Y') OR (ch = 'y');
  itemsÆitem_last+1Å := itemsÆitem_lastÅ;
  itemsÆitem_last+1Å.item_number := 0;
  item_last := item_last+1;
  WRITELN;
END;

PROCEDURE modify;
æ modify a field in an item å
VAR found,item : INTEGER;
    number : STRING 20;
    name : STRING 30;
    item_modify : INTEGER;
    answer : CHAR;
    A,B,C,D,N,R : STRING 3;
BEGIN
  A:=CHR(27);
  B:=CHR(48);
  C:=CHR(64);
  APPEND(A,B);
  APPEND(A,C);
  N:=A;
  A:=CHR(27);
  B:=CHR(48);
  D:=CHR(80);
  APPEND(A,B);
  APPEND(A,D);
  R:=A;
  found := 0;
  WRITELN;
  WRITE(' Modify Item number - ');
  READ(item_modify);
  WRITELN;
  FOR item := 1 TO item_last-1 DO
   IF itemsÆitemÅ.item_number=item_modify THEN
     found := item;
  WRITELN;
  IF found<>0 THEN
    BEGIN
      heading;
      item_print(found);
      WRITELN;
      WRITE(R,'I',N,'tem # ');
      WRITE(R,'M',N,'onth ');
      WRITE(R,'D',N,'ate     ');
      WRITE(R,'A',N,'mount   ');
      WRITE(R,'N',N,'ame or description      ');
      WRITELN(R,'C',N,'ode');
      WRITELN;
      WRITELN(' Modify one of the above fields ');
      WRITE(' Enter letter of the field to be changed?- ');
      READ(answer);
      WRITELN;
      CASE answer OF
	'I','i':BEGIN
		  WRITE(' New item number- ');
                  READLN(itemsÆfoundÅ.item_number);
		  WRITELN;
		END;
	'M','m':BEGIN
		  WRITE(' New month- ');
                  READ(itemsÆfoundÅ.month);
		  WRITELN;
		END;
        'D','d':BEGIN
		  WRITE(' New day- ');
      		  READ(itemsÆfoundÅ.day);
		  WRITELN;
		END;
	'A','a':BEGIN
		  WRITE(' New amount- ');
 		  READ(number);
		  WRITELN;
		  itemsÆfoundÅ.amount:=STRTOFIX(number);
		END;
	'N','n':BEGIN
		  WRITE(' New name or description- ');
		  READLN(name);
		  WRITELN;
		  WHILE LENGTH(name)<>30 DO
		    APPEND(name,' ');
		  itemsÆfoundÅ.description:=name;
		END;
	'C','c':BEGIN
		  WRITE(' New code #- ');
		  READ(itemsÆfoundÅ.code);
		  WRITELN;
		END;
	END;
  END;
END;

PROCEDURE swap_items(item : INTEGER ; VAR swaped : BOOLEAN);
æ exchange file data at location with location+1 å
BEGIN
  itemsÆmax_itemsÅ := itemsÆitemÅ;
  itemsÆitemÅ := itemsÆitem+1Å;
  itemsÆitem+1Å := itemsÆmax_itemsÅ;
  swaped := TRUE
END;

PROCEDURE date_sort;
æ sort data file by date å
VAR finish , item : 0..max_items;
    date_first , date_second : REAL;
    item_first , item_second : INTEGER;
BEGIN
  finish := item_last-2;
  REPEAT
    swaped := FALSE;
    FOR item := 1 TO finish DO
	BEGIN
	  WITH itemsÆitemÅ DO
	   BEGIN
	     date_first := year * 10000.0 + month * 100.0 + day;
	     item_first := item_number;
	   END;
	  WITH itemsÆitem+1Å DO
	    BEGIN
	      date_second := year * 10000.0 + month * 100.0 + day;
	      item_second := item_number;
	    END;
	  IF date_first > date_second THEN
	    swap_items(item,swaped);
	  IF (date_first = date_second) AND (item_first > item_second) THEN
	    swap_items(item,swaped);
	END;
      IF finish > 2 THEN
        finish := finish -1;
  UNTIL NOT swaped
END;

PROCEDURE dump;
æ write file of item information to disk å
VAR count : INTEGER;
BEGIN
  RESET(disk_file, data_file);
  REWRITE(disk_file,data_file);
  FOR count := 1 TO item_last DO
    WRITE(data_file,itemsÆcountÅ);
END;

PROCEDURE read_disk;
æ load data from disk to file å
BEGIN
  WRITELN;
  RESET(disk_file,data_file);
  item_last := 1;
  REPEAT
    READ(data_file,itemsÆitem_lastÅ);
    WRITE('.');
    IF item_last MOD 10 = 0 THEN
      WRITELN;
    item_last := item_last + 1;
  UNTIL itemsÆitem_last-1Å.item_number = 0;
    item_last := item_last -1;
    WRITELN;
END;

PROCEDURE prog_commands;
æ console entry of program command å
BEGIN
    WRITELN;
    WRITE(' Command ? ');
    READ(command);
    CASE command OF
	'A','a' : entry;
	'B','b' : print_balance;
	'P','p' : print_all;
	'R','r' : remove;
	'S','s' : date_sort;
	'D','d' : dump;
	'L','l' : read_disk;
	'M','m' : modify;
	'H','h' : copy_all;
	'I','i' : print_instructions;
	'J','j' : kopy_balance;
	ELSE :
	IF (command = 'Q') OR (command ='q') THEN
	  WRITELN(' Leaving Program')
	ELSE
	  WRITELN(' Invalid command .....')
   END;
END;

æ Mainline Program å
BEGIN
    initialize;
    instructions;
    WRITELN;
    WRITE(' Enter year " 2-digit " for new entries - ');
    READ(entry_year);
    WRITELN;
    WRITELN;
    REPEAT
      prog_commands;
    UNTIL (command = 'q') OR (command = 'Q');
    WRITELN;
    WRITE(' Save file ? ');
    READ(answer);
    IF (answer ='Y') OR (answer = 'y') THEN
      dump;
END.
«eof»