Developing NewtonScript apps for the Apple MessagePad

NewtonOS in 2020

In 2020, running NewtonOS via the Einstein emulator is tons of fun. I am currently trying to get a very comfortable version of Einstein running on Android (and eventually iOS) mobile devices. Particularly e-Ink devices are very much in the intent of the original MessagePads. Part of this is developing an interface between NewtonOS and Einstein that is as simple as possible for Newton developers, and is supposed to give NewtonOS access to host properties wherever needed.


NTK is a fully integrated developer environment for NewtonScript apps, running on a classic Mac. There are usually no external tools required to get an app compiled and running on a MessagePad connected via the serial port.

In todays world, we can't launch classic Mac apps anymore without the help of an emulator like BasiliskII (download here), and RS232 serial ports are nowhere to be found, unless daisychaining USB adapters and MessagePad proprietary cables.

But Einstein makes life a lot easier.

  • the latest version of Einstein from emulates serial ports over network (TCP/IP)
  • BasiliskII from also offers serial port emulation over TCP, so in the BasiliskII config file ~/.basilisk_ii_prefs set the seriala entry to tcp:3679 and BasiliskII and Einstein will be best buddies.

  • on, find the classic Mac disk images MacOS 7.5.5 and NewtonDevel1.1; add a ROM to BasiliskII (search for Performa.rom) and Einstein (serach for 717006.rom), and you are ready to develop

Connect Einstein to NTK

On Basilisk, open the developer disk and launch NTK with a double-click.

No need to create a project yet, so select cancel.

Also launch EInstein. On Einstein, start Dock in the Extras drawer, choose Connect via Serial and tap Connect. Don't doddle now.

Go to NTK on Basilisk, choose Project >> Install Toolkit App, and after a few seconds, NTK should upload the Toolkit application to NewtonOS on your Einstein emulator.

If you made it here, you are ready to develop your first NewtonOS app!

If the emulators fails to connect, you may have the wrong version of Bailisk. If you are on a Mac, you can download the one I specifically compiled for this.

The NTK Inspector

Now that we know that the connection between Einstein and Basilisk is working, we can try to establish the testing and debugging connection via the Inspector. The Inspector is a dubber buit into NTK on the Mac side, and on the NewtonOS side is implemented via the Toolkit App that we just uploaded to EInstein.

On the Newton, launch Toolkit from the extras folder. Tap on Connect Inspector.

On the Mac side in NTK, press Apple-K, and the Inspector window will open and connect to the Newton. If both dialog boxes vanish, the connection was successful. In the Inspector window, type 2+2 and press Apple-Return. This launches an long chain of events:

GeekOut: NTK, emulated m68k code, will send this request to the serial port that BasiliskII will forward to the pty which will then be picked up by EInstein which forwards it via an emulated serial port to the Toolkit app, emulated ARM code, which then tells NetwonOS to interprete that request in its NewtonScript interpreter. This will compile the text into byte code, and then interprete that bytecode, giving the result back to the Toolkit which gives it back to Einstein, then through the pty to BasiliskII and finally to the NTK Inspector which then prints #8 2. The first number is the event number, the next number is the reult of our calculation. Yeah, it really is that simple.

Try other commands. GetRoot(); is a bit more exciting.

Congratulations. You now have the exact same setup that a Newton developer would have had in 1996. Play some Jamiroquai and dance the Macarena. And send me a video of that.

My first Newton app

Let's try the almost mandatory hello world program. Assuming you have everything set up and the Inspector connection is alive (as long as the toolbox in the inspector window is open, the connection is alive).

In NTK, select Project >> New Project... from the menu. In the following file chooser dialog, create a folder named hello and change into it. Also name the project hello and click Save. The new window will contain a list of files that you use to build your app.

Choose File >> New Layout and the layout editor will open.

Choose File >> Save as... and name the file hello.lyt. Then choose Project >> Add hello.lyt. You are done. This is a very minimal app that will do absolutely nothing. NTK realizes that and will not let you compile it. So we need to add at least a window, I guess.

In the little toolbox window next to the layout, choose protoFloatNGo from the pulldown menu (it's also on the second button in the second row of the shortcuts).

With that selected, click down in the top left corner of the layout view and drag to the bottom right to create an appropriately sized window. Nope, there is no preview.

Select protoStaticText form the pulldown, or the last button in the first row, and create a smaller box inside the larger box in the layout window.

We want the static text field to say "Hello, world!", so double-click it in the Layout view which will open the hello.lyt Browser. Click on protoStaticText in the left list, then text in the right list. Replace the "Static Text" in the bottom view with "Hello, world!", including both quotes.

Press Apple-S to save the layout, Apple-1 to build the app, and Apple-2 to upload the app to the MessagePad, assuming the Inspector is still running. Now on the MessagePad, open the Extras folder and you should find a new app named "hello". Tap it, and your app should open a window to say hello to the world.

Congratulations, you are a programmer now. You really earned your MMMBop and a portions of Limp Bizkit. Aaaah, that brings back memories of 1987, George Michael, and my Amiga.

Now hop hop, off you go, write some exciting new apps for the community... !


App icons are 31 pixels wide and 29 pixels high.

native functions:

  • dbgPrintICode := true; /* print intermediate code */
  • dbgPrintCCode := true; /* print C code */
  • dbgVarNames := true; /* make C var names similar or same a SN names */

  • On mac: GlobalData, Windows95: GlblData.f

;; VK_F1 0x70
protoEditor:DefineKey({key: $e, command: true}, 'EvaluateSelection);
protoEditor.upcaseSelection := func(off, len) begin
protoEditor:DefineKey({key: $u, option: true}, 'upcaseSelection);
print(knownglobalfunctions); ;; checkglobalfunctions
foreach key, value in knownglobalfunctions do begin print(key); print(value); end;
Display("Hi!"); ;; writes to Inspector screen (so does print();)
GetGlobals();  ;; really fun!
print(StrHexDump(Debug("showFloaterButton").text, 4));

v := debug("myslider")._proto.changedSlider; w := installbreakpoint(v, 1); enablebreakpoint(w, true);