COMMODORE: Finished the 1541-II Installation

by Payton Byrd 14. February 2012 14:02


2012-02-14_13-27-05_330Here’s the final result of the 1541-II Installation.  To get it looking nice required a new case as the eMachines case’s faceplate just got too jacked up from all the cutting to make the drive’s Chinon faceplate fit.  It winds up being a better install because the new case actually has room for the DVD drive, too.  A cool feature of the case is that the drive bays are covered in mesh and you can see the 1541-II power and activity lights through this mesh.  Overall I’m very happy with the outcome of this project.

Tags:

PROGRAMMING: Fun, fun, fun!

by Payton Byrd 28. January 2012 01:41

Writing binary object serializers from scratch in C is fun.

NOT!

Tags:

Commodore | Programming

COMMODORE: Installing a 1541-II into my C= PC

by Payton Byrd 26. January 2012 11:51

About a year ago I bought a device from Jim Brain called the ZoomFloppy.  This is a USB device that acts as a hub for the Commodore IEC and IEEE based hard drives that allows PCs, Macs and GNU/Linux boxes to read and write floppy disks using a 1541 or 1571 disk drive.  The ZoomFloppy interfaces with the user with software called OpenCBM, which is a device driver and utility set for manipulating Commodore disk drives and disk images (currently the disk drive models available for use is a function of the OpenCBM software, not the ZoomFloppy hardware).  The main function of ZoomFloppy and OpenCBM is the archiving and preservation of old floppy disks, although some people still use this setup to move disk images to real hardware and back.

A couple of weeks ago I decided that my ZoomFloppy had been sitting idle for too long and that it needed to be put to good use.  One reason I don’t use it very much is that it’s a big, naked circuit board that adds clutter to my desk.  I decided to do something about that: install it, along with a floppy drive, to the PC that I use to work with the ZoomFloppy.

When I dreamt up this project I had envisioned using an old-school 1541 disk drive and controller board.  I had a unit already disassembled and ready to go so I grabbed it and did some measuring and quickly realized that this would be a problem.  First, the controller board is too big.  It’s massive, as a matter of fact, nearly as big as the motherboard of a Commodore 64c.  There simply would not be room to fit this controller board in the computer.  Second, even if I could fit the controller board in the computer I couldn’t get power to it.  It has it’s own AC-DC conversion circuit on the controller board and I didn’t want to reverse engineer the board to figure out where the conversion circuit’s outputs were and then drill holes to solder in wires.  So, the classic 1541 was out. 

Luckily, Commodore released the 1541-II, which is a cost reduced version of the 1541 disk drive.  The major changes were mostly packaging.  The 1541-II reduced the size of the controller board considerably, mostly through the elimination of the AC-DC conversion circuit and replacing it with an external power brick.  This makes the 1541-II the perfect drive for this project because the controller board fits into a standard 5.25” drive bay and the power for the board is provided by a cable that supplied +5 VDC and +12 VDC, which happens to be the same voltages supplied by the power supply of a modern PC.  Unfortunately, I didn’t have one of these drives.

Luckily, Daniel Mackey, who’s a great guy and avid Commodore nut, was willing to trade a perfectly good 1541-II with some cosmetic damage for a few carts from my collection.  Soon I had my 1541-II and was ready to go!

2012-01-26_11-16-53_722The first thing I had to do was some planning on where to put the components.  I had already realized that in the 2 years that I’ve owned the PC involved that I’d never used the DVD drive.  Almost all the software I buy these days is digitally delivered and the DVD drive is going the way of the dinosaur.  Removing the DVD drive gave me the two 5.25” bay slots I needed to complete this project.  The next consideration was where to put the ZoomFloppy.  Fortunately, the machine being used generates little heat as it doesn’t have a monster CPU, so there’s no case fan on the back, yet there is a very large open space to mount one.  It just so happens that the ZoomFloppy fit into this location perfectly (as you can see in the picture to the left, the ZoomFloppy is the blue circuit board).  To mount the ZoomFloppy, I used a sheet of industrial hook-and-loop (also known as Velcro) tape.  The ZoomFloppy can be easily removed if desired.  The ZoomFloppy connects to the 1541-II controller board via a 12” IEC cable sourced from Jim Brain.2012-01-26_11-16-35_551

Once I had the ZoomFloppy in place, I had to install the 1541-II into the computer.  This was very  easy to do.  I disassembled the 1541-II that Daniel had sent me, separating the controller from the disk drive.  This simply required unplugging three connectors.  In the 1541-II’s case, the board is oriented below and behind the disk drive.  In this new installation it would be directly below the drive.  This meant that I had to cut a tie-wrap holding the controller cable for the floppy drive to give it enough space to stretch to the relocated board.  This was literally the only modification to the 1541-II itself!  As you can see in the picture to the right, the 1541-II’s drive mechanism and controller board slide right into place.  The only downside to using the 1541-II is that it’s drive mechanism doesn’t include a faceplate.  Commodore saved money by molding the front of the disk drive as the face plate, and the disk drive’s case doesn’t lend itself to being cut up to make a face plate. :(

2012-01-26_11-17-04_469 The final step in completing this installation was providing power to the disk drive.  This was done by cutting the power cord that plugs into the disk drive and placing a male molex connector on the end of it, then simply plugging the new cable into the appropriate places inside the computer.  Making this cable was the hardest part of the whole project and took about 15 minutes including waiting for the soldering iron to heat up. :)  For the record, if you should choose to replicate this project, the power cable from the 1541-II must be wired up as follows:

Connection 1541-II Molex
Ground Black Black
+12 VDC Red Yellow
+5 VDC Green Red

 

The only thing left for me to do is modify the faceplate of this computer.  It doesn’t have standard 5.25” openings for me to use, so I’ve got to do some cutting on the plastic which I’ll probably accomplish this weekend.  I’ve fired everything up and transferred some disks to images and it works great!

Tags: , ,

Commodore | Mods

COMMODORE: Plans for CBM-Command 3.0

by Payton Byrd 23. January 2012 22:54

CBM-Command is a project I started about 2 years ago.  It’s an Orthodox File Manager similar to Norton Commander for DOS and runs on the Commodore 64, Commodore 128, Commodore VIC-20, and Commodore Plus/4 computers.  There’s also a port to the Apple II computers called A2Command.   Currently, CBM-Command is up to version 2.1.

Now that I’ve learned how to design for and implement overlays in CC65, I can start thinking about how to expand CBM-Command to meet some user requests.  With previous versions, I simply could not fit any more features into the program without running out of RAM, overlays will allow a nearly infinite amount of features.  Here’s a list of some of the features I want to implement in CBM-Command V3.0.

  1. Break out Disk Image functions to an overlay and support more formats, such as DNP.
  2. Break out Disk Copying functions to an overlay and support bigger buffers to improve performance, possibly even using a REU to cache entire files so that they can be read and written in a single pass.
  3. Disk defragmenter with customizable interleave.
  4. Move the reading of directories to an overlay which can optionally use a REU to provide enough RAM to sort even the largest directories on devices such as the uIEC.  The directory would stay in memory of the REU and would simply be paged to main memory for display and batch operations.
  5. Update the text file reader with the following features:
    • Allow scrolling one line at a time, in both directions
    • List BASIC programs
    • Show PETSCII art files
  6. A directory editor for the following specific formats:
    • 1541/1571
    • 1581
    • CMD-HD/FD
  7. A module for managing the Flyer Internet Modem.

So what features do you think CBM-Command should gain for Version 3.0?  Feel free to comment below.

Tags:

Commodore

PROGRAMMING: Introducing Worlds@War

by Payton Byrd 22. January 2012 23:51

Some people are already aware of the fact that I’ve started a new programming project.  This project is a fairly significant game called Worlds@War and is for the Commodore 64 computer.  Worlds@War is a space game similar to Master of Orion.  You start as one of five unique races, each with their own strengths and weaknesses.  These races start with a single planet in a rather large galaxy which contains 30 star systems (each with up to five planets) on a 30x18 parsec map.  The maps are randomly generated allowing for an infinite amount of game replay. 

The first version of the game will be single player against 4 AI opponents.  The AI opponents will treat each other exactly the same as they treat you, so you don’t have to worry about any collusion.  There will be no diplomacy, everyone will be at war.  You will have to build your economy quickly and get your fleet out as fast as possible!

Each planet you colonize will be one of several types with attributes for size (which determines max population) and gravity (which determines worker productivity).  Some planets will support life natively and some won’t.  You will have to pick and chose the planets you colonize wisely!

Each turn your planets will produce food, credits, manufactured goods, and science.  Your empire can attain wealth and power through a strong economy and/or bloody battles.  The last empire standing wins.

I’ve made a lot of progress on the structure of the data for the game and setting up the new galaxy.  Each major function of the game (setting up the galaxy, combat, planetary screens, science research) is an overlay so that since this is a single player, single turn game, only one of these things can be used by the player at a time.  This allows the maximum amount of RAM for the game data and the game code for each activity.

I haven’t decided if I want to try to sell the game or release it as “donation-ware”.  I have no delusions that I’m going to make any real money off of it, but maybe Protovision might pick it up and help me earn a few bucks with it.  If not, that’s ok too.  I’m doing the project to have fun, and eventually have a game that I can play myself!

Tags:

Commodore | Programming

CC65: Using Overlays

by Payton Byrd 22. January 2012 09:44

Note: Much of the information in this blog post comes from Oliver Schmidt.  I’m simply passing along my experiences with this topic in hopes of documenting it thoroughly for other people to enjoy.

CC65, the cross-compiler system for 6502/65816 computers, is very powerful.  One of the most powerful features is the ld65 linker which allows you to create executables that are extremely flexible.  One use case allowed by the linker is the ability to create overlays, or code fragments that reside at the same memory location and are loaded into RAM dynamically as needed.  This is an extremely useful feature for writing large applications that will not fit into the typically tight memory configurations of 6502-based computers.

Creating an application with overlays does require some planning ahead of time.  You must make some decisions about how much RAM to allocate to the main program and how much to allocate to the overlays.  The results of these decision is documented in the linker configuration file.  You must define some SYMBOLS that the linker will use as variable.  The SYMBOL that most affects us is __OVERLAYSIZE__.  This SYMBOL specifies the size of the overlay (note your overlay does not have to consume all of this memory, but it cannot consume more than this amount of memory).  The __OVERLAYSIZE__ SYMBOL is used in the MEMORY definitions to allocate the memory of the overlay.  Overlay memory should be defined by starting at the top of RAM available for cc65 and work down.  In the case of the C65, we define the top of RAM to be $D000 (you can make it higher by banking out I/O and Kernal ROM, but that’s beyond the scope of this article).  So the start of RAM for the overlays is $D000 – __OVERLAYSIZE__.  The linker config file also specifies the name of the overlay file to be written.  We will use a naming convention where the name of the main executable is used, followed by an index for the overlay.  Your SYMBOLS and MEMORY sections should look like this:

Code Snippet
  1. SYMBOLS {
  2.     __LOADADDR__:    type = import;
  3.     __EXEHDR__:      type = import;
  4.     __STACKSIZE__:   type = weak,   value = $0800; # 2k stack
  5.     __OVERLAYSIZE__: type = weak,   value = $1000;
  6. }
  7. MEMORY {
  8.     ZP:       file = "", define = yes, start = $0002, size = $001A;
  9.     LOADADDR: file = %O,               start = $07FF, size = $0002;
  10.     HEADER:   file = %O,               start = $0801, size = $000C;
  11.     RAM:      file = %O, define = yes, start = $080D, size = $C7F3 - __STACKSIZE__ - __OVERLAYSIZE__;
  12.     OVL1:     file = "%O.1",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
  13.     OVL2:     file = "%O.2",           start = $D000 - __OVERLAYSIZE__, size = __OVERLAYSIZE__;
  14. }

Note also the RAM memory definition.  This takes the normal amount of RAM allocated for our program, which is $C7F3 bytes, and reduces it by the size of the overlay.  This is where our main program and variables go.

In addition to defining the MEMORY section of the configuration file, we must now use those MEMORY definitions to declare memory SEGMENTS which are used to link together the application.  These segments are used by the linker to determine things such as the beginning RAM for each block of 6502 assembly code that is generated by the compiler or specified by the programmer.  Here is the SEGMENTS section of our configuration file:

Code Snippet
  1. SEGMENTS {
  2.     LOADADDR: load = LOADADDR, type = ro;
  3.     EXEHDR:   load = HEADER,   type = ro;
  4.     STARTUP:  load = RAM,      type = ro;
  5.     LOWCODE:  load = RAM,      type = ro,                optional = yes;
  6.     INIT:     load = RAM,      type = ro,  define = yes, optional = yes;
  7.     CODE:     load = RAM,      type = ro;
  8.     OVL1CODE: load = OVL1,     type = ro,  define = yes;
  9.     OVL2CODE: load = OVL2,     type = ro,  define = yes;
  10.     RODATA:   load = RAM,      type = ro;
  11.     DATA:     load = RAM,      type = rw;
  12.     ZPSAVE:   load = RAM,      type = bss;
  13.     BSS:      load = RAM,      type = bss, define = yes;
  14.     ZEROPAGE: load = ZP,       type = zp;
  15. }

Of note to our overlay use case are the OVL1CODE and OVL2CODE segments.  What these SEGMENTS do is define memory allocations for TWO overlays.  If you will need more overlays you will need to define more SEGMENTS.  You should also name these segments such that they are easy to identify which will make your code easier to read when you generate the overlay specific code in your C or assembler sources.

The rest of the linker configuration file is not pertinent to this discussion.  I will post an archive in a later article that includes the complete linker configuration file, but this should be enough to get you started.

Now that we have our linker configuration done, we can turn our attention to the code necessary to implement overlays.  There are four topics that need our attention:

  1. Specifying the code that is included in an overlay.
  2. Specifying the literals that are included in an overlay.
  3. Linker defined macros that specify values for the load address and size of our individual overlays.
  4. Loading the overlay to RAM.

Specifying the code in an overlay

To create overlays, the linker needs to know what compiled code modules need to be located in the overlay memory segment.  This is done through the use of the code-name pragma (please read the link for a full description of this pragma).   In our example, that pragma points to either OVL1CODE or OVL2CODE.

Specifying the literals in an overlay

One side effect of creating overlays and using the code-name pragma is that your string literals define in the overlay code do not reside in the overlay by default, but rather will go into the main string table of the application.  If your application is tight on RAM this is not the optimal use of that RAM and you will want your string literals for the overlay to reside in the overlay.  To accomplish this we use the rodata-name pragma (please see the link for a full description of the pragma) to define where in memory these string literals are placed. 

Although not strictly necessary, I highly recommend putting the code for each Overlay into a separate source code file.  This is just a good idea from a code management perspective and allows you to not use the compiler stack to define the scope of the pragmas.  Here is a sample overlay:

Code Snippet
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5.  
  6. #pragma code-name ( "OVL2CODE");
  7. #pragma rodata-name ( "OVL2CODE");
  8.  
  9. int overlay2()
  10. {
  11.     printf("This is overlay 2.\n");
  12.     return 1;
  13. }

Getting the size and location of an overlay

Overlays are incredibly easy to use, but they are not magical.  Your main program still has to have some knowledge of the size and location of an overlay if it is to load the overlay into RAM.  To facilitate this, the linker can populate a pair of macros that provide this information to you code.   These macros are used like constants in your application and follow a naming convention so you know what to put in your code.  That naming convention is _{MEMORY SEGMENT}_LOAD__ for the load address of the overlay and _{MEMORY SEGMENT}_SIZE__ which is used to get the compiled size of the overlay (not the value of the __OVERLAYSIZE__ symbol).  Note that these constants are pointers and must be treated as such.  Here is an example of using these macros:

Code Snippet
  1. extern void _OVL1CODE_LOAD__, _OVL1CODE_SIZE__;
  2. extern void _OVL2CODE_LOAD__, _OVL2CODE_SIZE__;

Loading the overlay to RAM

Finally, we must load our overlay to RAM.  This uses the constants defined above to provide the information necessary to load the overlay.  Loading a binary file to RAM is pretty simple, but one thing you need to know is that the overlay files do NOT include a load address, so you may not use cbm_load, which is something I learned the hard way. :)

Here is a loader that takes the information about the overlays and loads them on demand.

Code Snippet
  1. bool loadOverlay(char *overlayName, void *startAddress, void *size)
  2. {
  3.     static char filename[21];
  4.     
  5.     unsigned int r = 0;
  6.     
  7.     sprintf(filename, "%s,p,r", overlayName);
  8.     r = cbm_open(2, _curunit, 2, filename);
  9.  
  10.     if(r == 0)
  11.     {
  12.         r = cbm_read(2, startAddress, (unsigned)size);    
  13.  
  14.         cbm_close(2);
  15.  
  16.         if(r == (unsigned)size)
  17.         {
  18.             sprintf(messageBuffer, "Read %s (%u bytes) from %d.", overlayName, r, _curunit);
  19.             log(messageBuffer);
  20.         }
  21.         else
  22.         {
  23.             sprintf(messageBuffer, "Error on %d reading %s, %d", _curunit, overlayName, _oserror);
  24.             log(messageBuffer);
  25.         }
  26.  
  27.         return r > 0;
  28.     }
  29.     else
  30.     {
  31.         sprintf(messageBuffer, "Error on %d opening %s, %d", _curunit, overlayName, _oserror);
  32.         log(messageBuffer);
  33.     }
  34.  
  35.     return false;
  36. }

 

 

 

**please note that log() is a helper method defined elsewhere in my framework that I’ll be posting later.

This method is called in the following manner:

Code Snippet
  1. if(loadOverlay("overlaytest.c64.2", &_OVL2CODE_LOAD__, &_OVL2CODE_SIZE__))
  2. {
  3.     overlay2();
  4. }

**Your code should always test that the overlay was successfully loaded before attempting to call the methods of that overlay!

And that’s it!  You are now ready to use overlays in your own application!  Feel free to post questions or comments below!

PS.  The configuration and other elements of this article are based on the newest nightly snapshot of CC65 at the time of the writing of this article.  If you are using older or newer versions of CC65 you may have to adjust your linker configuration file as appropriate.

Tags: ,

Commodore | Programming

RANT: HostMySite.com and .Net 4.0

by Payton Byrd 22. January 2012 02:25

<rant-on />

Today was a busy day, and in the middle of that busy day came an unpleasant surprise.  I’ve been a HostMySite.com customer for nearly 5 years now and they’ve done me dirty a couple of times.  First last year, they took away the free WordPress blog that was part of the .Net Developer package I had been a subscriber to since July of 2006.   They offered to continue hosting the blog for me, but I’d have to buy a separate GNU/Linux hosting plan to do so.  NO THANK YOU.

So today I finally decide to update my BlogEngine.Net from 1.4 to 2.5.  Version 2.5 is for ASP.net 4.0.  I go to the HMS.com control panel, and there’s a nice option to change my website from ASP.Net 2.x to ASP.Net 4.0.  I select it.  It fails.

So I open a support chat.  A lady named Shannon gets on and I describe my problem.  She then proceeds to explain that to use ASP.Net 4.0, I have to upgrade to a new plan.  However, this new plan must be purchased individually and run in parallel to the old plan until the migration is complete.  Additionally, my user names and passwords will all change because it’s a new plan.  Great, just freaking great.  Fortunately we were able to keep my SQL Server and Email settings the same and just re-associate them to the new account.

So I purchase the “upgraded” account and Shannon gets everything migrated over.  Unfortunately, I cannot rename the technical user for some reason and it’s this horribly complicated artificial name.  Also, I still cannot log into my FTP site despite the fact that the FTP Manager shows the technical contact is supposed to be able to log in.  To say I’m frustrated is an understatement.

<rant-off />

Tags: , ,

Rants

The Random Rants, Version 3.0

by Payton Byrd 22. January 2012 01:53

I've finally gotten around to updating my blog, which has sit abused and forgotten for well over a year since Host My Site took down my Wordpress blog.  I've updated to the latest and greatest version of BlogEngine.Net and couldn't be happier with it.  You can look forward to a lot of content in the near future as I do not plan on releasing any more blog entries to IT Toolbox and I do have a lot to say on a lot of topics.

Tags:

Blog

About the author

Payton is married to Rebecca Lynne Byrd and has three wonderful children, Mary, Robert and JT.  Payton is a professional software developer and currently works as contractor for Link Systems in Nashville, TN and Tool Planners Inc in Hendersonville, TN.  Payton also is an active member of the Commodore 64 scene having recently created and released demos and original music.  Payton is the creator of CBM-Command, which is an Orthodox File Manager for the Commodore 8-bit line of computers.

Month List