Fish NDA 1.0 Released!

Finally, about a month and a half late, I have released Fish NDA, the stupidest program in computer history! Check out the details onĀ my Apple II software page.

April 11th, 2010, posted by admin

Joe Kohn Passes Away

Long time Apple II writer, publisher, and advocate Joe Kohn, best known for his work at inCider/A+and Shareware Solutions II, passed away this week. has the story.My deepest sympathies to Joe’s family. While I have not had contact with him in several years, there was no one more supportive of the Apple II.

January 9th, 2010, posted by admin

IPDataReporter a1.0 Released (Untested!)

This was my KansasFest 2009 HackFest entry; I intend to do some more work on it, but since the KansasFest committee already asked for an archive of it, here it is–I will warn you, however, that it is not even close to beta ready (even though it does work on my system).

Good luck!

July 27th, 2009, posted by admin

IItter 1.0 and Stock Quote CDA 1.0 Released

Today I will be releasing two new Apple II products: IItter 1.0 (only a year late), a freeware Apple IIgs Twitter client in a New Desk Accessory and Stock Quote CDA 1.0, a public domain Apple IIgs Classic Desk Accessory which gets stock quotes; the latter includes source and compilation instructions.

July 23rd, 2009, posted by admin

At KansasFest 2009

Yes, I am here at KansasFest 2009; I will be releasing one program and at least announcing if not releasing another. Party on.

July 21st, 2009, posted by admin

Using Records: a Twitter Example

When I first started figuring out how to do Toolbox programming (and trust me, I am a rank amateur), one of the things I remember Mike Westerfield (of Byte Works fame) saying is that to do Toolbox programming, you had to use records and pointers.

“What in the name of Rennyo is a record?”

A record is like a variable on steroids. In ORCA/Pascal, it’s a “type”, meaning it’s a type of variable. What’s special about a record is that it allows grouping of several other types of variables, making it like a “super variable.” The example Mike gives is a deck of playing cards; each card has a number and a suit. To see how this would be declared in Pascal, the example goes:

card = record
s: suit;
v: value;

Each card variable is a record, and that record has two of its own variables, s for the suit and v for the value. Presumably suit would be either spades, clubs, hearts, and diamonds, and value is between 1-13 (or, since not actually clear here, among 2-10 and Jack, Queen, King, and Ace).

Let’s use another example: Twitter. My guess is that if you’re on the Internet (which you pretty much have to be to read this), you’ve heard about Twitter by now (or you just go to this site and nowhere else). In any case, I’m continuing to try and finish up my Twitter NDA, aka IItter, which is really close to release. In doing so, I learned quite a bit about data that Twitter puts out for each “Tweet” (each individual posting to Twitter).

For instance, if we fetch some Tweets from the server (the “mobile” version of Twitter, although I think this is essentially the same as we’d get from the non-mobile server), we see an individual Tweet’s raw XML would look like this:

<created_at>Mon Apr 06 09:31:02 +0000 2009</created_at>
<text>Ms. Unreliable just came online. Is that time for me to go to bed?</text>
<name>Ryan Suenaga</name>
<description>Hawai'i's best known Apple II Geek and social worker</description>
<created_at>Sun Mar 18 06:26:37 +0000 2007</created_at>

Now, that’s quite a bit of code! However, we may just want to look at a few of these elements–or at least, for IItter, I’m just looking at a few of these elements. All I’m interested in is the text of the Tweet, the screen name of whomever Tweeted, and the date and time it was created. So, we’re talking these three items from the Tweet above:

<text>Ms. Unreliable just came online. Is that time for me to go to bed?</text>
<created_at>Sun Mar 18 06:26:37 +0000 2007</created_at>

And yes, I know this is not 2007, but that’s what the Twitter API returned just now!

Once I have those, I have the basis of the data I wish to display. I also know that the text of the Tweet is at most 140 characters; the created_at information is a fixed length of 30 characters (a lot like a standard Internet date and time string seen with, among other things, electronic mail); and we also know that the maximum length of a Twitter screen_name is 15 characters.

So, if we want to set up a record type to account for this information, we can do so like this:

twitter_record = record
text : pstring;
screen_name: pstring;
created_at: pstring;

my_twitter_record: twitter_record;

We have declared a record type called twitter_record to suit our needs of grouping the text, screen_name, and created_at information together, then declared the variable my_twitter_record of the type twitter_record for our use in this program.

Since we know that all of the data returned are strings of text less than 255 characters in length, pstrings are quite useful here. With appropriate parsing, we end up setting our variables so that they have these values:

is ‘Ms. Unreliable just came online. Is that time for me to go to bed?

my_twitter_record.screen_name is ‘rsuenaga

and finally,

my_twitter_record.created_at is ‘Sun Mar 18 06:26:37 +0000 2007

So, there’s a quick bit on records. It’s going to take a bit more time to get IItter done (I was hoping while I was off but many other things also needed attending to).

April 6th, 2009, posted by admin

Bitly CDA 1.0 released

My KansasFest 2008 HackFest project, Bitly CDA, has just been released. Requires System Software 6.0.1, Marinetti 2.0.1 or later, and a working TCP/IP connection. It uses the Web site to shorten URLs. Check it out here!

August 31st, 2008, posted by admin

Coming Soon…

I announced (but have not yet released) a program at KansasFest, and I participated (for the first time) in HackFest (and won!) with another program that’s actually more ready for release.

IItter is what’s not yet done, even though I worked on it forever (like more than a year). It’s a Twitter client in an Apple IIgs New Desk Accessory. Requires Marinetti 2.0.1, System Software 6.0.1, and a working TCP/IP connection.

Bitly is a Classic Desk Accessory (that’s right, -not- a NDA, a CDA!) that takes the text content of the IIgs clipboard and submits it to the URL shortening service, returning a shorter version.

Screenshots (and hopefully a release!)d soon.

July 30th, 2008, posted by admin

Base64 Encoding Using ORCA/Pascal

I am currently working on a TCP/IP New Desk Accessory (what else do I ever work on?) that requires “basic authentication”. Basic authentication is a really simple, very unsecure way of encoding a username and password. In essence, the username and password are joined together in a single string with a colon between the two:


and then encoded into Base64. As I’ve never tried to figure out how to encode into Base64 before, I decided this would be a nice exercise for my Pascal skills.

Working backwards, I can easily figure out what the end result of the encoding is supposed to be; there are many online Base64 encoding Web pages, so the string above would be encoded as:


How do we get there from here?

Wikipedia to the rescue! Wikipedia provides about as close to a plain English step by step on encoding a string as Base64.

First off, each character that needs conversion must be converted to its ASCII numeric equivalent. Well, actually, first, once we have the username:password string built–which are two p-strings combined to make a c-string; p-strings because that’s an easier way for me to get input from a IIgs LineEdit dialog, and a c-string because its longer length could be an advantage depending on how long the username and password are–we need to look at it character by character. So in order to do that, we take the assembled username:password string and use a loop to parse out the characters one by one:

Procedure CharParser; {parses out each character}

username, password: pstring;

parsedchar: char;
rawauthstring, binauthstring: cstring;

ploop: integer;


rawauthstring := concat(username, ':', password); {combine the username}
{and password with a }
{colon between them }

ploop := 1; {parsing loop--1 for 1st character}
While ploop <= length(rawauthstring) do begin
parsedchar := rawauthstring[ploop]; {sets parsedchar to the current}
{character as ploop increases }
ploop := ploop + 1; {increment ploop by a character}
end; {parsing loop}
end; {CharParser}

This procedure, while it will run right now, isn’t useful without a bit more code that we won’t get into yet. Basically as the ploop starts with the first character in rawauthstring and moves character by character through the string until it reaches its end, it assigns the character at the current position in the loop to the character value parsedchar, then moves onto the next character. In order for this procedure to be more useful, more has to be done with parsedchar, starting with converting from a character to an ASCII value, then converting the numeric ASCII value into a binary value, padding the length of the binary value so it’s eight digits long, and adding it to a progressively growing string of 0s and 1s for further conversion. We’ll tackle some of this next episode!

March 16th, 2008, posted by admin

A facelift, a new domain and a new site got a facelift this past weekend, this site just got its own domain name (, and I just launched my personal finance blog at Please check them out and I hope you like them.

December 3rd, 2007, posted by admin