Mottek Archive 2010

Fun with NEWT/0

One of my long standing pet peeves is the problem of not being able to use Mac OS X anymore for Newton development since the Leopard days. Basilisk II is of course an option, but it's quite cumbersome. For that reason, I've been trying to put together simple compiler based on NEWT/0 and the DCL to allow at least some sort of text based development.

So far my experiments are actually quite successful, and it seems that developing Newton applications with just a text editor is not that impractical. It is in fact easier when it comes down to version control management. Some things are still missing for developing larger apps, like the ability to split the code into multiple source files, and a way to embed resources into the final package, but for simple applications (and even auto parts), we might have a way forward.

This is nowhere as ambitious as Matthias Melcher's DyneTK project, but maybe good enough to get people interested in a bit of Newton hacking. Unfortunately I haven't gotten around to packaging the code nicely yet, so far it's part of the SVN repository at SourceForge under tntk. I also uploaded the Mac OS X binary itself, but there are guarantees that it would actually to something useful. It has a couple of non-functional parts, but compilation should be as simple as

tntk -c ProjectFile.nprj

Below is how a simple NewtApp would look like, first the project file which describes basic app parameters, and also points to the NTK platform file which contains common definitions needed for development (this would be saved as e.g. ProjectFile.nprj):

{
    parts: [
        {
            main: "Main.newt",
            files: [],
        }
    ],
    name: "MiniNewtApp:40hz",
    platform: "/Applications/Newton/NTK 1.6.4/Platforms/Newton 2.1"
}

And this is the main file, according to the project file above it would need to be saved as Main.newt:

kAppSymbol := '|MiniNewtApp:40Hz|;
kAppTitle := "MiniNewtApp";
kVersion := "1.0";

defaultLayout := {
    _proto: newtLayout,
    masterSoupSlot: 'MiniNewtAppSoup,
    name: "Default",

    viewJustify: vjParentFullH + vjParentFullV,
    viewBounds: {left: 0, top: 20, right: 0, bottom: -25},

    stepChildren: [
        {
            _proto: newtEntryView,

            viewJustify: vjParentFullH + vjParentFullV,
            viewBounds: {left: 0, top: 0, right: 0, bottom: 0},

            stepChildren: [
                {
                    _proto: newtLabelInputLine,
                    path: 'title,
                    label: "Title",
                    labelFont: ROM_fontSystem10Bold,
                    viewJustify: vjParentFullH + vjParentTopV,
                    viewBounds: {left: 0, top: 4, right: -8, bottom: 32},
                },
            ]
        }
    ]
};

overviewLayout := {
    _proto: newtOverLayout,
    masterSoupSlot: 'MiniNewtAppSoup,
    name: "Overview",

    viewJustify: vjParentFullH + vjParentFullV,
    viewBounds: {left: 0, top: 20, right: 0, bottom: -25},

    Abstract: func(target, bbox) begin
        return MakeText(target.title, bbox.left + 2, bbox.top, bbox.right, bbox.bottom - 18);
    end
};

mainView := {
    _proto: newtApplication,
    title: kAppTitle,
    appSymbol: kAppSymbol,
    appObject: ["Task", "Tasks"],
    appAll: "All Tasks",
    allLayouts: {
        default: defaultLayout,
        overview: overviewLayout
    },
    aboutInfo: {
        tagLine: "MiniNewtApp - a NewtApp demo",
        copyright: "(c) Eckhart Koeppen, all rights reserved",
        version: kVersion
    },
    allSoups: {
        miniNewtAppSoup: {
            _proto: newtSoup,
            soupName: "MiniNewtApp",
            soupIndices: [],
            soupQuery: {},

            CreateBlankEntry: func() begin
                return Clone({title: "Title"});
            end
        }
    },
    stepChildren: [
        {
            _proto: newtClockFolderTab
        },
        {
            _proto: newtStatusBar,
            menuLeftButtons: [newtInfoButton],
            menuRightButtons: [newtActionButton, newtFilingButton, newtCheckAllButton]
        },
    ],

    viewJustify: vjParentFullH + vjParentFullV,
    viewBounds: {left: 16, top: 16, right: -16, bottom: -16},
};

{
    app: kAppSymbol,
    text: kAppTitle,
    theForm: mainView,

    devInstallScript: func (partFrame) begin
        partFrame.removeFrame := partFrame.theForm:NewtInstallScript(partFrame.theForm);
    end,
    RemoveScript: func(partFrame) begin
        partFrame.removeFrame:NewtRemoveScript(removeFrame);
    end,

    InstallScript: func (partFrame) begin
        partFrame:?devInstallScript(partFrame);
        if HasSlot(partFrame, 'devInstallScript) then RemoveSlot(partFrame, 'devInstallScript);
        partFrame.InstallScript := nil;
    end,
}

Web site moved

I noticed that this web site started to show more and more slowdowns, and I asked my current hosting provider Hurricane Electric what they could do about it. They offered to move me to another server, which initially seemed like a great idea, the new hardware was indeed faster, but then I noticed that it's running Linux on 64 bits, which causes memory consumption to go up. That by itself is not an issue, unfortunately the site was using Apache and the Python-based MoinMoin Wiki as the CMS, and Python modules which are dynamically loaded are wasting quite a bit of memory. In the end, there was no other option to rewrite the whole setup, and PHP was the safe choice. With Kohana, I found a framework which has the right level of abstraction, and after about two weeks of hacking, things should be back to normal now :) The RSS feed might need some modifications still, but I hope I can now go back to the regularly scheduled Newton programming!

The 2008 Bug

The NewtonOS still has one problem related to the year 2010 problem: Very early in the boot sequence, the OS adjusts the real time clock to a "reasonable" value. Unfortunately, dates past 2009 are not considered reasonable, and the OS resets the date therefore to 1996.

The 2010 patch kicks in after that, and it can then only get the date to something slightly better, which is 2008. A proper fix would require to change the function which adjusts the clock, but it is not in the patchable area. It also occurs so early in the boot sequence that there is no easy way to intercept it, backup the proper clock value, and restore it later.

There are some workarounds possible, for example storing the correct time every minute when the Newton is turned on, but they require a good place for the time value. Flash memory is not ideal, a better place would be somewhere in RAM which survives resets and reboots. I'm now on the hunt for such a buffered location...