It all started…

with a short blurb from a video by Dave Murray, The 8-bit Guy, called The Quest for 80 Columns on the Commodore 64.  He was talking about getting an 80 character display on the Commodore 64.  In it, he was demonstrating the Batteries Included cartridge and noted that it has very little software available for it in 80 character mode.  He wanted to see if his program called Pet Draw could be modified to work on the 80 column screen.  At around 10 minutes into his video, he describes Pet Draw and one of the features that it has, which is to draw in a “pseudo bitmap mode” using the C64’s block characters.  Pet Draw would figure out the correct character to use when drawing lines and shapes with it. It was cool, but I didn’t do much PETSCII art, so it was not something I had thought about using.

Later, I came across a BASIC extension package called EXBASIC LEVEL II.  It was a basic extension package that, unlike Simons’ Basic, did not extend the basic with bitmap commands.  The extension seemed more geared to assisting with programming music and character graphics displays.  It’s hard to be completely sure because the only manual I can find for it is in German.

What I did figure out was the commands, SET, RESET, & POINT. These commands did exactly what the 8-Bit Guy’s program did, but with BASIC commands.  Once I started playing with them, I found the ability to plot small blocks using an x, y axis in BASIC to be a pretty useful feature. I hated that I would need to load EXBASIC every time I wanted to play with them.  I also didn’t like the fact that if I wanted to share something I wrote, I would need to note that it only works on C64s that had EXBASIC installed.  It also made the ability to compile any BASIC programs impossible.  In the end, I decided to write my own machine language utility that I could either have installed within the BASIC program using DATA statements, or have the BASIC program automatically load it at the start of the program execution.

So I set out to write this utility.  I had a few goals in mind.

  1. It needed to give me the ability to plot a point, remove a point, and check to see if a point was already plotted.
  2. It needed to use a simple X, Y coordinate system to plot the points.
  3. It needed to have color easily controlled.
  4. It needed to only use the built in BASIC commands without alteration so that it could be compiled.
  5. It needed to check to make sure if X or Y was out of range, and would stop execution of the BASIC program with an ILLEGAL QUANTITY error.

The last one is on the list last because as I was writing the utility and testing it out with my BASIC programs, I would occasionally have the Y coordinate go beyond the 50 points allowable and destroy my BASIC program mercilessly until if failed to function.

I also wanted to put the program somewhere out of the way that may help in not interfere with other ML programs that the user might want to use with it.  I decided to tuck the program into the last 300 bytes of memory in the 4K block starting at 49152 ($C000).  That puts it right before the VIC-II registers/Character ROM starting at 53248 ($D000).

Download the .D64 and let’s check it out.

Load and list the file:  CPLOT-LOADER. The program loads the ML code from the disk called “CPLOT” and then sets up some variables.  This file can be used as the start of your own programs that use this utility.  There is also a file called, “CPLOT-BASIC” which installs the ML program using DATA statements if you don’t want to have to include the CPLOT program with your own BASIC program.  The variables are used to help run the commands.  You could use the direct memory addresses instead of these variables.  I like using the variables for shorthand.

So first run the program and then try this:

POKE PX,0:POKE PY,0:POKE PC,0:SYS PS

This will give you a black square at the very top left of the screen. Try poking a few different values into PX and PY followed by the SYS PS command to see where a square gets plotted.  If you enter a value greater then 79 for PX or greater than 49 for PY, you will get an illegal quantity error.  Try changing the value of PC as well.  You will be changing the square’s color. Always remember to follow up the POKE commands with the SYS command.

Check out the program to the right.  Lines 100 – 130 are from the CPLOT-LOADER program on the disk.  Type in the rest of the program to see what it creates and how easy it is to plot using this utility.  All the hard work is done by the utility. You are allowed to plot blocks anywhere on the screen and color them with any of the 16 colors available.  The catch with color is that it still must follow the 8X8 color cell rule of the text screen. That’s because the program is using the built in PETSCII characters to draw the display.  This also means that if you program your own character set, these would have to be copied over in their original locations to work (or adjust the ML program).

Available commands:

PLOT SET (PS)    SYS PS  or SYS 53150
Plot a point using the values in memory locations PX (53203) for X, PY (53204) for Y, and PC (53205) for color.

PLOT RESET (PR)  SYS PR or SYS 53165
Remove a point using the values in memory locations PX (53203) for X, and PY (53204) for Y.

PLOT POINT (PP)  SYS PP or SYS 53187
Inquires the status of a point to see if it is on or off. PX and PY must be set to the coordinate to be checked.  After the SYS command is executed the memory location PI (53206) would need to be PEEKed to determine the status.  0 = empty.  >0 = occupied.

Variables / Memory Locations:

PX  –  POKE PX or POKE 53203
The X-coordinate.  Valued from 0 to 79.  0 is the left-most side of the screen.  A value greater than 79 will produce and illegal quantity error and stop program execution.

PY  –  POKE PY or POKE 53204
The Y-coordinate.  Valued from 0 to 4.  0 is the top-most part of the screen.  A value greater than 49 will produce and illegal quantity error and stop program execution.

PC  –  POKE PC or POKE 53205
The color to be plotted. This follow the normal 0-15 color palette of the C64.  Numbers greater than 15 will still produce one of the 16 colors.

PI  –  PEEK PI or PEEK 53206
The status of the point at location PX,PY.  The PLOT POINT Command must be run first to update this memory location.  A value of zero indicated an empty point.  All other values indicate an occupied point.

A Few Examples

To show off what you can do with this utility, I included a few demo programs to play around with.  All use standard BASIC and I compiled some of them using the Blitz compiler.  Check them out to see what is possible.

BIORHYTHM calculates the biorhythm of an individual based on they’re birth-date and target date.  This program uses the PLOT and COLOR features of CPLOT to graph out the different biorhythms of people.

MAZE draws a maze by meandering around the screen until it gets trapped and then backtracks to an un-trapped location and continues.  Maze uses the PLOT and POINT features of CPLOT.  POINT Checks to see of a location already has a square in it.  There is a compiled version called C/MAZE.

C/MAZE-COLOR.  There is only a compiled version of this program because it is almost exactly the same as MAZE.  I changed  or added the following lines:

Change:
140 POKE53281,0:POKE53280,0:PRINT"{CLR}":CL=0
150 M=49152:SK=0:C=INT(RND(1)*15)+1:POKEPC,C

ADD
505 C=INT(RND(1)*15)+1:POKEPC,C

SNAKE is the classic game of snake where you move around the board, growing when you “eat” some food.  You must avoid the walls and your growing body.  Snake uses the PLOT, RESET, POINT and COLOR features of CPLOT.  There is a compiled version of this called C/SNAKE.  On the compiled version, if you’re feeling like the game is too easy, you can speed it up by poking a value into memory location 9125 in direct mode once the program is loaded.  This does not work on the un-compiled version.

POKE 9125,48+x

Where X=0 to 9
0 is the fastest, 9 is the slowest.
The default setting is 4

Data Maker

One last thing to talk about in this post.  I’ve added another program to the disk called DATA MAKER.  What it does is looks into memory where the ML program is located and generates DATA statements that install the program into your BASIC program so it doesn’t need to load the program from the disk every time you run the program.  Normally, if you plan to use the utility, I would recommend you start with the CPLOT-BASIC and add your program into it.  If, on the other hand, you had already written your program and want to add this utility, or you were using the disk loader and decided you wanted it to load internally from your current program, you can use this program.  It’s a bit of a sideways way to add the DATA, but it works well enough for me.

First, load CPLOT into the computer using LOAD”CPLOT”,8,1. This puts the machine language in the proper location in the computer.  Next load your BASIC program into the computer. The next step requires you to either type in the program below, or to copy it from below and paste it into your own program using an emulator such as VICE. Your program will also need to be free of statements from lines 5000 to 6000.  Next, run the program below with a RUN5000 command.  This will cause the computer to PEEK from memory the machine language and build DATA statements with them.  It uses the first memory address of the data to address the DATA line. It prints the 9 BASIC statement on the screen, plus a RUN command at the end.  Then, the computer fills the keyboard buffer with a series of returns (CHR$(13)) and tells the computer the buffer is full.  With the cursor properly placed, the program ends, forcing the computer to hit return 10 times on the screen editor creating the actual program lines into code.  The last return hits the RUN5080, and the process continues until all the DATA is created.  The current line number has to be broken into two bytes and stored in memory with POKEs because the variables lose their information when a new program line is created.

5000 ms=52948:me=53245:fs=49152:fe=fs+2
5010 sh=int(ms/256)
5020 sl=((ms/256)-sh)*256
5030 eh=int(me/256)
5040 el=((me/256)-eh)*256
5050 pokefs,sl:pokefs+1,sh
5060 pokefe,el:pokefe+1,eh
5070 rem -------------------------------
5080 fs=49152:fe=fs+2:printchr$(147):print
5090 sl=peek(fs):sh=peek(fs+1)
5100 el=peek(fe):eh=peek(fe+1)
5110 ms=sl+sh*256
5120 me=el+eh*256
5130 c=0
5140 l$=str$(ms)+" data "
5150 by=peek(ms):by$=str$(by)
5160 l$=l$+right$(by$,len(by$)-1)
5170 ifms=methenprintl$:goto5260
5180 iflen(l$)<35thenl$=l$+",":ms=ms+1:goto5150
5190 printl$
5200 ms=ms+1
5210 ifc<8thenc=c+1:goto5140
5220 sh=int(ms/256)
5230 sl=((ms/256)-sh)*256
5240 pokefs,sl:pokefs+1,sh
5250 print"run5080"
5260 printchr$(19);
5270 fori=0toc+2:poke631+i,13:nexti
5280 poke198,c+2
5290 end

After the DATA statements are written, the BASIC lines written between 5000 and 5290 are manually removed and a few more lines of basic code are created to write the ML program. You could either type this in, or copy/paste it into an emulator.

50000 rem load ml program
50010 print"please wait";
50020 forn=52948to53245
50030 readl:poken,l
50040 nextn
50050 ps=53150:pr=ps+15:pp=ps+37
50060 px=ps+53:py=px+1:pc=px+2:pi=px+3
50070 return

Finally, add a GOSUB50000 somewhere at the beginning of your program to install the machine language, and you’re ready to go.

This was a fun and satisfying little utility to write that I hope other people find useful,  Next time I’ll get into detail on how I created the utility, and why I made some of the choices I did.

-M