🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Stuart A. Kurtz Mon, 18 Mar 1985 17:14
MacModula-2 bug fixes (Part I: program listing)
#855
Author: Stuart A. Kurtz
Date: Mon, 18 Mar 1985 17:14
281 lines
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