opcode source, destination
which is the other way around from most contemporary ISA:s. So a line like move.l d0, -(a7)
will first decrement the value of register a7, then write the contents of register d0 to the resulting address (it's a "push" for a downwards-growing stack).Edit: added Wiki-linkage.
[1]: https://en.wikipedia.org/wiki/Motorola_68000#Instruction_set...
My recent pet peeve is that macOS doesn't seem to remember window sizes and locations properly. Things are certainly complicated by multi-monitor setups, but it seems like some sensible default behavior could be implemented.
I don't dislike the column browser, but I wish macOS would preserve/revive its spatial UI in both the Finder and document window positions.
Android is also about to lock down "sideloading", another "great" dysphemism for "installing software".
Moving the Overton window on this has been so successful, that even people in our industry happily accepted the much maligned dysphemisms of "jailbreaking" and "rooting" for what used to be called "local admin rights" and look upon such access as if it's only something pirates, criminals or malware spreaders would want to do.
I say this as someone who is running an Android phone with a kernel with some backported patches applied and compiled by myself. The fact that I can do it is great. The fact that the entire industry is trying to make it as frustrating as possible for me to do this under the guise of false premises such as "security" is disheartening.
POKE 35136, 0
thus it ever was.
Stepping through, line by line, editing the code and adding JMPs to get around the copy protection code after loading the magic numbers into the register...
Happy, happy times.
In some ways, the world has moved on as well. Spatial orientation worked really well when the number of files and folders we typically dealt with was fairly small in number. Now we tend to deal with huge numbers of files, most of which aren't even on our local computer. It's hard for me to imagine how a spatial system like that could be made to work with all of that. What would a "spatial Wikipedia" look like?
Obviously this is nothing on things like V-MAX! and Rapidlok which even nowadays have variations that are tough to remaster.
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.
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.
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.
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.
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.
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.
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).
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.
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'
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.
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?
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