No News Is Good News

In this case at least.

Apologies for the lack of updates, especially after telling quite a few folks that “I’ll post some new info shortly” for the past couple of months :/

Here’s the latest on the Flyer project:

  • I’m finishing up a comprehensive user guide which should be wrapped up by the end of the weekend.
  • The hardware has been final for quite some time. A number of units are built, tested and ready to go.
  • I was able to get the cost down to $100 by re-sourcing some components and purchasing a few items in bulk.
  • A companion website for online disk and program storage is in place and will be announced shortly.

I feel confident in saying that the Flyer will be available very soon for anyone interested in purchasing one. I don’t want to release anything half-baked or missing any obvious functionality, even though firmware updates are extremely easy and safe to perform on the Flyer (and I have many ideas planned for future updates).

First impressions and all that…

Anyway, since this is a short update I’ll reprint one of the examples from the user guide on writing a very simple network-based “fortune cookie” program with the Flyer.  Keep in mind this will work on nearly any Commodore machine.

Thanks for reading!

4.1 Writing a Fortune Cookie Program

This example will demonstrate how easy it is to write a simple internet-enabled program in BASIC using the Flyer. Our goal is to write a program to fetch one of potentially thousands of “fortune cookie” messages from an HTTP server and display them to the user.

The Server

The first thing we’ll do is write a PHP script to serve messages back to the client. To keep things simple, we’ll just choose one of three hard coded messages (a “real” solution would most likely parse/fetch data from real fortune files or a database, but that’s outside the scope of this example).


require_once '';

$fortunes = array(
"As a computer, I find your faith in technology amusing!",
"If a pig loses its voice, is it disgruntled?",
"Confidence: The feeling you have before you understand the situation."

$index = rand( 0, count( $fortunes ) - 1 );
$petscii = Retroswitch::AsciiToPetscii( $fortunes[$index] );
e c h o urlencode( $petscii );


This script has been placed at

A couple of things are worth pointing out…

First, since Commodore computers do not use standard ASCII (although it’s very close), we must convert any text data before outputting it to ensure it will be displayed properly (this will always be an issue when communicating with “the outside world” from your Commodore). The Retroswitch utility class (available on contains PHP code for converting between ASCII and PETSCII.

Second, note that we are url encoding the returned fortunes, since we’ll be reading them with the INPUT# instruction. INPUT# will stop on various delimiters (such as a comma), and url encoding allows us to retrieve the entire response in one chunk. Otherwise we would have to use GET#  and receive one character at a time, which is much slower. Of course, url decoding in BASIC is also quite slow and is the main cause for the delay when retrieving fortunes in this example. It is a perfect candidate for a speedy little machine language routine, however!

The Client

Next we’ll write a BASIC program that will fetch and display a random message. This program should be entered and run in lower case mode, as with all the other examples in this manual.

This first section is the main loop of the program. It simply fetches and displays a fortune, then prompts the user whether they would like to continue:

10 gosub 100: rem returns random fortune in m$
20 print:print m$:print
30 print"Would you like another (Y/N)?"
40 get q$: if q$="" then goto 40
50 if q$="y" OR q$="Y" then goto 10
60 print:print"Have a nice day!"
70 end

Next is the subroutine which performs the HTTP request to retrieve the fortune. We first open the command channel so we can check error status and issue commands. Then we open a general communications channel (2 in this example), using the HTTP protocol and supplying the path to our PHP script.

We can add additional POST and FILE data to the HTTP request at this point since the server transaction has not yet occurred. However, for this example we’re only interested in the server response so we initiate the transaction immediately by issuing the HTTP-TRANSACT command over the command channel, specifying the communication channel with the pending transaction (#2). This pattern should be very familiar to anyone that has done direct-access disk programming.

Once the transaction has occurred, the server’s response can now be read. We read the response into E$, url decode it, then return the result back to the main loop in M$:

100 open 7,7,15: rem open command channel
110 open 2,7,2,""
120 print#7,"http-transact:2":gosub 500
130 input#2,e$:gosub 500
140 close2:close7
150 gosub 200: rem url decode e$, result in u$
160 m$ = u$
170 return

Next we have a couple of subroutines used for url decoding:

200 rem url decode from e$ to u$
210 sl=len(e$):u$="":ifsl=0thenreturn
220 fori=1tosl:ac=asc(mid$(e$,i,1))
230 ifac=43thenu$=u$+" ":goto280
240 ifac<>37thenu$=u$+chr$(ac):goto280
250 an=asc(mid$(e$,i+1,1)):gosub300:h0=dn
260 an=asc(mid$(e$,i+2,1)):gosub300:h1=dn
270 i=i+2:u$=u$+chr$(h0*16+h1)
280 nexti
290 return

300 rem convert ascii nybble to dec from an to dn
310 ifan>=48andan<=57thendn=an-48:return
320 ifan>=65andan<=90thendn=an-55:return
330 ifan>=97andan<=122thendn=an-87:return
340 dn=0:return

And finally a short subroutine which we call periodically during the network I/O to check for any error conditions. If an error is detected, we print the error code and message before quitting.

500 input#7,a,b$,c,d
510 if a=0 then return
520 close2:close7
530 print"Error: ";a
540 print"Message: ";b$
550 end

That’s it! For your typing convenience, this sample program can be loaded directly from the following location: