Thread View: net.micro.mac
1 messages
1 total messages
Started by Stuart A. Kurtz
Mon, 18 Mar 1985 17:14
MacModula-2 bug fixes (Part I: program listing)
Author: Stuart A. Kurtz
Date: Mon, 18 Mar 1985 17:14
Date: Mon, 18 Mar 1985 17:14
281 lines
10130 bytes
10130 bytes
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.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads