Mac OS 9 Lives
Mac OS 9 Discussion => Mac OS 9, Hacks & Upgrades => Topic started by: ELN on September 18, 2017, 04:54:49 AM
-
Hi all,
I have made some good progress reversing the Mac OS ROM in recent months, about which I will soon be posting. To get all that development done on a heterogeneous network, I have needed to put some tools in place. Since they make working on Mac OS 9 in this century so much easier, I thought I'd share.
This is how I set up my "MacSrc" Debian 8 VM to serve the same source tree to both my Mac OS 9 and Linux desktops.
Problem 1: case sensitivity
My source code sloppily expects a case insensitive filesystem like HFS, which Linux is reluctant to provide. Use vfat, Linux's long-filename FAT driver. Never mind that it has no permissions support -- just have it owned by your Netatalk guest user. (I use "mpw", UID/GID 1001.)
apt install dosfstools
# (Finding some actual storage space for your FS is an exercise
# left to the reader. I suggest gobbling an entire virtual disk.)
mkfs.vfat /dev/sdb
echo '/dev/sdb /MacSrc vfat uid=1001,gid=1001 0 0' >> /etc/fstab
mkdir /MacSrc && mount /MacSrc
Problem 2: Netatalk
With the release of Netatalk 3, version 2 has been deprecated. But Netatalk 2.1.6 is the last version that works correctly with MPW. Newer versions cause MPW to save files with incorrect names, which of course is unacceptable on a dev system. Attached to this post is a compiled source tree for that Netatalk version on Debian 8, ready to be installed straight away.
tar xf netatalk-2.1.6-built.tar.gz && cd netatalk-2.1.6 && make install
# Lines to change in /etc/default/netatalk
AFPD_UAMLIST="-U uams_guest.so"
AFPD_GUEST=mpw
ATALKD_RUN=no
PAPD_RUN=no
TIMELORD_RUN=no
A2BOOT_RUN=no
CNID_METAD_RUN=yes
AFPD_RUN=yes
# Append to /usr/local/etc/netatalk/AppleVolumes.default
# (deleting the existing "~" line)
/MacSrc MacSrc options:caseinsensitive
Problem 3: git
We use git to manage the CDG5 repository. While git can deal with any binary file, its build-in diff utility chokes on old-style Mac line endings. This Python FUSE module provides git with a sane view of your Mac source tree while trying very hard not to mangle binary files.
apt install fuse libfuse2 python3-pip
pip3 install fusepy
#!/usr/bin/env python3
# It is best to run this FUSE module as your "mpw" user, to avoid permissions problems.
from __future__ import with_statement
import os
import sys
import errno
from fuse import FUSE, FuseOSError, Operations
class FSCiv(Operations):
def __init__(self, root):
self.root = root
# Constants
# =========
MUNGE_ON = 1
MUNGE_PROTECT = 0
MUNGE_HIDE = -1
# Helpers
# =======
def _full_path(self, partial):
if partial.startswith("/"):
partial = partial[1:]
path = os.path.join(self.root, partial)
return path
def _munge_mode(self, partpath):
split = [x for x in partpath.split('/') if x]
if any(x in split for x in ['.git', 'BuildResults']):
return self.MUNGE_PROTECT
if split and any(split[-1].endswith(x) for x in ['.o','.lib','.sit']):
return self.MUNGE_PROTECT
if '.gitignore' in split:
return self.MUNGE_ON
if any(x.startswith('.') and x not in '..' for x in split):
return self.MUNGE_HIDE
if any(x in split for x in ['Network Trash Folder', 'Temporary Items', 'TheVolumeSettingsFolder']):
return self.MUNGE_HIDE
return self.MUNGE_ON
# Filesystem methods
# ==================
def access(self, path, mode):
munge_mode = self._munge_mode(path)
if munge_mode == self.MUNGE_HIDE:
raise FuseOSError(errno.EACCES)
full_path = self._full_path(path)
if not os.access(full_path, mode):
raise FuseOSError(errno.EACCES)
def chmod(self, path, mode):
full_path = self._full_path(path)
return os.chmod(full_path, mode)
def chown(self, path, uid, gid):
full_path = self._full_path(path)
return os.chown(full_path, uid, gid)
def getattr(self, path, fh=None):
full_path = self._full_path(path)
st = os.lstat(full_path)
return dict((key, getattr(st, key)) for key in ('st_atime', 'st_ctime',
'st_gid', 'st_mode', 'st_mtime', 'st_nlink', 'st_size', 'st_uid'))
def readdir(self, path, fh):
full_path = self._full_path(path)
yield from ['.', '..']
for list_name in os.listdir(full_path):
my_child_path = os.path.join(path, list_name)
if self._munge_mode(my_child_path) != self.MUNGE_HIDE:
yield list_name
def readlink(self, path):
pathname = os.readlink(self._full_path(path))
if pathname.startswith("/"):
# Path name is absolute, sanitize it.
return os.path.relpath(pathname, self.root)
else:
return pathname
def mknod(self, path, mode, dev):
return os.mknod(self._full_path(path), mode, dev)
def rmdir(self, path):
full_path = self._full_path(path)
return os.rmdir(full_path)
def mkdir(self, path, mode):
return os.mkdir(self._full_path(path), mode)
def statfs(self, path):
full_path = self._full_path(path)
stv = os.statvfs(full_path)
return dict((key, getattr(stv, key)) for key in ('f_bavail', 'f_bfree',
'f_blocks', 'f_bsize', 'f_favail', 'f_ffree', 'f_files', 'f_flag',
'f_frsize', 'f_namemax'))
def unlink(self, path):
return os.unlink(self._full_path(path))
def symlink(self, name, target):
return os.symlink(target, self._full_path(name))
def rename(self, old, new):
return os.rename(self._full_path(old), self._full_path(new))
def link(self, target, name):
return os.link(self._full_path(name), self._full_path(target))
def utimens(self, path, times=None):
return os.utime(self._full_path(path), times)
# File methods
# ============
def open(self, path, flags):
full_path = self._full_path(path)
return os.open(full_path, flags)
def create(self, path, mode, fi=None):
full_path = self._full_path(path)
return os.open(full_path, os.O_WRONLY | os.O_CREAT, mode)
def read(self, path, length, offset, fh):
os.lseek(fh, offset, os.SEEK_SET)
buf = os.read(fh, length)
if self._munge_mode(path) == self.MUNGE_ON:
buf = buf.replace(b'\r', b'\n')
return buf
def write(self, path, buf, offset, fh):
os.lseek(fh, offset, os.SEEK_SET)
if self._munge_mode(path) == self.MUNGE_ON:
buf = buf.replace(b'\n', b'\r')
return os.write(fh, buf)
def truncate(self, path, length, fh=None):
full_path = self._full_path(path)
with open(full_path, 'r+') as f:
f.truncate(length)
def flush(self, path, fh):
return os.fsync(fh)
def release(self, path, fh):
return os.close(fh)
def fsync(self, path, fdatasync, fh):
return self.flush(path, fh)
def main(mountpoint, root):
FUSE(FSCiv(root), mountpoint, nothreads=True, foreground=True)
if __name__ == '__main__':
main(sys.argv[2], sys.argv[1])
-
Oops! Here is the compiled Netatalk tarball.
-
netatalk/AFP filesharing is a godsend for seamlessly bridging the gap between the vintage Mac OS and the modern world,
are many mac user musicians linux proficient?
arent there simpler pre-configured solutions ?
-
While git can deal with any binary file, its build-in diff utility chokes on old-style Mac line endings.
And this right here is a big problem and one of the many reasons GIT is such a terrible solution for anything. It's just text characters. There is absolutely no reason a text processing tool should have any issue handling that. Displaying I may accept, but a tool for comparing text should not.
If a files encoding of line endings changes, then it's just character changes and it should be noted. Those changes can cause problems with other tools that are not meant to be cross platform and are reasonable in expecting a specific encoding type.
-
netatalk v3.1+ should work fine from what i understand so far, im curious what evidence do u have that supports your theory that v2.16 is the last compatible version?
i used v3.1+ for virtually all application and it always works fine.. 100% of the time,
and even if there was a bug, is it not easily circumvented by saving locally + then simply dragging files manually to do backups to a remote network share
googling on my own here for answers re: 2.1.6
found this post: http://macos9lives.com/smforum/index.php/topic,780.msg4294.html#msg4294
where user Mat linked this page: http://www.applefool.com/se30/
heres a quote:
The Netatalk stack must be installed from source because using sudo apt-get install netatalk will not set the --enable-ddp flag which is required for systems not using AFP over TCP/IP, however this depends on the repository. Some will have it already enabled, but it isn't very hard to compile from source anyways. Netatalk 3.x dropped AppleTalk support (DDP) and will not work entirely in this manner of this section. The Netatalk service is a server only and cannot access any other AFP servers as a client. Specifically, Netatalk 3.x is designed for OS X 10.4+, not for older Mac clients and includes OS X specific features such as Time Machine support.
so are u using an old mac SE/30? or Quadra? it looks like this is a non issue for compatiblity to any PCI power macintosh or g3/g4 which all use AFP over TCP/IP, are u actually using appletalk over localtalk serial connection?? :)
-
Nothing too ancient -- I use an MDD G4 for my Mac OS ROM builds. When saving a file to a Netatalk 2.1.7+ volume, MPW appends a number to the name (this number increments every time a file is saved). Then when the same MPW document is written out again, it pops up an error. Absolutely unacceptable on a development machine. I identified 2.1.6 as the last working Netatalk version by bisection.
I should note that one MPW tool (MrC, Apple's PowerPC C compiler) creates files on a a Netatalk volume with a zero (1994) creation date. I work around this problem by putting my BuildResults folders on a local disk.
-
By the way, my configure options were:
--enable-debian --disable-ddp --without-cnid-cdp-backend --without-cnid-last-backend --without-cnid-tdb-backend --without-shadow
-
Are you using GIT from mac os 9? I'm using cvs for revision control. It's .... cvs. It still sucks after all these years :/
I've been trying really hard to like MPW, but I find it awful. Maybe I am doing something wrong? Any pointers?
I'm going to check out netatalk on freebsd. I know a lot of people like Linux, but I found that the PPTP server refuses to work with anything I found that runs on OS 9, so I main FreeBSD. I did purchase a NAS unrelated to my work, synology 214j, and I have no problem with the appletalk on it. I also use the ftp server with no problems.
-
I've been trying really hard to like MPW, but I find it awful. Maybe I am doing something wrong? Any pointers?
It's a different beast than modern IDE's. It's got a pretty steep learning curve as well. We all like different things. I won't try to convince you. I personally don't like CodeWarrior and prefer MPW on OS 9. What's the problems you have that make you not like it?
I'm going to check out netatalk on freebsd. I know a lot of people like Linux, but I found that the PPTP server refuses to work with anything I found that runs on OS 9, so I main FreeBSD. I did purchase a NAS unrelated to my work, synology 214j, and I have no problem with the appletalk on it. I also use the ftp server with no problems.
I prefer to just run a Mac OS 9 server for file sharing. Most accurate implementation. I hate GIT so it's not really an issue for me.
For source control I use the stuff built into MPW, except at work where I'm stuck using Visual Source Safe (blah) or Team Foundation Server, which I actually like.
-
It's a different beast than modern IDE's. It's got a pretty steep learning curve as well. We all like different things. I won't try to convince you. I personally don't like CodeWarrior and prefer MPW on OS 9. What's the problems you have that make you not like it?
I guess I don't really understand it as a whole. I'll explain how I am treating/using it.
I open it up, it feels like a console window in *nix.
I type and can move between lines, so it behaves like vi or emacs in that sense.
I make what I feel like should be a shell script for compiling code. Nothing does what I want.
I download some sample projects, I managed to get one to compile, ever.
I'm assuming my brain is just broken and I've got a disconnect. I'd like to be able to build an older version of gcc to cross compile some stuff. I see gcc can be built with MPW, but I cannot figure out what to do or where to start.
Codewarrior is clumsy compared to modern IDEs. I often get annoyed with the fact I cannot hit delete and remove a file from a project. I still haven't figured out how to add in additional -D's to something so I can conditionally compile code.
I prefer to just run a Mac OS 9 server for file sharing. Most accurate implementation. I hate GIT so it's not really an issue for me.
For source control I use the stuff built into MPW, except at work where I'm stuck using Visual Source Safe (blah) or Team Foundation Server, which I actually like.
I'd like a machine that I could just leave on all the time running mac os 9 as a server, but not sure what to get.
I hate GIT as well :) I use it for storing code as GOGS has a decent web front end.
Visual Source Safe for windows or mac? Windows is such a turd. We have code in that. I also do not like TFS.
https://gogs.io if you are interested in gogs. I run it in a docker on a pi zero. Only problem I've seen with it so far is attempting to initial check in projects remotely that are _HUGE_ (400+Megs) as the docker pi is hiding behind another pi running freebsd and apache reverse proxy and the pi zero does 100% of communications via the USB OTG as a nic (which is sweet, but slow). I do the initial check in of huge projects from the box itself.
-
It's a different beast than modern IDE's. It's got a pretty steep learning curve as well. We all like different things. I won't try to convince you. I personally don't like CodeWarrior and prefer MPW on OS 9. What's the problems you have that make you not like it?
I guess I don't really understand it as a whole. I'll explain how I am treating/using it.
I open it up, it feels like a console window in *nix.
I type and can move between lines, so it behaves like vi or emacs in that sense.
I make what I feel like should be a shell script for compiling code. Nothing does what I want.
I download some sample projects, I managed to get one to compile, ever.
I'm assuming my brain is just broken and I've got a disconnect. I'd like to be able to build an older version of gcc to cross compile some stuff. I see gcc can be built with MPW, but I cannot figure out what to do or where to start.
Codewarrior is clumsy compared to modern IDEs. I often get annoyed with the fact I cannot hit delete and remove a file from a project. I still haven't figured out how to add in additional -D's to something so I can conditionally compile code.
I prefer to just run a Mac OS 9 server for file sharing. Most accurate implementation. I hate GIT so it's not really an issue for me.
For source control I use the stuff built into MPW, except at work where I'm stuck using Visual Source Safe (blah) or Team Foundation Server, which I actually like.
I'd like a machine that I could just leave on all the time running mac os 9 as a server, but not sure what to get.
I hate GIT as well :) I use it for storing code as GOGS has a decent web front end.
Visual Source Safe for windows or mac? Windows is such a turd. We have code in that. I also do not like TFS.
https://gogs.io if you are interested in gogs. I run it in a docker on a pi zero. Only problem I've seen with it so far is attempting to initial check in projects remotely that are _HUGE_ (400+Megs) as the docker pi is hiding behind another pi running freebsd and apache reverse proxy and the pi zero does 100% of communications via the USB OTG as a nic (which is sweet, but slow). I do the initial check in of huge projects from the box itself.
Your issues with MPW are the exact parts that are really a steep learning curve. The opening screen is very confusing. It's a terminal with history in the most bizarre way. If there was a good ide that took the good parts of MPW and CodeWarrior and maybe even some stuff from eclipse (sorry if you like that, but I hate that thing) would be awesome.
Source Safe just on Windows. At work we are on windows and pretty much do only .net development with the occasional odd ball project such as dbase, paradox and even some reversing of weird code for embedded systems.
TFS is a pain to install and setup and get permissions right.
My server is a G4 400 MHZ server model. It works. It recovers nicely from a power outage. (Should really get a ups for that).
-
I'd love to see what source safe on Mac OS 9 was like. I saw that Metrowerks had it.
-
I guess I don't really understand it as a whole. I'll explain how I am treating/using it.
Nanopico actually wrangled me into using MPW for the second iteration of the CDG5 project. In the long run, it was a very good decision. Here's my take on the environment.
It's Unix. Commands (which can be scripts or compiled executables) are called by issuing a command line. Something like `Files -c 'MPS '` is pretty typical. It will list to the standard output all the files in your working directory that are created by MPW. The names of commands are more verbose than their Unix equivalents (`ls` for the foregoing example), and there is a more consistent convention for arguments (no --long-arguments, no -abcd to combine arguments). Shell variables exist (which can be exported to environment variables -- run `Set` to see a current list), but are recalled like {this}, not $this.
The key difference is in *how* you issue commands. A Unix terminal has a prompt line at the bottom, after which you can type, edit and enter one command line. But in an MPW document, you can a command from anywhere. The easiest way is to put your cursor on a line of text and hit Enter (or Cmd-Return, but not plain Return). The standard output of the command will be inserted into the document under the line. Or, if you want to run multiple lines or a small part of one line, select that text and use the same keystroke. Again, the standard output will be inserted below the command that you issued.
(Note that there's plenty of help available. Run `Help` to get started.)
One of the oddities of MPW, imposed by the MacOS memory and multitasking models, is that compiled commands ("Tools") cannot call each other, and therefore only one can run at a time. This is most obvious in the way that the Make tool works: `Make -f :Project.make :BuildResults:TheApp > :MakeOut ; :MakeOut`. Preventing nesting is annoying at first, but I found that it made me think more like a functional programmer. Each command I issued would answer a single question, and any side effects were clearly understood beforehand. And the extensive paper trail left in the form of auto-generated shell scripts made one particular large build system much easier to debug.
Every MPW instance opens your Worksheet file without a close box (in the MPW folder -- run `Echo "{Active}"` from the Worksheet for illustration). Being a persistent main shell, this should be kept short and tidy. Below is mine. I keep a block of commands for every project that I'm working on, each line containing a single task. (Use ; to delimit commands on a line if a task requires more than one).
# BUILD MAC OS ROM
SetDirectory MacSrc:Posterity:
:Make:Build RISC -src : -mo "-d BuildDir=Common:PosterityBuild:" Common:PosterityBuild:Image:RomMondo
Duplicate -y Common:PosterityBuild:Image:RomMondo MacSrc:CDG5:BuildResults:NewWorld:Image:
SetDirectory MacSrc:CDG5:
:Make:Build -f TbxiBetterScript TbxiPatchG4Version NKShowLog
Open -f MacSrc:CDG5:BuildResults:NewWorld:Image: "{SystemFolder}"
I'll close with my very favourite application of MPW's unique environment. This is the log file from Vectorize, a build tool missing from the leaked "System 7.1" sources. While reimplementing Vectorize I wrestled with all sorts of subtleties in the Apple sources and object formats, requiring me to examine the resultant 1MB binary closely after each run. This I achieved by producing log files that doubled as MPW worksheets, full of useful commands to dump and browse the output objects. But because the log itself ran to 10k lines, I also had to insert commands into the log file that would move the cursor and navigate through the file itself.
# # ####### ##### ####### ####### ###### ### ####### #######
# # # # # # # # # # # # #
# # # # # # # # # # # #
# # ##### # # # # ###### # # #####
# # # # # # # # # # # #
# # # # # # # # # # # # #
# ####### ##### # ####### # # ### ####### #######
# This log file is formatted as an MPW worksheet, to help you troubleshoot
# your build.
# (Fake)Vectorize attempts to replace a lost Apple build tool. It is mostly
# based on patent US5546586, "Method and apparatus for vectorizing the contents
# of a read only memory device without modifying underlying source code".
# Dump the input file containing "vector patches":
Set PatchDump "{TempFolder}VectorPatchDump"; DumpObj ":BuildResults:RISC:Obj:VectorTablePatch.a.o" > "{PatchDump}"
# and navigate its contents:
Find /NAVIGATE PATCHES/ "{Active}"
# Dump the "vectorized" output file: (takes a while)
Set RomDump "{TempFolder}VectorRomDump"; DumpObj ":BuildResults:RISC:Lib:MainCode.Lib" > "{RomDump}"
# and look at it:
File "{RomDump}"
# or navigate it input-file-wise:
Find /NAVIGATE OUTPUT/ "{Active}"
Find /¶":BuildResults:RISC:Lib:StartMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Obj:VectorTableInit.a.o¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:IOPrimitives.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:MMU.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:OS.lib¶"/ "{Active}"
Find /¶":Misc:GoNativeROMLib.o¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:SlotMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:SCSI.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:HFS.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ADBMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:Toolbox.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:MemoryMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:AliasMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ComponentMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:DataAccessMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ExpansionBusMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:Gestalt.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:NotificationMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ToolboxEventMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ControlMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:DisplayMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:WindowMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:MenuMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ATAMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Obj:DeviceMgr.a.o¶"/ "{Active}"
Find /¶":BuildResults:RISC:Obj:DispatchHelper.a.o¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:DialogMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ResourceMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:ScriptMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:CQD.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:FontMgr.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Lib:Lastly.lib¶"/ "{Active}"
Find /¶":BuildResults:RISC:Obj:DispTable.a.o¶"/ "{Active}"
Find /¶":BuildResults:RISC:Obj:CoolStuff.a.o¶"/ "{Active}"
############################# NAVIGATE PATCHES #############################
# (These command lines are a bit clumsy. Oh well...)
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"JMFBDRVR¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"JMFBDRVRSIZE¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"JMFBPRIMARYINIT¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"TFBDRVR¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"TFBDRVRSIZE¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"TFBPRIMARYINIT¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ADBMANAGER¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"COUNTADBS¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"GETINDADBTRAP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"GETADBINFOTRAP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"SETADBINFOTRAP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ADBOPTRAP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"RUNADBREQUEST¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"EXPLICITREQUESTDONE¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"IMPLICITREQUESTDONE¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ADBREINIT¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"INITADBDRVR¶"/ # patch $2010,$0004,A7
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"RSETKMAP¶"/ # patch $2010,$0008,A7
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"SLOTBLOCKXFERCTL¶"/ # patch $2010,$000c,A7
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"KEYTRANS¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"SYSBEEP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ORIGBOOTBEEP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ORIGBOOTBEEP6¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ORIGERRORBEEP1¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ORIGERRORBEEP2¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ORIGERRORBEEP3¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ORIGERRORBEEP4¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"BOOTBEEP6¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ERRORBEEP1¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ERRORBEEP2¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ERRORBEEP3¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ERRORBEEP4¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"DOBEEP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"BOOTSOUND¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"MARIOBOOTSOUND¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"CYCLONEBEEP¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"CLOCK¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"ONESECINT¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"PRAMIO¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"READXPRAM¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"WRITEXPRAM¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"VALIDATEPRAM¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"CRSRDEVDISPATCH¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"CRSRDEVHANDLEVBL¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"CRSRDEVREINIT¶"/ # patch $2010,$0010,A7
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"INITCRSRDEV¶"/ # no patch
File "{PatchDump}"; Line 0; File "{PatchDump}"; Find /Module=¶"SETCRSRDELAY¶"/ # patch $2010,$0014,A7
# (file abbreviated)
############################## NAVIGATE OUTPUT #############################
# ":BuildResults:RISC:Lib:StartMgr.lib"
Find /Åjump to next fileÅ/ "{Active}"
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"MYFIRSTPROC¶"/ # ID 4769
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"BASEOFROM¶"/ # ID 4771, offset $0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"MYROM¶"/ # ID 4852
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"CHECKFOREGRETORCUDA¶"/ # ID 4893, offset $1132
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"SETUPTIMEK¶"/ # ID 4865, offset $402
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"TCOFF¶"/ # ID 4864, offset $b4
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"STARTINIT1¶"/ # ID 4863, offset $de
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"STARTBOOT¶"/ # ID 4862, offset $b6
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"ROMLOC¶"/ # ID 4861, offset $2e
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"OPENSDRVR¶"/ # ID 4860, offset $d0a
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INITSCC¶"/ # ID 4859, offset $1066
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INITDEFGAMMA¶"/ # ID 4858, offset $e64
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"DISPOFF¶"/ # ID 4857, offset $22
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"CRITICAL¶"/ # ID 4856, offset $26
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"BOOTRETRY¶"/ # ID 4855, offset $1ce
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"ADDVIDDEVICE¶"/ # ID 4854, offset $101c
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"INTERC_11E0_C2PSTRCPY¶"/ # ID 4849
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1230¶"/ # ID 4847, offset $50
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_12C0_ISLAND¶"/ # ID 4840, offset $e0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_12D0_ISLAND¶"/ # ID 4838, offset $f0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_12E0_CODEPREPARE¶"/ # ID 4836, offset $100
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_14E0¶"/ # ID 4834, offset $300
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_15C0_CODEPREPARE2¶"/ # ID 4872, offset $3e0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1690_CODEREGISTER¶"/ # ID 4871, offset $4b0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1750_LANLIB¶"/ # ID 4829, offset $570
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1890_INITLANDISK¶"/ # ID 4890, offset $6b0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1910_USBFAMILYEXPERTLIB¶"/ # ID 4882, offset $730
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1980_DRIVERS¶"/ # ID 4881, offset $7a0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1CA0_INCREMENTSTRUCTFIELD¶"/ # ID 4821, offset $ac0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1CC0_MOVEUNIVINFOTOSYSHEAP¶"/ # ID 4867, offset $ae0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1DB0¶"/ # ID 4819, offset $bd0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1DE0¶"/ # ID 4816, offset $c00
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1E20¶"/ # ID 4813, offset $c40
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1E90¶"/ # ID 4811, offset $cb0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_1F40_BACKLIGHT¶"/ # ID 4892, offset $d60
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2090_POWERMGR¶"/ # ID 4875, offset $eb0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2130_CARDBUS¶"/ # ID 4889, offset $f50
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2250¶"/ # ID 4783, offset $1070
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2320¶"/ # ID 4782, offset $1140
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2380¶"/ # ID 4775, offset $11a0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_23E0¶"/ # ID 4774, offset $1200
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2440¶"/ # ID 4772, offset $1260
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_24C0¶"/ # ID 4853, offset $12e0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2560¶"/ # ID 4874, offset $1380
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2600_EXPERTENTRYPOINT¶"/ # ID 4896, offset $1420
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_26F0¶"/ # ID 4897, offset $1510
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2750¶"/ # ID 4898, offset $1570
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2780_FIREWIRE¶"/ # ID 4884, offset $15a0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_29C0_WIRELESS¶"/ # ID 4900, offset $17e0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2A20_SCSITARGETMODE¶"/ # ID 4886, offset $1840
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2A80_ETHERPRINTFLIB¶"/ # ID 4876, offset $18a0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2B20_GRAYPAGE¶"/ # ID 4903, offset $1940
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2BC0_DEBUGPRINT¶"/ # ID 4878, offset $19e0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2F40¶"/ # ID 4905, offset $1d60
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2FA0¶"/ # ID 4906, offset $1dc0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_2FF0¶"/ # ID 4907, offset $1e10
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_3020¶"/ # ID 4908, offset $1e40
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_3040¶"/ # ID 4909, offset $1e60
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INTERC_3060¶"/ # ID 4910, offset $1e80
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"FINDSTARTUPDEVICE¶"/ # ID 4831
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"ERASEMYICON¶"/ # ID 4789, offset $5bc
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"ZEROD0¶"/ # ID 4850
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"INTERNALWAIT¶"/ # ID 4832
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"GETDEFAULTSTARTUP¶"/ # ID 4919
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"SETDEFAULTSTARTUP¶"/ # ID 4920
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"GETOSDEFAULT¶"/ # ID 4921
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"SETOSDEFAULT¶"/ # ID 4922
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"GETVIDEODEFAULT¶"/ # ID 4923
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"SETVIDEODEFAULT¶"/ # ID 4924
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"STARTLIB_GETSTARTUPDEVICE¶"/ # ID 4917
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"STARTLIB_GETSTARTUPDEVICETYPE¶"/ # ID 4912, offset $c0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"STARTLIB_GETFIREWIRESTARTUPDEVICEINFO¶"/ # ID 4911, offset $180
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"BOOTME¶"/ # ID 4776
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"__v__OPENSLOTS¶"/ # ID 140, offset $132
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"INITSYS7TOOLBOX¶"/ # ID 4848, offset $22a
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"OPENSLOTS¶"/ # patch ID 4944, patch $2010,$00b0,A7, offset $22c
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"#0001¶"/ # ID 4940
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"PUTICON¶"/ # ID 4936, offset $204
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"CRITERR¶"/ # ID 4777, offset $0
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"SYSERRINIT¶"/ # ID 4841
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"TODEEPSHIT¶"/ # ID 4938
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"GENEXCPS¶"/ # ID 4932
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"NMIEXCP¶"/ # ID 4929, offset $1a
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"IRQEXCEPTION¶"/ # ID 4930, offset $18
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"SYSTEMERROR¶"/ # ID 4928
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"SYSERR2¶"/ # ID 4926, offset $10
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"SYSERR1¶"/ # ID 4927, offset $6
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Module=¶"#0001¶"/ # ID 4925
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"DSERRORHANDLER¶"/ # ID 4904, offset $4e
File "{RomDump}"; Line 0; File "{RomDump}"; Find /Entry=¶"ALLOCFAKERGNS¶"/ # ID 4933, offset $0
# ":BuildResults:RISC:Obj:VectorTableInit.a.o"
Find /Åjump to next fileÅ/ "{Active}"
I agree that MPW is unfriendly to the newcomer. But since I have learnt to use MPW's strengths, and integrated it into a heterogeneous computing environment, it has become my very favourite development system.
-
By the way, madalynmcworm, what kind of development are you looking to do?
-
By the way, madalynmcworm, what kind of development are you looking to do?
Been making some small apps that I feel I need while I work towards bigger goals.
So far, I've been working on a shell application. It runs, lets me list files in directories, etc. and it can spawn off a new program. The original library from Metrowerks would exit upon running a program, but I just got rid of that part. Reading your post seems that might have been a mistake on my part :D
I made a small library that I've been working on that lets me build windows programmatically. I can add UI elements, etc, and it handles all the button pushes etc. It takes in functions as callbacks, and just sets everything up cleanly. Builds everything with HANDLES.
Poked around with old SDL. Got it to compile and made a terrible tetris. It's terrible. I won't mention it again :)
Compiled the source for a NES emulator, that was a chore. But it works fine as far as I can tell.
Just mostly poking as I have time. Maybe some day I'll make some real apps.