Skip to content

Plotting graphics

The Commodore 128 has a nice API for setting graphics mode and plotting graphics, that can be used in 40 column mode. The GRAPHIC command takes a mode (0 to 5) and a “clear screen flag”, and changes the current graphics mode. 0 is the 40 column text mode and 1 is the high resolution monochrome graphics mode. This program sets a few random pixels on the screen using the DRAW command:

10 GRAPHIC 1, 1
20 FOR A = 1 TO 100
30 DRAW 1, RND(1) * 320, RND(1) * 200
40 NEXT A

When the program is run, the text is hidden, so to retain the text cursor, just type GRAPHIC 0 and hit Enter. If you like, you can add this to your program.

The Commodore 64 does not provide any API for graphics, so on the C64 this task is accomplished by manipulating bits in a memory area. You can jump to graphics mode by setting the bit 6 on byte 53265 to 1 and return to text mode by setting it to 0. While plotting, you must make sure you know how to handle bit patterns. The screen area can be located at 8192 if we set a flag for this (bit 4 at byte 53272), like so:

10 POKE 53272, PEEK(53272) OR 8

The screen consist of 8000 bytes, so in this case from 8192 to 9191. Then, enter graphics mode:

20 POKE 53265, PEEK(53265) OR 32

Now we don’t have the service to get a clean color map (that is Commodore 128 luxury), so random boxes (8×8 pixels) will have strange colors. No worries, this is expected.

Finally, these lines of code will draw a few horizontal lines in the upper left 8×8 pixel area:

Set graphics mode

30 POKE 8192, 255
40 POKE 8193, 0
50 POKE 8194, 255
60 POKE 8195, 0
70 POKE 8196, 255
80 POKE 8197, 0
90 POKE 8198, 255
100 POKE 8199, 0

Click to view

When the program has run, you will not see the text cursor, but to restore everything, type:

POKE 53272, 21
POKE 53265, 27

…and our horizontal lines will be gone and the text cursor is back.

Restoring.

Categories: Geeky.

Tags: ,

Iterators in Visual Basic

The concept of iterators is well known to C# programmers, but it is new in Visual Basic (available in Visual Studio 11), so this post is probably only interesting for VB programmers. I got some great help from my friend Roger Alsing in explaining what it is that is good about iterators.

An iterator is similar to a function that returns a collection, but an iterator allows the caller to iterate before the collection is populated. The iterator is implemented as a function with the keyword Iterator, but it is actually compiled to an object.

Public Iterator Function Test() As IEnumerable(Of Integer)

This is an iterator named Test that returns integers. The return type declared must be an IEnumerable of the type your iterator contains. This iterator returns Integer values, and therefore the return type is set to an IEnumerable(Of Integer). This is a usage example of our iterator:

For Each I As Integer In Me.Test()
   MessageBox.Show(I.ToString())
Next

Of course, a bunch of integer values will pop up on screen. But lets check the full implementation of the Test iterator.

Public Iterator Function Test() As IEnumerable(Of Integer)
   Yield 10
   Yield 20
   Yield 30
End Function

When the For Each loop is done iterating, three message boxes have popped up. They first displays 10, the second 20 and the third 30. So why not just return an array of {10, 20, 30}?

Like I mentioned, a function that returns a collection must load the collection before returning it. Imagine that you want to return 10 objects, each object takes one second to load. This gives you a pause of 10 seconds before the iteration starts. Example:

Public Function ReturnTenThings() As List(Of String)
   Dim Ret As New List(Of String)()
   For I As Integer = 0 To 9
      Threading.Thread.Sleep(1000)
      Ret.Add((I + 1).ToString())
   Next
   Return Ret
End Function

This iteration will not start until 10 seconds have passed:

For Each X As String In Me.ReturnTenThings()
   MessageBox.Show(X)
Next

If we rewrite ReturnTenThings to be an iterator, like this…

Public Iterator Function ReturnTenThings() As IEnumerable(Of String)
   Dim Ret As New List(Of String)()
   For I As Integer = 0 To 9
      Threading.Thread.Sleep(1000)
      Yield (I + 1).ToString()
   Next
End Function

…the same iteration will still take 10 seconds to complete, but it will start after just one second.

Finally, a word of warning. If you need to know before you start your iteration, how many elements it holds, don’t just read the Count property of your iterator, because that will execute your code. If you need to know, copy the elements to a list, and read the Count property of that list. This code will take 20 seconds to execute, because the iterator runs twice:

MessageBox.Show(Me.ReturnTenThings().Count.ToString())
For Each X As String In Me.ReturnTenThings()
   MessageBox.Show(X)
Next

Categories: Visual Studio 11.

Stealing keys

Events and everything you might need to develop a user control, will tell you about mouse and keyboard activity so that you can respond the user correctly. If you want to be able to catch arrow keys or tab, you must overload this function:

Protected Overrides Function ProcessCmdKey(ByRef msg
   As System.Windows.Forms.Message, ByVal keyData
   As System.Windows.Forms.Keys) As Boolean

This method gets called no matter what key is pressed. Also, if you act on the key, and don’t want the original functionality, make the function return True. If you want the framework to act on the key press, make the function return False.

Categories: Visual Basic 10.

Download run.exe

It takes some clicking and fiddeling to install run.exe, the text based application starter. This post describes what you have to do and also how to use it. There are some arguments that are nice to know:

run -p

This displays all running processes together with an ID.

run -k 1234

This will kill process with ID 1234 (careful with this). And finally, to display your defined aliases, type:

run -a

Download run.exe from here.

Categories: Programs.

A text based start menu

Since I have tried everything (including RocketDock), this is what it has come to. I have made a text based start menu! I have my little personal setup with a folder that is handled by Dropbox so that it is available on all my computers. It is also specified in the PATH system variable, so I can access the scripts and programs without specifying the full path to them. The EXE file is called run.

Now, I can start CDBurnerXP by typing:

run "C:\Program Files (x86)\CDBurnerXP\cdbxpp.exe"

Also, passing arguments to programs are also supported, so this will open the a specified web page in

run "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" http://www.winsoft.se/

This might feel a bit odd, because this command can already be executed from cmd.exe, so what does the run command actually provide?

In the configuration file, you can point out a file that define aliases. The alias file consists of aliases for any phrase you like. By defining an alias for the Firefox path like so:

#DEFINE ff "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"

…you can start Firefox and open a specific address like so:

run ff http://www.winsoft.se/

And of course, you can add another line to your file to create an alias for the URL you want to visit, like so:

#DEFINE ff "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
#DEFINE winsoft http://www.winsoft.se/

Now, all you need to type to open WinSoft.se in Firefox is:

run ff winsoft

You can also use run to display running programs and close programs. More information and a download link to come.

Categories: Programs.

A physical C65 in action

There are some preserved footage of actual Commodore 65 machines out there. This first clip demonstrates some graphics capabilities. Note that you don’t have to specify the unit number when loading from disk.

This clip shows how to use the Commodore 65 in C64 “fast mode”.

Categories: Geeky.

Tags:

Comparing strings: What’s being compared?

In a simple loop, I compare ten million short strings with other strings. 1.4 million of them are identical. Depending on how the comparison is done, the execution speed differs. When the compare operator is used, the ten million tests are done in 0.31 seconds on my laptop.

If Strings(A1) = Strings(A2) Then

When the String.Compare function is used, the ten million tests are done in somewhere between 3.35 to 3.39 seconds. For me, case sensitive tests tend to be slightly slower.

If String.Compare(Strings(A1), Strings(A2)) = 0 Then

The reason that the equals operator is faster, is because it only compares the addresses where the strings are located, and since strings are unique in .NET, two strings with the same value, are stored in the same address. The Compare function looks at the characters in the string, and is therefore slower.

This is the disassembly for the test with the equals operator:

0000018f  mov         eax,dword ptr [ebp-50h]
00000192  mov         edx,dword ptr [ebp-48h]
00000195  cmp         eax,dword ptr [edx+4]
00000198  jb          0000019F
0000019a  call        67E075C0
0000019f  mov         eax,dword ptr [edx+eax*4+0Ch]
000001a3  mov         dword ptr [ebp+FFFFFF70h],eax
000001a9  mov         eax,dword ptr [ebp-54h]
000001ac  mov         edx,dword ptr [ebp-48h]
000001af  cmp         eax,dword ptr [edx+4]
000001b2  jb          000001B9
000001b4  call        67E075C0
000001b9  mov         eax,dword ptr [edx+eax*4+0Ch]
000001bd  mov         dword ptr [ebp+FFFFFF6Ch],eax
000001c3  push        0
000001c5  mov         ecx,dword ptr [ebp+FFFFFF70h]
000001cb  mov         edx,dword ptr [ebp+FFFFFF6Ch]
000001d1  call        558156C0
000001d6  mov         dword ptr [ebp-74h],eax
000001d9  cmp         dword ptr [ebp-74h],0
000001dd  sete        al
000001e0  movzx       eax,al
000001e3  mov         dword ptr [ebp-64h],eax
000001e6  cmp         dword ptr [ebp-64h],0
000001ea  je          00000201

This is the disassembly for the test with the String.Compare function:

0000018f  mov         eax,dword ptr [ebp-50h]
00000192  mov         edx,dword ptr [ebp-48h]
00000195  cmp         eax,dword ptr [edx+4]
00000198  jb          0000019F
0000019a  call        67F275C0
0000019f  mov         ecx,dword ptr [edx+eax*4+0Ch]
000001a3  mov         eax,dword ptr [ebp-54h]
000001a6  mov         edx,dword ptr [ebp-48h]
000001a9  cmp         eax,dword ptr [edx+4]
000001ac  jb          000001B3
000001ae  call        67F275C0
000001b3  mov         edx,dword ptr [edx+eax*4+0Ch]
000001b7  call        5E514300
000001bc  mov         dword ptr [ebp-74h],eax
000001bf  cmp         dword ptr [ebp-74h],0
000001c3  sete        al
000001c6  movzx       eax,al
000001c9  mov         dword ptr [ebp-64h],eax
000001cc  cmp         dword ptr [ebp-64h],0
000001d0  je          000001E7

It looks less, but it does more. The actual comparing is not shown, but it checks character until a mismatch is found. Since the difference is big, it’s important to pick the right method. If you add the compile option to compare text as text, the equal operator is almost just as slow as the String.Compare function, so the impact for this option…

Option Compare Text

…is huge.

Categories: Microsoft .NET.

Naming your images

I have been planning to do a PhotoName II for some while now, and here it is. Because of the different take on this application, I also decided to change it’s name from PhotoName II to RenameImg (short for Rename Image). The main difference is that this has no graphical user interface, you use it from your text console. It takes a few clicks to install this, but when it’s done, it is easy to upgrade and you have a friend for life.

If you are planning to run RenameImg from PowerShell, you must have given yourself the right to execute scripts, and to be able to do that, you must start PowerShell as an administrator. You only have to do this once, regardless of what scripts or programs you want to run from PowerShell. If you are planning to run this from your old command prompt (cmd.exe), you don’t have to do anything.

The next thing you have to do, is to unzip the exe file and give it a suitable location on your system. Your console must be able to reach the exe file. I have created a folder on my machine where I put all my console applications and cmdlets. That folder is then pointed out in the Path system variable. This makes it easy to start the application, because all I have to do, is to type renameimg in the console. When started without any arguments, RenameImg will rename all JPG images in the current folder Just like DIR lists the files in the current folder when executed without arguemnts, RenameImg will rename the files in the current folder when started without arguments. I will talk about the supported arguments you can pass to RenameImg in a later post.

Now, if it finds any JPG images that haven’t already been renamed using RenameImg, it will list them and ask you if you want them renamed, and if you answer yes, RenameImg will rename each image to a filename that looks something like this:

D20110504T204540_13045X32648P15591.jpg

The new name will consist of:

The capital letter D.

The date the image was taken according to the EXIF (YYYYMMDD).

The capital letter T.

The time of day the image was taken according the the EXIF (HHMMSS).

An underscore.

Up to five numeric digits from the original filename. If less than five numeric digits are available, random digits are used.
The capital letter X.

A random number (five digits).

The capital letter P if the date and time actually is taken from the EXIF. If not, the capital letter C indicates that the date is the file creation date.

Finally, before the file ending, a serial number, that is previous image’s number plus one, or a random number if the image is first in the batch (five digits).

The file ending is .jpg (lowercase).

By using this naming standard on your images, you can store all your images in one single folder on your hard drive. Also, you can use the name as the unique identifier if you are storing your images in a database. Finally, pictures are always displayed chronologically in media players and you can know when the picture is taken just by looking at the name of the file.

You can download RenameImg from here.

Categories: Programs.

Tags:

Dagens konflikter

Trött efter att ha bråkat med Stefan Attefall och hamnat i konflikt Anders Gustafsson. Jag tror att jag har polariserat skeptikerrörelsen idag.

Men jag fick en trevlig avslutning med brorsan och brorsdöttrarna. ;-)

Categories: General.

Tags:

5 musikaliska genier, utan inbördes ordning

Helt oberoende av musikstil eller vad jag lyssnar på (vilket ibland är samma sak), dessa fem musikaliska personligheter har en bidragit med svåröverträffade gärningar i musikbranschen.

Categories: General.