Swedish woo-woo map

This is the Swedish woo-woo map on Google Maps. Please help updating it, and do consult it to make sure you’re not paying for any nonworking preparations or other bogus.

Editing code on the Commodore 65

The Commodore 64 and the Commodore 128 uses the same method for editing code. You press enter over a line, and that line is stored the with the index of the entered line number, overwriting any existing code on that with that index. The Commodore 65 has the same machine code monitor as the Commodore 128 (it runs more smoothly because the C65 is much faster than the C128). Also, adding and overwriting Basic code is done in the same way. Editing is probably not, but I am not sure.

On the C128, you just had to make sure you saw the line of code on screen, move the text cursor to it, write something else on top of what is there, and save it by pressing Enter. The C65 does not allow you to fly around with the text cursor over the screen. I loved the fact that you could move the cursor to any position, but it was tricky to collect user input if the user suddenly felt the urge to move away and type something unexpected at an arbitrary location. Perhaps they were to implement some command to do this, or perhaps they planned to allow the cursor to move freely. I don’t know.

I have found some great improvements. Here, I have added 4 lines of code. It displays three lines of text and makes a sound. I use the LIST command to display the whole Commodore Basic 10 program.

Already on the C128 you could use arguments to list parts of the program, and change the line numbers throughout the program using the RENUMBER command. But on the C65, you can find out the line number of certain line of code using the FIND command.

The above image shows the C65 telling me where the word HEJ can be found in my program. Also, I can use the CHANGE command to search and replace text. Let’s say I want to change the notes I want the C65 to play, I can use CHANGE to do this. The C65 asks for each search hit before changing.

Hope to get back to the lovely world of Commodore in the future.

The Commodore 65

This is truly one of those machines you really want to own. The Commodore 65 (or C64DX) never made it to the market, probably because of the huge success of the Commodore Amiga. But what a machine it is.

Better graphics than the Amiga, 128 Kb of RAM (could be expanded 8 Mb) and a Basic interpretator for Commodore Basic 10. Commodore Basic 10 is sort of the same that the Commodore 128 has (Commodore Basic 7) but well improved with added support for mouse programming and genlocking (that is adding graphics to video).

The most amazing feature of the C65 must be that it had two SID chips for sound. This gave the machine 6 channels of fat analogue stereo sound. Like the C64, but more.

There are (illegal) ROM dumps circulating the Internet, and I sometimes get it to run without crashing my PC. I hope to get back to this soon enough.

Tweaking the wall, part 1/3: Before and after update

The Wall has some support for free drawing. This can either be done before or after updating the screen. Any drawing that is done before updating will be displayed behind registered objects (se the Hello World example) and any drawing that is done after updating will be displayed on top of registered objects. The coordinate system of registered objects use characters, and by default a character is 25 pixels wide and 42 pixels high.

The Hello World application in The Wall Looks like this…

BackgroundColor = "#445566"
RegisterTextItem 0, "A", 4, 4, "#aabbcc", "InitializeText"

Sub InitializeText(ByVal Item)
	Item.Value = "Hello!"
End Sub

…and the result looks like this:

The code I add to illustrate how graphics can be added behind registered objects is red and bold in the following listing. BeforeUpdate “MyBeforeFunction” tells The Wall to call a function before drawing the registered items. The argument is the name of the function.

BackgroundColor = "#445566"
RegisterTextItem 0, "A", 1, 1, "#aabbcc", "InitializeText"

BeforeUpdate "MyBeforeFunction"

Sub MyBeforeFunction(ByVal G)
	G.DrawLine 0, 70, 100, 70
End Sub

Sub InitializeText(ByVal Item)
	Item.Value = "Hello!"
	Item.Shadowed = True
End Sub

The result is the word “Hello!” with a white line behind it. I added a shadow behind the text to make the effect more visible.

To draw graphics in front of the registered items, use the AfterUpdate function to register a callback for that. This code (new lines are red and bold) also draws a line in front of “Hello!”.

BackgroundColor = "#445566"
RegisterTextItem 0, "A", 1, 1, "#aabbcc", "InitializeText"

BeforeUpdate "MyBeforeFunction"
AfterUpdate "MyAfterFunction"

Sub MyBeforeFunction(ByVal G)
	G.DrawLine "#ffffff", 0, 60, 300, 60
End Sub

Sub MyAfterFunction(ByVal G)
	G.DrawLine "#ffffff", 0, 62, 300, 62
End Sub

Sub InitializeText(ByVal Item)
	Item.Value = "Hello!"
	Item.Shadowed = True
End Sub

This is the result:

A demo is available

The Wall is an intelligent home component that can display and update text items, numeric values and bars. Also, The Wall can react to mouse clicks from a computer mouse or from a touch screen. The demo has all the functionality of the full version, but adds an overlay. This is the “Hello world” of The Wall:

BackgroundColor = "#445566"
RegisterTextItem 0, "A", 4, 4, "#aabbcc", "InitializeText"

Sub InitializeText(ByVal Item)
   Item.Value = "Hello!"
End Sub

The demo will display “Hello!” at position 4 x 4 with an overlay, like so:

The MSI file is available for download from here. If you are using Windows Vista or Windows 7, you might need to download the Microsoft Script Control, since The Wall is powered by VBScript.

Tuples

Tuples in F# is a list of objects with different types, and the tuple itself is strongly typed. You can imagine a simple class or a structure without having to declare the type. This code creates a tuple called myTuple that contains a string, and integer, another string and finally a boolean.

let myTuple=("A", 10, "B", true)

The string representation of a tuple is a string representation of the individual values within parenthesis. This code…

let myTuple=("A", 10, "B", true)
System.Console.WriteLine(myTuple)

…gives you…

(A, 10, B, True)

This code will extract the individual values from the tuple. The output from this code will be 10.

let myTuple=("A", 10, "B", true)
let v1, v2, v3, v4 = myTuple
System.Console.WriteLine(v2)

The types of the values will be the .NET types from the original values in the tuple, v1 is a string, v2 is a 32 bit integer, v3 is also a string and v4 is a boolean. Tuples can be used in many ways, as allowing a single function to return multiple values.

Logging in Notepad

All that you have to do is to add .LOG as the first line in a text document, and then save it. Now, each time you open the text file in Notepad, the current date and time will be added to the file, and the file will be marked as unsaved. I started out like this, and saved my file:

.LOG

This is a log.

Next time the file was opened, this is what Notepad showed:

.LOG

This is a log.

00:32 2010-06-19

The date is not in the file, it was added when the file was opened. I added a line of text (“A new line is added to my log”), saved and reopened again. Notepad added a new line like this:

.LOG

This is a log.

00:32 2010-06-19

A new line is added to my log.

00:39 2010-06-19

Those little things can be so nice to have!

Some cool software for the C128: GEOS


So CP/M is the text based disk operating system for the Commodore 128. You could buy a window based operating on disk called GEOS (Graphic Environment Operating System). GEOS was available for some of the Commodore machines and the Apple II. GEOS is not “smashing” either, but it solved some problems that text based systems had at that time. It presented the features of the applications and the system itself, so that the user could point and click on the feature that user wants to use. These screenshots show GEOS in all its glory on an enormous 320 by 200 pixel screen.

At startup, GEOS shows the content of the system disk. To access some of the useful applications, you would insert that disk, and click Disk and Open to refresh the screen. GEOS was delivered with word processor, a painting program, among other things. Not very sophisticated compared to what you could get for your Macintosh or Windows, but a life saver for any C128 user.

GEOS did not multitask very well. Here, when I use the calculator, I can’t move the mouse outside the calculator window. I need to close it, before I can access the applications window behind, and that window cannot be moved around. It can be closed, and reopened from the Disk menu.

GEOS was relesed in 1986 and from what I know, the GEOS disks are not available for download.

Decompressing text

This post shows how to compress a String to reduce the amount memory it consumes, and this post shows how to use the CompressText function. To be able to read the content of the string, it must be decompressed (or inflated) again. The DecompressText function is one way to do this.

Private Function DecompressText(ByVal B() As Byte) As String
   Dim Result As New System.Text.StringBuilder()
   Using MemStream As New System.IO.MemoryStream(B)
      Using GZStream As New System.IO.Compression.GZipStream(MemStream, _
         IO.Compression.CompressionMode.Decompress)
      Do
         'Note that this makes 1024 bytes in VB.
         Dim Buffer(1023) As Byte
         Dim BytesRead As Integer = GZStream.Read(Buffer, 0, 1024)
         If BytesRead > 0 Then
            Result.Append( _
               System.Text.Encoding.UTF8.GetString(Buffer, 0, BytesRead))
         End If
         If BytesRead < 1024 Then
            Exit Do
         End If
      Loop
      GZStream.Close()
      Return Result.ToString()
      End Using
   End Using
End Function

Now, imagine that B is a byte array returned from the CompressText function. B holds the bytes of a compressed text string. B is passed to the DecompressText function and the function returns the inflated string again. Example:

'Create some text.
Dim S As String = "This is some text that I want to compress. Preferably it's " & _
"a long string loaded from a text file or some XML document."

'Assign the compressed version to the variable B.
Dim B() As Byte = CompressText(S.ToString())

'Decompress it, and display the result.
Dim Decompressed As String = DecompressText(B)
Console.WriteLine(Decompressed)

Have you seen a more elegant way to handle strings in memory than what the .NET Framework offers?

Some cool software for the C128: CP/M

CP/M, the disk operating system for the Commodore 128

This is one of the strange things about this machine. Microsoft DOS was around, and Commodore was already making computers running DOS. But the Commodore 128 was supposed to run CP/M. Who used this?

If you want to boot CP/M, download the image from here. In the ctools/x128 folder, attach the “cpm128.d64″ image to device 8 and type BOOT (or reset the machine).

Attach the first file to drive 8 and type BOOT (or reset the machine). If you’re doing this from a physical C128, make sure to have the 80 col key pressed down. If you’re doing this from the Vice emulator, send the -80 argument to x128.exe at startup.

X128.exe -80

It takes a while to boot, and watching the prompt is sort of just as fun as watching it boot. What can it do? Most of the operations will require that other disks are inserted to the drive. They were delivered with your machine when you bought it, but you probably reformatted those disks to make room for some pirated games. However, you can show the contents of a disk by typing dir and you can get help by typing help. Hang on, it is working on providing you help. No it didn’t crash, it is working on providing you help! Yes, it is. Ah there you go. Like I said, it can provide help!

In purple and everything!

Some commands worth mentioning are PIP to copy or combine files (PIP can be used without any extra disks), ED to edit a file, DUMP to display a file and FORMAT to format a CP/M disk.

Have fun. Or perhaps: Have “fun“.