https://tinkerdifferent.com/threads/patching-68k-software-simpletext.4793/ TinkerDifferent TinkerDifferent * Home * Forums New posts Search forums * What's new New posts New resources New profile posts Latest activity * Resources Latest reviews Search resources * Donate Log in Register [ ] Search [ ] [Everywhere ] [ ]Search titles only By: [ ] Search Advanced search... [Everywhere ] [ ]Search titles only By: [ ] Search Advanced... * New posts * Search forums Menu Install the app Install Assembly Patching 68K software - SimpleText * Thread starter David Cook * Start date Yesterday at 5:50 PM * Home * Forums * Vintage Apple * Software & Operating Systems * Software | Development JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding. You are using an out of date browser. It may not display this or other websites correctly. You should upgrade or use an alternative browser. Relating to assembly on 68k or PPC David Cook David Cook Tinkerer Jul 20, 2023 97 124 33 * Yesterday at 5:50 PM * * #1 Someone asked to have SimpleText open a smaller text window at startup. Initially, I assumed this would be a fairly easy fix by just overwriting a few constant values in SimpleText code. It turned out to be a pain -- but I learned a lot along the way. You need to have the code editor (from one of the Apple developer CDs) in your ResEdit preference file in order to disassemble code resources within ResEdit. Then, open each 'CODE' resource of SimpleText and search for _SizeWindow (A91D). Or, just skim the code until you see system calls that look like they have something to do with windows. Here is a nice chunk in routine Anon48. A new window is created, then it looks at the main device, looks at the size of the menu bar (MBarHeight), sets the port, and moves and sizes the window. 1762274763843.png But, uh oh, earlier in the code it checks what type of window it is opening. A patch is going to need to avoid resizing code for pictures, video, and the about box. 1762274975174.png I could not locate any obvious constants to adjust. Instead, I would need to inject a more complicated routine that detects whether it was a text window and substitute a new rectangle for the size. But, you cannot simply insert code, as it would move all subsequent code down, and the jumps (subroutine calls) that cross over that location would now jump to the wrong spots. So, I need to jump out of their code to my own (appended at the end of the code resource) and return. For example, SimpleText's code to get the size of MBarHeight can easily be performed elsewhere. My routine need only return the MBarHeight in register D0 before returning. That gives me 8 bytes to overwrite with my jump. 1762275571578.png Here is my replacement code. It still is only 8 bytes. But, I now jump to my subroutine, check the result, and jump over their resizing code if my routine says it is changing the window size. 1762275874018.png In my subroutine, I make sure all the needed information is in registers (which I checked that SimpleText was not using), I call my various functions and then perform any work that was lost from overwriting or jumping over the original code. Specifically, I get the MBarHeight into D0 and set the current port to the window. 1762276068873.png Easy! But, later in the code, SimpleText reads the content of whatever document is being opened and once again resizes the window. So, I needed to patch later code as well. How could I determine at that point that a replacement window size was being used? I simply store the result of the first subroutine (see SetRecentResult above) and then check it on later calls. Where could I store this information? it is not possible to add global variables and the registers are all reused by SimpleText between the first and second routines. Well, you can store a variable (or an entire structure with many variables) within the code itself. Here is my little workaround for CodeWarrior. 1762276820212.png A couple of other tricks. 1. The system routine GetHandleSize has some glue code (they intercept the call in a local library before calling the system). I needed this call, but didn't want to add the weight of CodeWarrior's libary. So, I defined the direct call to GetHandleSize (I didn't need the glue fix). 1762277354659.png 2. You can pass any of the scratch registers (D0-D2, A0-A1, FP0-FP3) to a C function. The way of defining that in CodeWarrior is noted below. You cannot use any other registers. To make debugging easier, I wrote the original subroutine as a true C function, and the register->C function as a wrapper. 1762277419369.png 3. CodeWarrior does not support BSR for some reason. Use JSR instead. Also, a called routine must be placed before the caller routine in order to generate a short relative JSR rather than absolute address. See my 'RecentResult' example above, where the routines that call RecentResult are placed after it in code. 4. SimpleText stores literals (strings, constants) at the end of the 'CODE' resource. After that is where I placed my code. Unfortunately, this breaks disassembly in ResEdit. Below, do you see 'A9FF'? That's the '_Debugger' trap call. It is follow by the rest of the code, and the MacsBug symbols for "SimpleTextWindowChoicePrep' 1762277836489.png I then needed to hand compute the JSR patched in the original SimpleText code to this location at the end of the code resource. 5. To make it easy to redefine window sizes in the future, I added a resource. 1762278013427.png The ResEdit definition of this resource is the TMPL. By the way, I have experienced corruption twice with ResEdit 2.1.3. Perhaps it has a bug with templates? 1762278055592.png I doubt this information will be useful to most people. However, it may help avoid some frustrating issues for those few people that attempt patching old software. Attached is the hacked version of SimpleText. - David Attachments * 1762277048181.png 1762277048181.png 3.2 KB * Views: 53 * SimpleText UserWindow.hqx 146.6 KB * Views: 25 * Like * Love Reactions: Stephen, eric, Scorpio_ny and 4 others thecloud thecloud New Tinkerer Oct 2, 2025 6 2 3 * Today at 12:42 AM * * #2 Instead of declaring a variable in the middle of your code and then having to branch over it to the RTS, can't you just put the RTS ahead of it? Code: { lea recentResult,a1 rts recentResult: dc.w 0x4e71 } David Cook David Cook Tinkerer Jul 20, 2023 97 124 33 * Today at 1:08 AM * * #3 thecloud said: Instead of declaring a variable in the middle of your code and then having to branch over it to the RTS, can't you just put the RTS ahead of it? Code: { lea recentResult,a1 rts recentResult: dc.w 0x4e71 } Click to expand... Great question! Doing so would prevent MacsBug from recognizing the name of the function during debugging. It expects a name immediately after the rts. You must log in or register to reply here. Share: Facebook Twitter Reddit Pinterest Tumblr WhatsApp Email Share Link * Home * Forums * Vintage Apple * Software & Operating Systems * Software | Development About us * Launched in 2021, Tinker Different is the result of a group of vintage tech enthusiasts and tinkerers coming together to form a new online community. Our forum provides unbiased, critical discussion among people of all different interests and backgrounds. We are also working every day to make sure our community is one of the best. Quick Navigation Home Forums Contact us User Menu Login * * Dark mode * Contact us * Privacy policy * Help * Home * * RSS Community platform by XenForo^(r) (c) 2010-2021 XenForo Ltd. Top Bottom * Cookies help personalize content and keep you logged in if you register. By using this site, you are consenting to our use of cookies. Accept Learn more... [ ]