MODULE VARIO; {by Ed Reed Tailored Computer Solutions 1919 S. Newport Kennewick, WA 99336 } {This module was written for Release 5.2 to write variable-length records to a random access file. Of course, one file may have only one length record in it; the usefulness of the module coming from the fact that the length of the records can be changed by parameters for a variety of files without recompiling the program.} CONST MAXLEN = $345; {$345 was chosen because it is easy to find in an assembly language listing. Pick a value that is as large as the largest record expected for the application program.} TYPE VREC = RECORD VAREC : ARRAY [1 .. MAXLEN] OF CHAR END; VFILE = FILE OF VREC; MTYPE = (MBYTE, MINT); MULT = RECORD {Structure to convert one integer to two bytes.} CASE MTYPE OF MBYTE : (B2, B1 : BYTE); MINT : (MLEN : INTEGER) END; PROCEDURE VARESET (LEN : INTEGER); {This procedure sets the value of the record length. If only one file is being accessed, it can be called once before any I/O is done. If several variable files are being accessed, it can be called before every I/O operation.} TYPE INSTR = ARRAY [1 .. 150] OF BYTE; {Program space for VARIO_I and VARIO_O.} VAR CODE : ^INSTR; CJ, CK : CHAR; II, I, J, K : INTEGER; MULTS : MULT; BEGIN WRITELN (LEN); CODE := ADDR (VARIO_I); {Debugging output.} FOR II := 0 TO 14 DO BEGIN WRITELN; FOR I := 1 TO 10 DO BEGIN J := CODE^[II * 10 + I]; K := J DIV 16; J := J MOD 16; IF K < 10 THEN CK := CHR (K + 48) ELSE CK := CHR (K + 55); IF J < 10 THEN CJ := CHR (J + 48) ELSE CJ := CHR (J + 55); WRITE (' ', CK, CJ) END END; WRITELN; {Replacement of compiled length with desired length.} MULTS.MLEN := LEN; CODE^[ 24] := MULTS.B1; CODE^[ 25] := MULTS.B2; CODE^[ 50] := MULTS.B1; CODE^[ 51] := MULTS.B2; CODE^[ 70] := MULTS.B1; CODE^[ 71] := MULTS.B2; CODE^[ 99] := MULTS.B1; CODE^[100] := MULTS.B2; CODE^[110] := MULTS.B1; CODE^[111] := MULTS.B2; {Note that MT MicroSYSTEMS is NOT under any obligation to generate the same assembly code from PASCAL code in any future revision of PASCAL MT+. One can also expect that different versions of PASCAL MT+ for different machines will also give differing results. To find where the record length is stored in I/O instructions, pick an easy-to-find record length, compile it with the debugging output enabled, and take a look. It may also be of help to compile with the X option and look at the assembly code generated using MT's disassembler. If the program croaks or spits garbage, guess again. This version runs on a 64K Z80-based EXO Nobus-Z.} {More debugging output. WRITELN (LEN:8, MULTS.MLEN:8); FOR II := 0 TO 14 DO BEGIN WRITELN; FOR I := 1 TO 10 DO BEGIN J := CODE^[II * 10 + I]; K := J DIV 16; J := J MOD 16; IF K < 10 THEN CK := CHR (K + 48) ELSE CK := CHR (K + 55); IF J < 10 THEN CJ := CHR (J + 48) ELSE CJ := CHR (J + 55); WRITE (' ', CK, CJ) END END END; PROCEDURE VARIO_I (VAR INFIL : VFILE; VAR INREC : VREC; RECNUM :INTEGER); {Input procedure.} BEGIN SEEKREAD (INFIL, RECNUM); INREC := INFIL^ END; PROCEDURE VARIO_O (VAR OUTFIL : VFILE; OUTREC : VREC; RECNUM :INTEGER); {Output procedure.} BEGIN OUTFIL^ := OUTREC; SEEKWRITE (OUTFIL, RECNUM) END; MODEND.