stuart@gargoyle.UChicago.UUCP (Stuart A. Kurtz) (03/18/85)
Modula Corporation recently released bug fixes for their MacModula-2 product. Performing the fix requires either typing in a 5 page Modula program and running it, or sending your Master disk (together with $3.00 and various customer information) to Modula Corp. In the interests of saving everyone some time and/or money, I'm posting the program (and the m-code .LOD file) to net.sources.mac. Modula Corporation recommends running this program on the work disk, and *NOT MODIFYING* your distributions disks. The program modifies both interpreter files (Modula-2 and Modula 2). Stuart Kurtz ihnp4!gargoyle!stuart Dept. of Computer Science stuart@uchicago.csnet University of Chicago P.S. This posting has the official blessing of Modula Corporation.
stuart@gargoyle.UChicago.UUCP (Stuart A. Kurtz) (03/18/85)
Here's the listing of the bug fix program for MacModula-2's interpreters.
The compiled (m-code) version is also being posted in BinHex4.0 form.
(It's difficult but possible to compile on a 128K Mac.)
Stuart Kurtz ihnp4!gargoyle!stuart
Dept. of Computer Science stuart@uchicago.csnet
University of Chicago
------------------------------[cut here]------------------------------
(* This program patches a number of potential problems in MacModula-2...
1- Fixes a problem of the interpreter crashing at
exit on some systems on a 128K Mac.
2- Fixes SystemEvent trap.
3- Fisex GetNamedResource trap.
4- Fixes local variable problem in NewProcess
*)
MODULE Patch;
FROM InOut IMPORT ClearScreen, WriteString, ReadString, WriteLn,
WriteCard, Read, WriteInt, Write;
FROM ResourceManager IMPORT SizeResource, OpenResFile, GetResource,
ChangedResource, CloseResFile, ResError;
FROM Strings IMPORT StrModToMac;
FROM MacSystemTypes IMPORT Str255, Handle;
FROM MemoryManager IMPORT HNoPurge, HPurge;
CONST
Same = 11; (* Number of similiar patch bytes for both *)
bigCnt = 5; (* Number of patch bytes for Modula-2 *)
smallCnt = 6; (* Number of patch bytes for Modula 2 *)
Max = Same + bigCnt + smallCnt;
GrandSum = 8587; (* Total vertical checksum *)
TYPE
patchRec = RECORD
where : CARDINAL; (* Byte location of byte to be
* changed *)
bad : CARDINAL; (* Original value *)
good : CARDINAL; (* New value to replace original
* value *)
chksum: CARDINAL;
END;
buffer = POINTER TO ARRAY [0..32767] OF CHAR;
bufhdl = POINTER TO buffer;
VAR
Data : ARRAY [1..Max] OF patchRec;
RsrcHdl1, RsrcHdl2 : bufhdl;
res1, res2 : INTEGER;
ch : CHAR;
PROCEDURE ChangeByte(Hdl : bufhdl; i : CARDINAL);
VAR where : CARDINAL;
BEGIN
WITH Data[i] DO
IF CHAR(bad) # Hdl^^[where] THEN (* Verify old byte is bad *)
IF CHAR(good) = Hdl^^[where] THEN (* Byte must be already changed *)
WriteString('Patch #'); WriteCard(i,0);
WriteString(' has already been patched!'); WriteLn;
ELSE
WriteString('Patch #'); WriteCard(i,0);
WriteString(' has wrong byte! File must be corrupt!');
WriteLn;
Error;
END;
END;
Hdl^^[where] := CHAR(good); (* Change byte in resource *)
END;
END ChangeByte;
PROCEDURE OpenResourceFiles;
VAR macstr : Str255;
BEGIN
StrModToMac(macstr,'Modula-2');
res1 := OpenResFile(macstr); (* Open resource fork of Modula-2 *)
IF res1 = -1 THEN
WriteString('Could not open resource: Modula-2');
WriteLn;
Error;
END;
CheckError;
RsrcHdl1 := GetResource('CODE',1); (* Get the machine code *)
IF RsrcHdl1 = NIL THEN
WriteString('Cannot read code resource for Modula-2');
WriteLn;
Error;
END;
CheckError;
HNoPurge(Handle(RsrcHdl1)); (* Lock our resource into memory *)
StrModToMac(macstr,'Modula 2');
res2 := OpenResFile(macstr); (* Open resource fork of Modula 2 *)
IF res2 = -1 THEN
WriteString('Could not open resource: Modula 2');
WriteLn;
Error;
END;
CheckError;
RsrcHdl2 := GetResource('CODE',1); (* Get the machine code *)
IF RsrcHdl2 = NIL THEN
WriteString('Cannot read code resource for Modula 2');
WriteLn;
Error;
END;
CheckError;
HNoPurge(Handle(RsrcHdl2)); (* Lock our resource into memory *)
END OpenResourceFiles;
PROCEDURE FixBigInterp;
VAR i : CARDINAL;
BEGIN
FOR i := 1 TO Same DO (* Change the similiar bytes *)
ChangeByte(RsrcHdl1,i);
END;
FOR i := Same TO Same + bigCnt DO (* Change the unique bytes *)
ChangeByte(RsrcHdl1,i);
END;
WriteString('Changing resource'); WriteLn;
ChangedResource(Handle(RsrcHdl1)); (* Flag the resource as changed *)
CheckError;
HPurge(Handle(RsrcHdl1)); (* Let the resource be purged *)
END FixBigInterp;
PROCEDURE CheckError;
VAR err: INTEGER;
BEGIN
err := ResError();
IF err # 0 THEN
WriteString('error = ');
WriteInt(err,0); WriteLn;
Error;
END;
END CheckError;
PROCEDURE FixSmallInterp;
VAR i : CARDINAL;
BEGIN
FOR i := 1 TO Same DO (* Change the similiar bytes *)
ChangeByte(RsrcHdl2,i);
END;
FOR i := Same + bigCnt + 1 TO Same + bigCnt + smallCnt DO
ChangeByte(RsrcHdl2,i);
END;
WriteString('Changing resource'); WriteLn;
ChangedResource(Handle(RsrcHdl2)); (* Flag the resource as changed *)
CheckError;
HPurge(Handle(RsrcHdl2)); (* Let the resource be purged *)
END FixSmallInterp;
PROCEDURE Error;
VAR ch : CHAR;
BEGIN
WriteString('Hit any key to Halt...(Files will probably not be updated)');
Read(ch);
HALT;
END Error;
PROCEDURE CheckData; (* Verify that the data has been entered correctly *)
VAR i, calcSum : CARDINAL;
BEGIN
WriteString('Checking data...'); WriteLn;
calcSum := 0;
FOR i := 1 TO Max DO
WITH Data[i] DO
IF where + bad + good # chksum THEN
WriteString('Inconsistant data in array element: ');
WriteCard(i,0); WriteLn;
WriteString('Check the data initialization section carefully!');
WriteLn;
Error;
END;
(* Perform an XOR checksum *)
calcSum := CARDINAL(BITSET(calcSum) / BITSET(chksum));
END;
END;
IF calcSum # GrandSum THEN
WriteString('Total checksum (');
WriteCard(calcSum,0);
WriteString(') does not equal correct amount(');
WriteCard(GrandSum,0);
WriteString(').');
WriteLn;
Error;
ELSE
WriteString('Data is OK -- Patching can proceed.'); WriteLn;
END;
END CheckData;
BEGIN
ClearScreen;
(* Data Initialization Section *)
Data[1].where := 3358; Data[1].bad := 32;
Data[1].good := 103; Data[1].chksum := 3493;
Data[2].where := 3359; Data[2].bad := 68;
Data[2].good := 26; Data[2].chksum := 3453;
Data[3].where := 3361; Data[3].bad := 104;
Data[3].good := 68; Data[3].chksum := 3533;
Data[4].where := 3362; Data[4].bad := 0;
Data[4].good := 32; Data[4].chksum := 3394;
Data[5].where := 3363; Data[5].bad := 118;
Data[5].good := 104; Data[5].chksum := 3585;
Data[6].where := 3364; Data[6].bad := 50;
Data[6].good := 0; Data[6].chksum := 3414;
Data[7].where := 3365; Data[7].bad := 40;
Data[7].good := 118; Data[7].chksum := 3523;
Data[8].where := 3366; Data[8].bad := 0;
Data[8].good := 50; Data[8].chksum := 3416;
Data[9].where := 3367; Data[9].bad := 8;
Data[9].good := 40; Data[9].chksum := 3415;
Data[10].where := 3368; Data[10].bad := 66;
Data[10].good := 0; Data[10].chksum := 3434;
Data[11].where := 3369; Data[11].bad := 130;
Data[11].good := 8; Data[11].chksum := 3507;
Data[12].where := 8608; Data[12].bad := 32;
Data[12].good := 34; Data[12].chksum := 8674;
Data[13].where := 8613; Data[13].bad := 16;
Data[13].good := 17; Data[13].chksum := 8646;
Data[14].where := 10611; Data[14].bad := 194;
Data[14].good := 178; Data[14].chksum := 10983;
Data[15].where := 15881; Data[15].bad := 2;
Data[15].good := 3; Data[15].chksum := 15886;
Data[16].where := 4279; Data[16].bad := 38;
Data[16].good := 40; Data[16].chksum := 4357;
Data[17].where := 3370; Data[17].bad := 52;
Data[17].good := 36; Data[17].chksum := 3458;
Data[18].where := 4558; Data[18].bad := 34;
Data[18].good := 50; Data[18].chksum := 4642;
Data[19].where := 4602; Data[19].bad := 34;
Data[19].good := 50; Data[19].chksum := 4686;
Data[20].where := 4646; Data[20].bad := 34;
Data[20].good := 50; Data[20].chksum := 4730;
Data[21].where := 7426; Data[21].bad := 49;
Data[21].good := 33; Data[21].chksum := 7508;
Data[22].where := 10385; Data[22].bad := 2;
Data[22].good := 3; Data[22].chksum := 10390;
CheckData;
OpenResourceFiles;
WriteString('Patch Modula-2? ');
Read(ch); Write(ch); WriteLn;
IF CAP(ch) = 'Y' THEN
FixBigInterp;
END;
WriteString('Patch Modula 2? ');
Read(ch); Write(ch); WriteLn;
IF CAP(ch) = 'Y' THEN
FixSmallInterp;
END;
WriteString('Patching has been completed successfully!');
WriteLn;
WriteString('Hit any key to halt...');
Read(ch);
HALT; (* Note: Program is intended to terminate with HALT *)
END Patch.