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.