Understanding TRS-80 CMD Files

I had originally published this text on Sunday, November 8, 2009. Reworking it for the newer blog reminded me that I need to pick up the Z-80 assembler and write more for the venerable Model I!

There is some C code in this post, but the main point of the post is to provide a way to dump TRS-80 binary CMD files.

Here’s the older post with a few updates to the C source code.

I’ve begun to use TRS-80 Model I emulators to recapture some of the programming experiences of my younger days. The emulator I’m currently using under Windows is trs80gp which can be found here:

http://members.shaw.ca/gp2000/trs80gp.html

I invoke the emulator with the command-line parameters -m1 to force Model I emulation and -na for non-authentic display.

While trs80gp does not support any of the Disk-Operating-Systems of yesteryear, it does provide a menu option that will load /CMD executable files and BASIC files. You really can’t save any information back to the Windows filesystem, but that’s okay. For my purposes, I want to write some programs in a cross-assembler or cross-compiler environment and will just load the files to try them out. At some point, I will either look for or will build a utility that will tokenize a text listing to a BASIC listing so that I can create BASIC programs as well.

My initial goal, however, is to write Z-80 code and run it on the emulator.

My first task was to find a cross-assembler for the Z-80 that would run under Windows. The trs80gp site references ZMac which sounds like a great editor, but it doesn’t appear to compile in its current form under Windows.

I found a utility called Pasmo here:

http://www.arrakis.es/~ninsesabe/pasmo/

Like some of the others I tried, Pasmo basically generates a binary machine-image file. I chose Pasmo because of the -d option which shows an assembly listing on the standard output device.

I would like to be able to package up anything I write into a standard /CMD file so that it can be used with other emulators or on the real hardware itself. In order to do that, I was going to have to determine how to convert a machine-image file into a /CMD file.

As a test program, I would use the example routine I published in my post http://www.mailsend-online.com/blog?p=54. That routine fills the video memory with the all-white character (191) and then returns.

I have several /CMD images of games that I have on cassette and began looking through them. I could see some control-codes and such, but my initial stab at trying to interpret them was not successful. After a little searching on the web, I found a reference to an article from The LDOS Journal volume 1, issue 4. Tim Mann has copies of this issue and others on his site here:

http://www.tim-mann.org/misosys.html

The article that describes the format is in the column Roy’s Technical Corner.

Roy describes the record formats permissible in a /CMD file. The format is not unlike the binary tag-based system used in the TIFF graphical image file format. The first byte one encounters is a record-type byte. The next byte is a length of bytes that will follow … sort of. The remainder of bytes should match the length specified in the length byte. The next record in sequence should be another record ID / length / payload sequence, but that doesn’t seem to hold true either.

I wrote a short C program readcmd.exe that lists each record in a /CMD file. While number of my /CMD files parsed correctly just fine, some did not.

Roy explains that the 01 record indicates a loadable block of binary data. The length byte in many of my /CMD files was zero, which I correctly assumed would yield a 256-byte block. However some of the /CMD files in my possession use a value of two in the length byte and seem to have a payload bigger than two bytes in length.

The article further explains that each loadable block of data first contains a load-address and states that zero and one are special values that indicate a two-byte load-address will be followed by 254 and 255 bytes of data respectively. The article doesn’t mention the value two, but I assume that since the 01 record will always have a load-address, two bytes will always follow. The values zero, one, and two are then used for machine-images of size 254, 255, and 256 respectively. The value three is a complete mystery to me. I have seen a small block with a length of four and the payload that follows the load-address is four bytes in length. I’ll tinker later and see how the emulators load a record with a length value of three.

I should state that my readcmd program is dependent on the Intel representation of a 16-bit integer ( Least Significant Byte followed by Most Significant Byte ). An unsigned short integer must be 16-bits in width in order for the program below to run correctly.
readcmd.c

// readcmd
// Dump the record information for a TRS-80 /CMD
// executable file
//
// License: MIT / X11
// Copyright (c) 2009, 2015 by James K. Lawless
// See http://www.mailsend-online.com/license2015.php
// http://jiml.us
//

#include <stdio.h>

int main(int argc,char **argv) {
   FILE *fp;
   unsigned char buff[258];
   unsigned int len;
   unsigned short address;
	printf("readcmd v1.10 by Jim Lawless\n");
	printf("https://unlawfulassembly.wordpress.com\n\n");
   fp=fopen(argv[1],"rb");
   if(fp==NULL) {
      fprintf(stderr,"Cannot open file %s\n",argv[1]);
      return 1;
   }
   for(;;) {
      if(!fread(buff,1,1,fp))
         break;
			// record type is "load block"
      if(*buff==1) {
         fread(buff,1,1,fp);

         len=*buff;
				// compensate for special values 0,1, and 2.
         if(len<3)
            len+=256;
				// read 16-bit load-address
         fread(&address,1,2,fp);
         printf("Reading 01 block, addr %x, length = %u.\n",address,len-2);
         fread(buff,1,len-2,fp);
      }
      else
				// record type is "entry address"
      if(*buff==2) {
         fread(buff,1,1,fp);
         len=*buff;
         printf("Reading 02 block length = %u.\n",len);
         fread(&address,1,len,fp);
         printf("Entry point is %d %x\n",address,address);
         break;
      }
      else
			// record type is "load module header"
      if(*buff==5) {
         fread(buff,1,1,fp);
         len=*buff;
         printf("Reading 05 block length = %u.\n",len);
         fread(buff,1,len,fp);
      }
      else {
         printf("Unknown code %u at %lx\n",*buff,ftell(fp)-1L);
         break;
      }
   }
   fclose(fp);
}

I found that after the 02 record is encountered, all kinds of garbage data can follow. I assume that most /CMD loaders halt interpretation of the file after the 02 record is encountered. You’ll notice a break out of the main input loop when readcmd encounters this record.

My readcmd program was able to parse through all of the /CMD files in my possession. Now that I have a way to verify the correctness of a /CMD file, it’s time to try and build my own.

I really can’t remember where the first bytes of free memory really start on a Model I. Address 17129 looks to be the spot where BASIC begins, but I’ve never owned a DOS on a Model I, so I don’t know if that address can change.

I noticed that a lot of the games I have begin at address 6C00H, so I chose that as the starting-address for my program.

Here is the slightly modified source code from my prior post:

fill.asm

    ORG 6c00H
    LD HL,3C00H ; 15360 in hex
    LD A, 191
    LD [HL],A
    LD DE,3C01H
    LD BC,1023
    LDIR
    RET

I then assembled it with the command:

pasmo -d fill.asm fill.out

The output from Pasmo is as follows:

ORG 6C00
6C00:21003C	LD HL, 3C00
6C03:3EBF	LD A, BF
6C05:77	LD (HL), A
6C06:11013C	LD DE, 3C01
6C09:01FF03	LD BC, 03FF
6C0C:EDB0	LDIR
6C0E:C9	RET
Emiting raw binary from 6C00 to 6C0E

My load-module is fifteen bytes in size. I need to create a load-record that accommodates fifteen plus two bytes for the load address. My 01 record will have a length of seventeen ( or 11H ) bytes. Here’s how the 01 record should look in hex:


01 11 00 6C 21 00 3C 3E BF 77 11 01 3C 01 FF 03
ED B0 C9

The total space occupied by the 01 record is nineteen bytes.

I then needed to add a 02 record to state the transfer address of 6C00H:

02 02 00 6C

The total size of the two records is twenty-three (17H) bytes in length.

I manually created the /CMD file using the Windows console DEBUG utility.

debug fill.cmd
e 100 01 11 00 6C 21 00 3C 3E BF 77 11 01 3C 01 FF 03
e 110 ED B0 C9 02 02 00 6C
rcx
17
w
q

I first used readcmd to ascertain that the records looked reasonable:

readcmd fill.cmd

readcmd v1.0 by Jim Lawless
http://www.mailsend-online.com/blog

Reading 01 block, addr 6c00, length = 15.
Reading 02 block length = 2.
Entry point is 27648 6c00

I loaded fill.cmd in trs80gp and it correctly filled the screen with whitespace.

I had expected the RET instruction to drop me back into BASIC, but it did not. I’m not sure if that’s an idiosyncrasy of trs80gp or if all emulators and the actual hardware/software will behave in this manner. ( NOTE: after fixing my code to use 1023 bytes to move instead of 4095 as George Phillips, author of trs80gp notes in the comments to the post, I did indeed drop into BASIC, but received a ?SN ERROR message at the prompt. I may try George’s suggestion of JP-ing to 1A19H at a later time. )

In the near future, I would like to write a program that will convert a larger memory-image file ( such as the one produced by Pasmo ) into a /CMD file.

The source and EXE files for readcmd can be found here, along with the source and /CMD file for the fill program.

http://www.mailsend-online.com/wp/readcmd.zip

Posted in Programming | Tagged , , | Leave a comment

Play MP3 in 386 Win32 Asm

This code simply plays an MP3 named “test.mp3”. I intend to flesh this out into a counterpart to my cmdmp3 utility.

; License: MIT / X11
; Copyright (c) 2015 by James K. Lawless
; see http://www.mailsend-online.com/license2015.php
global _main
extern _ExitProcess@4
extern _mciSendStringA@16
SECTION .text
_main:
mov ebp,esp
sub esp,4

push 0
push 0
push 0
push mp3command1
call _mciSendStringA@16

push 0
push 0
push 0
push mp3command2
call _mciSendStringA@16

push 0
call _ExitProcess@4

SECTION .data
mp3command1: db &quot;open test.mp3 Type MPEGVideo Alias theMP3&quot;,0
mp3command2: db &quot;Play theMP3 Wait&quot;,0

Command line for assembling the above:


nasm -fwin32 mp3play.asm
link /subsystem:console /nodefaultlib /entry:main mp3play.obj kernel32.lib winmm.lib

( I use the linker and libraries from the old Microsoft Visual Studio 5 tool set. )

After linking, you can place an MP3 file called test.mp3 in the same runtime folder as mp3play.exe. Then, run the EXE.

The next version will accept command line arguments and will process all appropriate error / exception conditions.

Posted in Programming | Tagged , , | Leave a comment

BSave and BLoad for the Commodore 64

I wrote this little subroutine package for the Commodore 64 in 2002. You can likely still find a cached Usenet post to comp.sys.cbm referring to it.

I thought that I would add in an open-source license header and would present it here.

The source code below is for two machine language library routines which can be called from BASIC. The first routine will save a section of the C64’s memory to disk. The second will load a file from disk into a specific spot in memory. These functions are akin to Applesoft BASIC’s BSAVE and BLOAD binary I/O commands.

I did not wedge the CHRGET routine to add any new command verbs to BASIC; one must use the SYS command to invoke each subroutine. A jump-table at the beginning of the module controls which of the two functions you’ll execute. Address 49152 is the BSAVE routine. Address 49152+3 is the BLOAD routine.

Please note that the filename parameter must always be in a variable. I didn’t have the routine that would parse a literal properly readily available … and still don’t remember how to do it off the top of my head.😉

; BSaVe and bLoaD extentsions for the Commodore 64
;
; License: MIT / X11
; Copyright (c) 2009, 2015 by James K. Lawless
; see http://www.mailsend-online.com/license2015.php
;
;
; To use in C64 BASIC:
; sys 49152,a$,start-addr,end-addr
; The above will save to file named in a$
; sys 49152+3,a$,start-addr
; The above will load a file named in a$
; to the specified location
;
; To save the default BASIC screen:
; a$=";screen,s,w";
; sys 49152,a$,1024,1024+999
;
; To reload the default BASIC screen
; a$=";screen,s,r";
; sys 49152+3,a$,1024

   *=$c000
; jump table for functions
   jmp save
   jmp load
flag .BYTE 00
save = *
   lda #$00
   sta flag
   jmp main
load = *
   lda #$01
   sta flag
   jmp main

main = *
   jsr $aefd ; skip comma
   jsr $b08b ; search for variable
   jsr $b185 ; find address
   sta $fb
   tya
   sta $fc
   lda #$00
   tay
   lda ($fb),y
   pha
   iny
   lda ($fb),y
   pha
   iny
   lda ($fb),y
   tay
   pla
   tax
   pla
   jsr $ffbd ; SETNAM
   lda #$02
   ldx #$08
   ldy #$00
   jsr $ffba ; SETLFS

   lda flag
   cmp #$00
   beq dosave
   jmp doload

dosave = *
   jsr $aefd ; skip comma
   jsr $ad8a ; eval expr
   jsr $b7f7 ; get uint in a,y
   sta $fc
   tya
   sta $fb

   jsr $aefd ; skip comma
   jsr $ad8a ; eval expr
   jsr $b7f7 ; get uint in a,y
   sta $fd
   tya
   tax
   ldy $fd
   lda #$fb

   jsr $ffd8 ; save ram
   rts

doload = *
   jsr $aefd ; skip comma
   jsr $ad8a ; eval expr
   jsr $b7f7 ; get uint in a,y
   sta $fd
   tya
   tax
   ldy $fd
   lda #$00
   jsr $ffd5 ; load ram
   rts
Posted in Programming | Tagged , , | Leave a comment

An Interview with Game Developer James Hague

This post was originally published in 1999. It was formerly hosted at http://www.radiks.net/~jimbo/art/int5.htm

Being a bit of a video-game and classic computer enthusiast, I recently purchased the electronic book Halcyon Days – Interviews with Classic Computer and Video Game Programmers. Note: In 2002, this book was made available to read freely here: http://www.dadgum.com/halcyon

The author of the book, James Hague, is himself a game developer. Since I noticed that his complete bio was missing from the text, I asked if he’d permit me to interview him.

What sort of formal computer training have you undergone?

I have a BS in computer science, but I learned more about programming and computer science on the side than I did in school. In retrospect I almost wish I had majored in something less techie, like English or History.

Why did you choose the Atari computer?

My dad was interested in getting a home computer, though for no particular reason. The Atari 800 was much cheaper than the IBM PC and Apple II, and the C64 wasn’t out yet. Other computers like the Vic 20 and Timex Sinclair were less expensive, but too toy-like. When the 800 looked like the best way to go, he dropped me off at a computer shop owned by someone he knew, and I spent the afternoon playing Pac-Man, Protector II, and Caverns of Mars on the display model. Other than an artillery game on a PET, I had never played any computer games before that, but I was hooked.

Your first several years of accomplishments appear to be games published in then-contemporary computer hobbyist magazines. Did you make a living using computers at this time?

Most of them were written when I was in high school, so it was a hobby. All in all, I made around three thousand dollars, which wasn’t much considering all the work involved.

Did this get you any sort of notoriety within the industry? Any job offers?

I was somewhat well-known as a regular contributor. I remember a bio that started out with “James has made many memorable contributions to Antic…” which made me feel good. And occasionally over the past nine years I’ve gotten email from people who typed in my games. It’s always cool to be remembered!

Did your high-school have computers? Did you burn 6502 code up one side of the wall and down the other on them?

I took some computer classes in high school on Apple IIs, but they were just fluff. I already knew how to program by that time, and I never did anything on them other than class assignments.

Do you remember your first 6502 program?

The period during which I learned 6502 assembly is a blur. I remember reading Kurt and Don Inmans’ _Atari Assembler_. I remember writing some simple code to try out player/missile graphics. Then I jumped into a full-fledged game that quickly outgrew the limits of the Atari Assembler/Editor cartridge. When the author of the manual wrote “This product is best suited for very small projects,” he meant it!

What kind of storage medium did you have at this time? Were you saving to cassette tapes?

I had an 810 disk drive by that time. I only had cassette tape when I first learned to program, and it was awful. I could only save relably at the beginning of a tape, and I couldn’t re-record over previous data. As a result, the BASIC games I wrote back then were each done in a single sitting, start to finish. That means that the machine never crashed during those hours, which I find amazing today.

Did you graduate to a more powerful assembler?

When the Assembler/Editor became unbearable, I convinced my mom to get me MAC/65 for my birthday. I used it so much I wore out the contacts and had to get a replacement!

What prompted you to try and publish “Bonk” in ANALOG Computing?

Though it was my first published game, Bonk was actually the second game I had accepted by ANALOG. For unknown reasons it made it into print before my first game, “The Electroids.” At the time, I was completely driven to write games for a living. I used to pour through the Atari Program Exchange catalog and marvel at the authors’ names. I memorized the few interviews with game programmers I could find. I went nuts over Levy’s _Hackers_. I eagerly awaited each issue of ANALOG and studied the source code and read all the author biographies.

I started writing Electroids with the intention of having it published in ANALOG. I had little direction when I began; I just made up the game as I went along. The first time I submitted it to ANALOG, they returned it with some suggestions. And, unbelievably, someone had printed out the source code and made comments about optimizations and improvements. I learned a lot about 6502 coding from whoever took the time to do that. The second time I sent in the game it still had some oddball bugs, but they accepted it anyway for $360.

I started Bonk right after I finished Electroids, and it was my second sale to ANALOG. It was a lot of fun to work on; the code flowed smoothly without any real sticking points.

I note that the time-frame when magazines like ANALOG and COMPUTE! were gaining popularity was shortly after or in the preliminary phases of “the big video game crash”. Why do you think that game-publishing via source-code in magazines became a craze at this time? Do you think it might have been related to a lack of retail games?

There weren’t other sources for cheap games unless you were into the BBS piracy scene. Most people who owned computers were isolated. They didn’t have modems, and they didn’t belong to user groups. So being able to buy a four dollar magazine full of software, as compared to $30 or more for one commercial game, was a great deal.

Was Tarzan for the SNES your first “professional” game?

Yes, it was the first game I worked on full-time. Tarzan was a horrible, horrible game. After being into original ideas and doing my own designs, I wasn’t prepared to have a completely derivative design dropped on my desk. The game ended up looking like a checklist of programming and art tasks–all of which were completed–without any thought given to the playability of the end result. Game-Tek wisely decided not to release the final product, even though they paid for it, and even though it was previewed at least once in Nintendo Power. When people start collecting SNES cartridges, they’ll be fighting over the handful of prototypes!

How did you go about making the transition from 6502 developer to SNES developer?

The short answer: by complete accident!

After graduating from college, I worked at a telecom company in the Dallas area for three years. I eventually got the corporate blahs, and started looking for work all over the country. I wasn’t specifically looking for game jobs, though I applied for some. In the summer of 1993 I picked-up a Seattle newspaper at a local bookstore and saw an ad looking for a “6502 hacker.” I thought it was funny, a 6502 programming job in 1993. I fired off a resume with a copy of the Bonk article and got the job. I was actually hired to do Sega Genesis programming, but because it took me some time to get moved up there and the Genesis project need to get going, I ended up working on the SNES instead.

I believe the Genesis used a 68000-series processor and the SNES used the 65816. Did you already have assembly disciplines for these other processors under your belt or did you have to undergo training?

At one time I figured I’d move from the Atari 800 to the Atari ST, so I bought some 68000 books and learned how to program that processor. But I never actually had the chance to do any 68000 coding until 1995 when I did some compressed sprite routines for the Mac version of Lion from Sanctuary Woods.

It looks as though your last public game effort was six years prior to Tarzan. Were you working on gaming in those years?

During college and the few years after I graduated, I lost interest in games. Well, it was more like I lost interest in the computers that were popular at the time. I almost bought an Atari ST when I was in college, but I’m glad I didn’t, because Turbo Pascal on my junky PC was mighty handy for classes. Unfortunately, that PC had a monochrome Hercules card, so I didn’t get into writing games for it. I finally bought a better PC after I graduated, but programming it was just so blasted *ugly* compared to the Atari 8-bit machines. I was used to getting almost anything running at 60 frames per second, but it was a complete struggle to get any kind of smooth framerate out of an ISA VGA card. And simple things like sound and timer programming turned into big hunts through bookstores and FTP sites. I worked on some things here and there, but I felt like my effort was being directed at technical problems rather than games.

Not to start a parochial war, but do you prefer using the Mac? Why or why not?

I prefer the Mac by a slim margin because the interface is more focused and has better aesthetics. I also like the fact that I can install and uninstall software myself without worrying about registry and DLL rot. But, as a regular Windows user, I find the two OSes are very similar otherwise. They could both use a little streamlining and re-thinking.

What do you think of Win95/NT as a gaming platform?

If someone handed me a game system with the specs of a current PC, I would be impressed by its power. Yet somehow the PC is less exciting, even though it’s basically the same thing. All the driver upgrades and registry problems and install/uninstall hassles tend to take the edge off things. What do you do if a game doesn’t run on a customer’s machine? Grill him or her about the machine’s configuration? Suggest trying the latest video card BIOS and drivers? These are pretty awful options. Even so, there’s a tremendous amount of power and potential for amazing games in the average PC.

Are you making a living as a game programmer, or is game authoring a part-time endeavor?

Both, actually. I’m working full-time for a PC game company, and I’m puttering about with my own projects at home. There are advantages to each. A large team can put together things of grand scope that an individual could never hope to achieve. But an individual has the opportunity to try crazy and smaller ideas that would never get up-front funding from publishers.

I’m somewhat surprised that garage game development has stagnated. There’s a certain pride that people have in discovering and latching onto underground music, and it eventually gets that music into the mainstream. Wacked-out bands who do their own thing are always cropping up: Cake, Laura Love, Squirrel Nut Zippers, etc. But there aren’t equivalents in the game world. The few independent game people have been rehashing the same junk forever: a handful of early eighties games, Tetris, generic platformers, vertically scrolling shooters with techno-organic bosses, and ridiculous attempts to clone games at the tops of their respective genres, like Quake II. Someting isn’t right with this picture.

I think that approaching the PC with little experience and the intent to create *any* game is very daunting–much more than than it was on a Commodore 64. The high frustration factor puts people off.

Do you stil code games at the assembly level or do you use higher-level languages?

Bumbler Bee-Luxe, which was released in 1997, was written entirely in PowerPC assembly. Mostly it was because I was frustrated with the higher level tools available for the Mac at the time, and I found an assembly language development system that agreed with me. Machines based around the Pentium 75 and PowerPC 601/66 were somewhat odd. They were fast, but not quite fast enough to effortlessly throw around 300K of screen data sixty times per second.

I’m much happier programming in higher level languages when good tools are available. With more speed in the average PC than people know what to do with, I don’t see any reason I’ll write more than an occasional subroutine in assembly.

Based on some of your recent Usenet postings, I note an interest in some rather exotic programming languages ( Forth, Scheme/Lisp, functional programming languages, and Perl extensions in languages other than C ). What are your current programming language interests?

I’m interested in fun. On an Apple II or Atari 800, for example, you could just turn on the machine and be writing code in three seconds. A few moments later, after you typed in a formula from your math homework, you were getting results. Imagine using Visual C++ for the same purpose: you have to create a project, you have to recompile whenever you make a change, you have to remember to include header files if you want to display the results or use an absolute value function.

Sitting down in front of Lisp or Haskell or Caml or Forth is unimaginably wonderful in comparison.

Specifically, what is your interest in Forth?

I’ve had an off and on romance with Forth. It’s such a subversive language; you can fit an entire Forth development system into the space taken by the executable header of a “Hello World” program generated by a C compiler. But I’ve finally decided that the whole Forth concept is too minimal in the modern world. It’s like using an artist’s paintbrush to paint a house. The Forthers will respond with comments like “If you think you need to paint the house, then you haven’t thought about the problem enough.” They’ll suggest that a tent will keep you dry as well as a house and is much easier to maintain. Meanwhile, someone with a big, bulky brush is almost finished with the first coat of paint on the house. There has to be a happy medium between a 20K Forth and a C++ compiler than won’t fit on a Zip disk.

What prompted the Giant List and ultimately Halcyon Days?

I went through a big retro phase back in early 1991 when I discovered Tim Duarte’s 2600 Connection newsletter. I bought a ton of 2600 cartridges from people on Usenet, plus a couple of Atari computer systems, a composite monitor, and a new 7800. I don’t know what I was planning on doing with all that stuff; I was just overdosing on memories and buying what I would have bought in the early 1980s if I hadn’t been a broke teenager.

A year or so later, partly spurred on by the short programmer interviews in The 2600 Connection, I started writing down all of the 8-bit game programmers I remembered and what they wrote. The information was entirely from memory and a stack of old issues of Electronic Games, Video Games, and ANALOG. This was more a private obsession than anything else. I started posting it to rec.games.video.classic sometime in 1994.

A cool side effect of making the list public was that people included on the list would spot themselves and send me corrections and additions and great stories. In late 1995 it occurred to me that I probably had more information on the whereabouts of classic game programmers than anyyone else, and I came up with the idea of a collection of interviews, a la Susan Lammers’ great _Programmers At Work_ from the mid-eighties. I made lots of progress on the interviews, but was stalled because I couldn’t find a publisher.

You state that Halcyon Days was an experiment … do you care to share the purpose and results?

I ran into a wall when I proposed Halcyon Days to publishers. Computer books that aren’t of the “how to” variety usually don’t sell well, and publishers are wary of them. And with a few exceptions, such books disappear quickly. In a bookstore, there may be dozens of shelves of computer books, but only a small part of one shelf is devoted to generalities, and who really looks at them?

By the autumn of 1996, I was kicking around self-publishing options when HTML struck me as an obvious idea. It’s perfect: a simple cross-platform solution with an almost universally available viewer. Even ASCII text isn’t as portable, because of the different line termination conventions on different machines. The experiment was to see if people would actually accept an HTML publication as a standalone concept without confusing it with the web itself.

At the time it seemed risky, but these days Apple and Microsoft are using HTML for help files, and it’s common for programs to ship with HTML documentation.

What can we expect to see from you in the near future?

That’s a good question. I would love to do more game design and programming for my own projects–I have all sorts of crazy designs in my head–but the effort involved is immense. There’s greater reward and much less frustration in writing articles and maintaining web sites.

Do you have any advice for up-and-coming game developers?

If you’re going to work on your own projects, please don’t stoop to cloning Galaxian and Tetris and Asteroids and Sokoban and Boulder Dash and so on. There are so many other ideas waiting to be explored!

Posted in Programming | Tagged , , | Leave a comment

An Interview with the Author of the French Silk Assembler

Speaking with Don French : The Man Behind the French Silk Assembler Tools

Originally posted 5-21-2004. 

In the early days of 8-bit computing, a programmer’s most often-used tool was the assembler. Due to memory constraints, many of the early 8-bit machines could not run a full assembler. At best, one could hope for some sort of machine-language monitor that would include a mini-assembler and a disassembler.

That was … until Don French came along and implemented a symbolic assembler on the unexpanded VIC-20.

Don was gracious enough to grant me an interview via e-mail.

What exactly were the products offered by your company French Silk? ( I’ve heard of the Assembler, Develop-64, and Develop for the Apple ][ …)

My first product was “The Assembler for the VIC-20”. It was the only assembler ever to run on the unexpanded VIC and I believe it was and still is the smallest assembler ever written for any computer. I included a specialized text editor and a loader with The Assembler. The company name was French Silk, but The Assembler also came to be known on the street as French Silk.

When the Commodore-64 came out I converted The Assembler to run on the 64. Up until this time I had done all the programming myself, but at this point I hired John Shifflet, one of the best programmers I have ever known, who wrote a symbolic disassembler, which we called Decoder-64. The disassembler could disassembler RAM, ROM, files on the 1541 disk drive, and even the ROMs of the 1541 disk drive. I sold the assembler, packaged with the disassembler, as Develop-64.

Not long after that we created an integrated development environment (one of the first IDEs) for the 64, that included an editor, assembler, disassembler, a symbolic debugger, and a loader all in one. I sold this as The Machine Shop and included a book that I authored, called “Inside the Commodore-64”. I also wrote and sold a book called “Inside the VIC-20”.

I think the next product was a program that could print the contents of the screen, a graphic screen dumper. It supported numerous printers, but I think it was the first, if not the only program that was capable of printing bitmapped graphics on the Commodore 1526 printer. It also printed color graphics on some color printer that Commodore made. I am having trouble remembering the name of that program, but it was “Something”-64. Geoff Terrell wrote the basic engine and I wrote the user interface and the1526 code.

I then published ApSoft-64, written out of house, which was a version of Applesoft Basic that ran on the 64.

Those were the main products, although I also sold a package of a hundred cheesy public domain Applesoft Basic programs that would run with ApSoft-64. I never wrote anything for the Apple ][.

Was ApSoft-64 your idea?

No. I was approached by a guy who had written it and who convinced me to publish it. It was a big mistake because everyone thought that you could load and run Applesoft Basic programs directly from published programs on Apple media, but that was not possible. You could only type them in, and while it was a good implementation of Applesoft Basic, not that many people wanted it for that limited purpose. I wish I had never decided to take the project on.

In an archived message-board post, I noted that you developed an assembler on the VIC-20 for the VIC-20. What computer / electronics experience did you have that prepared you for this endeavor?

I did not have any electronic experience other than building a Heath kit stereo. But I did have prior computer experience, beginning in 1967 writing business applications in Fortran for the IBM 1130. In 1969 I had a friend who wrote a package of device drivers for the 1130 that allowed the 1130 to run at up to ten times its normal speed. He invited me and another friend to join together and form a company to wrap up and market this fantastic product, and I was assigned to write one driver myself, the one for the paper tape read-punch. This is where I learned how to write assembler code. We very foolishly never marketed this package of programs and if we had, we would have made millions. We were so young and dumb. My friends were both working for IBM, who forbid them to take part in this project because it would make the 1130 competitive with much more expensive IBM equipment. My friends chose to stay at IBM unfortunately. It was just a killer product though. Cliff Harwood was the brains behind it and also my mentor.

I wrote IBM 360 BAL banking apps for a couple years and then worked on an IBM 1800 and wrote a driver to acquire data from an EKG machine, thus adding to my assembly language skills. In 1976 I bought a KIM-1 single board computer for which I wrote a variety of 6502 machine language programs (machine language, and not assembly language, because I didn’t have an assembler.) I had to hand assemble the code and enter it a nybble at a time into the keypad on the board. It was the dislike for this arduous and error-prone process that led me to buy the VIC-20 and write an assembler so I wouldn’t have to do any more hand assemblies.

Your Vic assembler seems to be a bit of an oddity; you built a complete assembler in under 2k of code. Did this feat draw attention to the VIC-20 Assembler?

The unexpanded VIC had 3583 bytes of available RAM and there were1944 bytes free after loading The Assembler. That 1944 bytes was the space available for your source code. This means that the assembler itself only took up 1639 bytes of RAM. By the way, when I say it was the smallest assembler in existence, I mean the smallest symbolic assembler, which is to say that it allowed for the use of labels (symbols) to represent addresses in memory or locations in the source. Besides allowing for symbols, it supported address expressions in which five different kinds of terms (symbolic labels, decimal numbers, hex values, literal characters, and the program counter) could be arithmetically combined through addition, subtraction, multiplication, division, exponentiation, and logical AND and logical OR. It also allowed the programmer to define both hex and alphanumeric strings and it supported comment lines and fields. Oh, and labels could be up to 72 characters long, if you were crazy enough to waste all that space on labels. There was also an EQU statement that doubled as an ORG.

That was quite a lot to pack into 1639 bytes and I pulled every trick in the book plus a number that I had to invent myself to pull it off. Of course, your assembly program had to be pretty small to fit in 1944 bytes, but a lot of people learned assembler by using this tool. I sold several thousand of these babies at $19.95 each.

Did it get attention it deserved due to this remarkable bit of shoehorning? I am afraid not. This was my mistake I am sure, as I was not a marketing genius.

Did you encounter any difficulties in marketing your development tools?

I just advertised in Compute and Run like every other Commodore software company. The trouble I ran into was distribution. At the beginning there were tons of Mom and Pop software stores and I had pretty good luck selling small quantities to lots of them. But then the chains moved in and forced the Moms and Pops out of business and the chains would only buy from a few big distributors and the big distributors would only stock and sell very heavily advertised products that had very professional packaging. I could not afford the required advertising budget and my packaging was not that great either. Getting product on the shelves became harder and harder. And a number of smaller distributors simply ripped me off. I never had the business moxie or experience to get around these problems and I grew so tired of the bullshit side of business that in 1986 I eventually just hung it up and drove an RV out to San Francisco and lived in it on the Panhandle and did volunteer work for the Haight Ashbury Switchboard.

Was it difficult competing with the various other assemblers in the Commodore markets?

Yes, especially for the Commodore-64. I had a pretty good product and I still have scores of letters from users who took the time to write me to rave about it, but the other assemblers were better promoted and were in fact better in some respects. I made certain compromises in the original editor and assembler for the VIC-20 that were a result of the memory limitation, and, like so often happens with software, I got caught in the trap of needing to (or believing I needed to) support the previous code base in each new version. So the deficiencies were propagated forward.

Did piracy ever visibly affect your sales?

Of course. Whenever it is possible to get free copies of software, people do. I found very little regard for the rights of software companies or programmers among the computer using public. I knew people who were leaders in their community, deans in the church and the like, and who were among the most honest upright citizens you could find anywhere. Yet they had no compunctions about making illegal copies of software. It is extremely rare to find someone who won’t copy software if they can. Remember when shareware was really that? You could keep and use the program and were asked to pay for it if you like it, all on the honor system? I have spoken with a number of shareware authors who tried this and never got a dime from the thousands of downloads of their program. In fact, I tried this with Problematic. Thousands of downloads, not a dime of revenue. People won’t pay if they don’t have to. Almost no exceptions. Some Commodore journalist once told me that French Silk (the assembler) had a huge cult following on the East Coast. I was very surprised to hear that because by that time I had sold very few.

Did you make transitions into computer markets other than the 8-bit Commodore line? ( Apple? Amiga? )

No. As I said above, I got tired of the rat race and all the rats I had to deal with and just jumped ship in 1986.

Are you actively producing software today?

After bailing on French Silk, and after my stint at the Haight Ashbury Switchboard, I contracted to write Dick Tracy for the C-64 for Disney. I then wrote and published a chess problemist’s toolkit called Problematic. You can read the docs on my chess site:

http://www.geocities.com/bozito/problematicDocs.html 5-17-2010 NOTE: The geocities links aren’t active any more, but it appears that this one has taken at new home at: http://reocities.com/SoHo/Cafe/8437/ ).

The only thing I have written since is a partially completed FreeCell program which can also solve positions. You can find it here:

http://www.geocities.com/bozito/freeCell.html

I am spending time doing photography mostly now, and playing a bit with robotics. I have the beginnings of a photography site:

http://www.donfrenchphotography.com

Please tell me about your experience writing Dick Tracy for the Commodore 64. Did you write the entire program yourself?

I wrote the entire program myself, but I did not design it. That is, Disney had a design and script that I and the PC team and the Apple guy had to follow. The program was written entirely in assembly language, but like all the other versions, it was never finished. Disney pulled the plug on all of versions when it became clear that they had badly misjudged the time it would take to get them out. No one was near done when the movie hit the silver screen. Plus, I think that the movie wasn’t doing that well and the merchandising wasn’t selling. The game design was kind of lame anyway. It offered me the opportunity to learn how to write interupt driven smooth scrolling screen animation, though. Not that I ever used it again.

Had you ever written video games for the C-64 prior to Dick Tracy?

Nope. It was my first.

How did you land the contract that allowed you to write Dick Tracy?

I answered an ad for a C-64 assembly language programmer. I think it was run in the San Francisco Chronicle. There was some company in the Bay Area that hired me and they had the contract with Disney to do the C-64 and Apple ][ versions. I have since forgotten the name of that company.

Had you ever built an assembler before your VIC-20 Assembler?

Nope. This was my first.

Did you ever have a desire to market compilers for higher-level languages such as C and Pascal for Commodore equipment?

I really never gave it much thought. I hadn’t learned either language by the time I got out of the business.

What is your educational background?

I have a BA in Chemistry from Kalamazoo College. My senior thesis was a topic in quantum mechanics.

Do you use any Commodore emulators on your computer today?

No, I don’t.

Do you have working Commodore equipment in your personal collection?

Oh yeah, I still have my original C-64 and VIC-20 as well as a 1541 disk drive.

Was your Assembler manual a 6502 tutorial? Have you thought about e-publishing it?

The books “Inside the VIC-20”, which accompanied some versions of the VIC assembler, and “Inside the Commodore-64”, which accompanied Develop-64 and The Machine Shop, included 6502 assembly language tutorials. I don’t think I have an electronic version of these any more. The last electronic versions I remember were on Osborne floppies and I don’t think I have them any longer. I certainly don’t have the Osborne. I suppose I could scan the manuals in, but I seriously doubt that I will do that. They were printed on dot matrix printers, for one thing, and are not likely to be very OCR friendly. Do you really think there is a market for a 6502 tutorial?

What can we expect to see from you in the near future?

Nothing in the near future, unless I decide to write a poker bot, which I have been mulling over

Any last words for today’s diehard Commodore enthusiasts?

Gee, I didn’t know there were any. But I guess that there are people who enjoy playing the favorite games of their youth, is that it? I will say that it was a truly great computer for its time, and I loved it dearly and can see why people still enjoy it (I am thinking the C-64, but the same goes for the various Pets and the VIC.) In fact, writing the answers to this interview has made me nostalgic for the old Commie. Maybe I should check out some of the emulators.

Posted in Programming | Tagged , , , | Leave a comment

Learning Z-80 Assembly Language on the TRS-80

Originally published on: Sun, 08 Nov 2009 02:17:14 +0000

My first computer was a second-hand TRS-80 Model I with 16K of RAM and a cassette-recorder for auxiliary storage. I was 17 years old when I received this computer in the Fall of 1982. My goal? Like many kids my age at the time, I had intended to write a video game or two and live happily on the riches that would befall me.

The computer was purchased at an auction and came with a fair amount of books on BASIC including many that just contained BASIC games.

My eldest brother had his own TRS-80, so he let me borrow from his vast library of 80 Micro magazines as well.

My first task was to really try to learn BASIC. I did so by typing in programs from the books and by trying to write my own. I had been familiar with BASIC for a couple of years, but only some of the more simple aspects. I had known that if I wanted to write games, I was going to have to code using some mysterious black art known as machine-language. All of the good games from Big Five seemed to be written in machine-language.

As I kept poring through the backlog of issues of 80 Micro, I learned how to use little machine-language subroutines via the USR() function. In order to execute machine-language from BASIC, you had to first reserve some space at the top of BASIC at the MEMORY SIZE? when the computer powered up. ( Note: there are ways of getting around this that I’ll explain in a future post. ) After that, you had to POKE your machine-language routine into reserved memory a byte at a time. Authors usually placed these bytes in a series of DATA statements and used the READ command to read each one in a loop.

After the subroutine was placed in memory, the last task was to point the USR() function to the routine. The address of the routine had to be broken down into two bytes, the least-significant-byte first. I began to grow comfortable with the conversion routine … dividing by 256 to get the high-byte and taking the remainder to get the low-byte.

I also became very comfortable with hexadecimal notation and conversion to and from decimal notation. The only thing I was really lacking at this point, was learning machine-language itself.

I began reading Hardin Brothers’ 80 Micro column The Next Step. This column was a tutorial on machine-language in a sort of cookbook approach. Brothers would present some sort of a short program in assembly-language ( the human-readable syntax that is then assembled into machine-language. )

Most of his programs were very compact and were wonderful to study. He would present the assembly listing for the machine-language routine complete with hex codes by each mnemonic. I found that by converting those hex codes to decimal, I would see the same numbers in the DATA statements for the BASIC loader for the particular routine.

This revelation enabled me to tinker a little with some of the subroutines presented.

One of the machine-language subroutines that was presented in the Radio Shack Level II BASIC manual was a simple routine that would fill the screen with white space. This was done by storing a character with the ASCII code 191 at each location in the machine’s video memory ( located at locations 15360 to 16383 inclusively. )

To see what the program was doing, the BASIC equivalent was easy enough to understand:

trsbasicfill

As the program ran, each character position on the screen would fill with a white block:

trsbasicfill2

The equivalent assembly language program usually looked something like this:

ORG 0H
LD HL,3C00H ; 15360 in hex
LD A, 191
LD [HL],A
LD DE,3C01H
LD BC,1023
LDIR
RET

The first line is the ORiGin directive that tells the assembler ( the program that translates assembly-language to machine-language ) what address we plan on starting at. This little routine is relocatable; it can be placed anywhere in memory because it does not internally depend on addresses within itself.

The major work is performed by a Z-80 instruction called LDIR ( LoaD-Increment-Repeat ). LDIR is a block-memory move command that begins by taking the byte at the address held in the HL register pair and stores it at the address in the DE register pair. Then, it decrements the BC register pair by 1 and if BC is not zero, it will increment HL and DE repeat the load-from-HL / store-at-DE / dec BC operation until BC reaches zero.

This routine uses a trick with overlapping memory locations. Note that HL starts at 3C00H and DE 3C01H. When the second iteration of the LDIR loop commences, the value it reads from 3C01H to store in 3C02H was the same as the one in 3C00H. This trick with the source and destination addresses differing by a byte causes the memory at DE for a length of BC to fill with the first byte specified.

So, this is a quick memory-fill routine.

The assembler’s output of this routine might look like the following:

ORG 0000
0000:21003C LD HL, 3C00
0003:3EBF LD A, BF
0005:77 LD (HL), A
0006:11013C LD DE, 3C01
0009:01FF03 LD BC, 03FF
000C:EDB0 LDIR
000E:C9 RET

The hex digits to the left of each instruction comprise the instruction and its operands (if any). Note the line LD A, BF. This is the line that loads a character 191 into the A register. I found that I could poke any character I wanted into byte number five of this routine and could fill the screen with that value.

I was slowly making headway to learning assembly language itself as I was beginning to understand that the output of the assembler program was ultimately a binary with a bunch of bytes that the Z-80 processor understood.

As I continued to study examples in 80 Micro, I showed some of these programs to my brother. He brought over a couple of items that he’d gotten at a clearance sale at Radio Shack: The Radio Shack Editor/Assembler on cassette and William Barden Jr’s book “TRS-80 Assembly Language Programming.”

I tried to leap into the middle of the book as I had done when learning BASIC, but failed miserably. I started anew and took it step by step. I finally started getting somewhere.

It took a while, but I was able to separate the pseudo-operation command from the actual Z-80 commands and began to make my own subroutines. I also began to use tricks with the cassette load-module format that I had seen some video games use. I figured out how to auto-start a program ( no need to type in a slash at the SYSTEM prompt), scroll the contents of the screen and blur the video in a manner similar to the effects that began the game Attack Force. I also figured out how to load a message immediately on the screen and that the asterisk that normally flashed during a casette load could be replaced with a character 191 for a more graphical effect.

By the Summer of 1983, my goal was to finally write this game. Alas, I knew nothing about software design. I would design fragments, but I was used to just sloppily coding something together and cajoling it to work. I really didn’t have a game idea. I was just working on different effects and animations and was trying to stitch them together into a game.

Unfortunately, my cassette recorder ( like many ) was unreliable when saving / loading my games. The EDTASM program required one to assemble to cassette, then reload to test. This process took forever. I had found a way to put my program at a high-enough spot in memory that I luckily found a re-entry point for EDTASM, so that once my code was tested, I didn’t have to reload EDTASM … I just entered SYSTEM and then an address ( that now escapes me ) that would leave me back at EDTASM’s ‘*’ prompt with my source-code intact.

I spent many late summer nights working on that code while my TV was affixed on a then-independent cable channel from Kansas City. I coded while listening to the audio for The Three Stooges followed by a mix of Get Smart, Hogan’s Heroes, and similar syndicated television shows from the 1970’s.

As I toiled away, the TRS-80 video games market crashed. New computers were becoming popular as was the Atari 2600 video game console system. If I had finished a game and had tried to market it through Big Five Software ( see http://www.bigfivesoftware.com), chances are they wouldn’t have taken it. Nor would any big-league publisher likely have taken on any new games for the TRS-80.

However, I didn’t finish a game. The slow development cycle and the inability to save reliably ultimately left me no choice but to move on. I had looked at getting an expansion interface so that I could then buy a disk drive and a Disk Operating System to minimize my turnaround time, but those options were costly. More attractive computers with color video and relatively inexpensive disk drive options started to take over the landscape.

Using my knowledge of Z-80 assembly-language, I taught myself 6502 assembly-language on one of the Apple ][‘s at school. In the Summer of 1984, I bought a Commodore 64 and 1541 disk drive. My days of hacking the TRS-80 were over.

…almost.

I amassed quite a bit of knowledge in a very short amount of time about that little computer. I had wanted to publish some of the more esoteric things I’d found in a magazine like 80 Micro, but I never did. I have some TRS-80 emulators and am planning on revisiting some of these subjects on this blog in the near future.

Posted in Programming | Tagged , | 2 Comments

My First C64 Interrupt Program

In late 1983, I began learning 6502 assembly-language by hand-assembling 6502 code on an Apple II computer at school. I had also been toying with a Commodore 64.

I had been reading some C64 articles that pertained to inserting interrupt-driven machine-code routines by modifying the vector stored in $0314 / $0315.

My first interrupt-driven C64 code simply incremented the border color with each invocation of the timer interrupt. Although I had originally written the code using Jim Butterfield’s SuperMon 64, I recently rewrote the same code using a label-based assembler:


; Interrupt-driver border changer for the C64
 ;
 ; License: MIT / X11
 ; Copyright (c) 2013 by James K. Lawless
 ; jimbo@radiks.net
 ; http://lawlessguy.com
 ;
 ; Permission is hereby granted, free of charge, to any person
 ; obtaining a copy of this software and associated documentation
 ; files (the "Software"), to deal in the Software without
 ; restriction, including without limitation the rights to use,
 ; copy, modify, merge, publish, distribute, sublicense, and/or sell
 ; copies of the Software, and to permit persons to whom the
 ; Software is furnished to do so, subject to the following
 ; conditions:
 ;
 ; The above copyright notice and this permission notice shall be
 ; included in all copies or substantial portions of the Software.
 ;
 ; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 ; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 ; OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 ; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 ; HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 ; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 ; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 ; OTHER DEALINGS IN THE SOFTWARE.
 ;
 ; To use in C64 BASIC:
 ; sys 49152

 * = $c000
 sei
 lda $0314
 sta jumper+1

lda $0315
 sta jumper+2

lda #<iroutine
 sta $0314
 lda #>iroutine
 sta $0315
 cli
 rts

iroutine = *
 inc $d020
 lda $d020
 and #$0f
 sta $d020

; the target address will be dynamically modified by the
 ; init portion of this code
 jumper = *
 jmp $0000
 end

You can download the source and .P00 file here:

http://www.mailsend-online.com/wp2/c64border.zip

When I had run the original program, the timing seemed to work nicely with NTSC video. I recall the colors changing in a manner that left scrolling colored stripes in the border where each stripe was about the size of a C64 character in height.

I no longer have a stock C64, so I had tried to tune VICE into generating the same effect, to no avail. Here’s what the code looked like in VICE with my settings:

Posted in Programming | Tagged , | Leave a comment

Jim Butterfield : The Commodore Guru

Originally published on: Sun, 25 Apr 2010 19:35:16 +0000

Jim Butterfield passed away on June 29th, 2007 after a long battle with cancer.

I grieve with the family and the legions of techies who looked upon Jim as a mentor via his articles and ongoing contact with the Commodore community.

Rest in peace, Mr. Butterfield.

***

This post was formerly hosted at http://www.radiks.net/~jimbo/art/c642.htm , http://www.mailsend-online.com/blog/jim-butterfield-the-commodore-guru.html , and had originally appeared in Commodore Hacking #14. It was reprinted in Commodore Free magazine and other e-magazines in Jim Butterfield tribute issues.

My initial interest in the Commodore 64 computer began in 1983. At the time, my primary source of information pertaining to the C64 came from Compute! and Compute!’s Gazette publications. One author’s name stood from the rest; Jim Butterfield.

I used to turn to Jim’s articles immediately when I managed to get my hands on a new magazine. Mr. Butterfield has the rare ability to describe complex subjects in simple terms.

I’m certain that I’m not alone when I credit Jim with having taught me a lot about the inner workings of the Commodore 64. As important as the specifics of writing code for the C64 was Jim’s style. He would often write code that was readily portable to multiple CBM machines. His code had longevity and purpose. The solidity of his programs left me with a lasting impression pertaining to how software should be developed.

The following interview with Jim was conducted via e-mail.

***

Q: What was the first programming language that you learned?

A: In about 1963, an assembly language called COGENT for a computer that few people have ever heard of: a Collins Radio C-8401. That was shortly followed by work on an IBM 1401, which had a machine language that was alphanumeric. (Honest! You could keypunch M/L directly!)

Q: Were numbers expressed in Base-36?

A: No. Decimal.

The basic machine had 1000 bytes (not 1K) of (7-bit) memory (core, not RAM!) so addresses ranged from 000 to 999 (and were given in decimal, of course). Expanded machines had 4K, then 16K … the addresses were slightly more complex in that case.

Thus, to move bytes from an area at, say address 123 to address 456 the instruction would be M123456. I AM NOT MAKING THIS UP!!!!

Q: Did you guys have contests to spell out goofy words as part of a program? (I know of a programmer who used to regularly use the return code $0BAD to indicate a problem…)

A: No (the addresses mixed in with the op codes ruled that out), but you could do fun things on a 1401 if the system manager wasn’t looking .. such as play music.

Q: What was the first computer that you owned?

A: Not counting the TUTAC-1, which was powered by rubber bands and was more correctly a logic machine: The KIM-1, a single-board microcomputer made by MOS Technologies, Inc., of Norristown PA. MOS Technologies was subsequently acquired by Commodore.

Q: When did you first encounter a Commodore computer?

A: When Commodore acquired MOS Technologies, the computer that I had owned for over a year became a Commodore computer. Subsequently, an employee of MOS Technologies, Chuck Peddle, convinced Jack Tramiel of Commodore that they should launch a personal computer called “The PET”. I got one of those not long after they started production.

Q: Did you have formal training in computer programming?

A: Yes, on that long-ago Collins C-8401. But this was more a process- control machine; it didn’t use of any the newfangled (at the time) languages such as Fortran and Cobol. So my training was in machine language/assembler.

Q: What was the first book that you wrote?

A: A couple of enthusiasts and I collaborated on a volume called “The First Book of KIM”, a book describing how to do things with the KIM-1 single board computer. That computer was powered by a 6502,by the way; in fact the KIM-1 board itself was designed as a engineering prototype for people who wanted to try out the chip.

Q: Was it similar to the Altair where you had to manually increment an address-counter before you could throw the switches to set the byte at that address?

A: No, the KIM-1 had an operating system in ROM. That’s one of the things that made all KIM users “equal” and able to share programs, while the other early micro owners had quite a scattering of stuff.

Q: What COULD you do with a KIM-1?

A: Hey, watch it! That’s like saying, “What could you do with a Commodore 64”? Although the KIM-1 came with a hexadecimal keypad rather than a keyboard, and output to a six-digit LED display, you could use those to good advantage AND hook up extra stuff. Play music? Play Blackjack? Hunt the Wumpus? Skeet shoot? Unless you had the budget for a printer, you’d have a hard time doing an accounts receivable, of course. But this is the 6502 we’re talking about! And we all know it can do ANYTHING!

Q: What was the last book that you wrote?

A: It’s probably the revised version of “Machine Language For the Commodore 64, 128, and Other Commodore Computers”. In 1985 and 1986, however, I did produce a “pocket diary” reference guide for Commodore 8- bit computers.

Q: Have you ever written articles or books on subjects that are not computer-related?

A: My first writing experience was a treatise on transistor theory, published by Popular Electronics in August of 1959. Not much else.

Q: Did you write commercial software for any of the Commodore computers?

A: As a general rule, no. All my stuff is public domain. At one time, I had written a simple spell-checking engine that was incorporated into a word processing package for a while.

Q: SuperMon was a tool that I used daily when developing ML routines or exploring the C64. What prompted you to write SuperMon?

A: In the early days of Commodore personal computers, there were quite a few machine language monitors around. They were partly based on some publicly published code by Steve Wozniak (of Apple!), and partly based on the MOS Technology TIM monitor, from KIM-1 days.

Two variants of the basic monitor caught my eye: NewMon, which added several useful features to the basic Machine Language Monitor; and HiMon, which sited the monitor in upper memory where it wouldn’t conflict with BASIC programs. I decided to put the two together and generate a self-relocating MLM. That was desirable in early PET/CBM days, where some computers would come with 8K RAM, some with 16K, and others with 32K; you couldn’t assume where the top of memory would be.

In those days, almost every Commodore computer came with a small built- in MLM, and the first Supermon was an add-on. Later, as Commodore changed the style of the MLM packages they built into newer machines such as the 128, I went back and modified those earlier versions so that they would work the same across all platforms.

Q: Did you ever expand the mini-assembler in SuperMon into a full-blown assembler development package?

A: No. I hustled Brad Templeton into writing PAL, so that there would be an assembler available for those who needed it. There had been a few assemblers around before that – Commodore had one, and another was the MAE system – but I was sure that somebody like Brad could do better.

Q: Even Superman had to put up with Kryptonite. Describe your worst experience as a software developer / technical writer.

A: My first publication of SuperMon in Compute! magazine had the wrong end-of-address supplied (my fault). I got a LOT of mail and phone calls on that one.

Q: I had heard a rumor pertaining to your software development habits that indicated you would approach a given project with full force. You would focus your undivided attention on it until it was complete. Is this rumor accurate?

A: Possibly. If I have a project under way, it “follows me around” until it’s complete; I fret over it and can’t put it away until all the pieces are in place.

Q: If so, did you ever change this methodology?

A: Not to any great extent. A half-written program bugs me, and I won’t rest until it’s finished.

I might, however, decide that I’m taking the wrong track, and scrap a program completely in order to start over. This isn’t a loss: the first attempt can show you what’s really wanted.

Q: Your articles made you seem a bit omniscient. You always had the inside info on the newest CBM computers and always seemed to be able to explain their complexities in a manner that would suggest that you had a lot of time to study them. I don’t know a whole lot about your employment during the mid/late 80’s. Were you affiliated with CBM? A beta-tester?

A: I had many friends in Commodore Canada, but I never worked for the company, although I did contract work for them on occasion.

The big problem was not getting information from Commodore; it was learning to ignore most of it. Commodore was bubbling over with ideas and plans that never came to fruition. There was no point in writing about projects that never happened (the Commodore music box? the cash register? the videotape/disk storage device?). I took the position: “Don’t tell me about it until it’s a real product!”.

Commodore Canada was an excellent source of information, and I relied on them to keep me from straying too far into technical speculation.

Q: Did you use any high-level languages on CBM computers?

A: BASIC, of course. COMAL, a BASIC derivative language from Denmark, was nicely constructed. Played around a little with C, but that language doesn’t fit comfortably into an 8-bit environment.

Q: What was your favorite computer that CBM produced?

A: I don’t know that I have a single favorite. The early PET/CBM machines were great “discovery” platforms, where we could investigate these wonderful new computers. The advent of the VIC-20 and the Commodore 64 brought color and sound, which added to the charm of these home computers; but they paid a penalty in slow disk access and screen width limitations. Today, perhaps the Commodore 128 ranks as the best, or at least the computer with most general usability. But it wasn’t produced in quantities as great as some of the earlier machines, and so the user community hasn’t been quite as furious.

Q: What kind of home computer do you currently use?

A: C128 .. Amiga .. Pentium system. All three.

Q: Who were your influences as related to writing?

A: Nobody specific. Just tried to write it as I would say it.

Q: Who were your influences as related to programming?

A: I’ve worked with a lot of sharp programmers over the years. Not one I can pick out especially.

Q: If you could relive the CBM glory years, would you do anything differently?

A: I don’t think so. On another path, I could have gone for big bucks; but making money carries a responsibility to support and service, and that would have taken the fun out of it.

Q: Is your current job computer-related?

A: I’m currently more or less retired.

Q: If you had not chosen a career in computing, what field of endeavor would you most likely have pursued?

A: Before computers, I worked in electronics and telecommunications.

Q: What are your current hobbies?

A: Reading; travel; films; raising my daughter. (That’s a hobby???)

Q: What sort of technical literature do you currently read?

A: Mostly reference material. Current magazines are heavy on the “what’s for sale” stream; to my mind, that’s not the fun part of computing.

Q: Are you surprised that a sort of “CBM renaissance” has been taking place the last few years ( …availability of C64 emulators on multiple platforms and such…the SuperCPU from CMD…).

A: It’s a shame that Commodore wasn’t able to/interested in keeping the 8-bit line going. It’s good to see that is happening.

Surprised? A little. But enthusiasts and user groups have always had a stronger effect than manufacturers are willing to admit.

Q: What is your opinion on the way consumer computing has evolved since the inception of the early PET machines?

A: The average computer user today has a lot less fun than we still have with the early machines. The industry message today is “Buy it and use it, and then turn it off .. don’t worry or think about how it all works”. That’s sure a lot less fun for tinkerers.

Q: What words of wisdom would you care to impart on a new (or revitalized) generation of CBM hackers?

A: Enjoy what you’re doing! If it becomes drudgery, you’re doing it wrong!

Posted in Programming | Tagged , , , | Leave a comment

Extending Commodore 64 BASIC

Back in the day, I used to write machine-language subroutines for the Commodore 64 that I would then call from a main program written in BASIC. I found it easier to use BASIC as the higher-order controller over a set of ML functions that usually did things for which CBM BASIC 2.0 was not well-suited.

In one case, I wrote an Xmodem file-transfer protocol handler. The routines to send data, receive data, read/write from/to files on disk, and computer checksums were all handled by machine-language routines.

I found it easier to experiment with the sometimes-touchy timing of the in-process handshakes using BASIC. ( Some Xmodem implementations on some BBS’s had personalities of their own. )

In my earliest programs, I would POKE addresses of data into predetermined spots in memory using BASIC and my ML code would know where to look to pick up those parameters.

Later, my friend Mike showed me a technique that allowed me to pass parameters right on the SYS command that invoked a particular machine-code routine.

While that technique worked well, I found myself memorizing numbers ( memory addresses or function indexes ) instead of some kind of mnemonic. The obvious answer was to change BASIC to incorporate my ML routines as new commands. There were a few different techniques for doing this sort of thing. I just had to pick one. I experimented with a few and never really got around to using one I liked until now … 30 years later.

I decided to use the “@” symbol to identify my new commands. At this time, I am only adding imperative commands. I may address extended functions later, but there’s an old Transactor article that really covers that topic well. Each of my command names will only be a single alphabetic letter in length.

I have not seen the technique I’m using employed in the way I am using it. The traditional approach to implementing a “@” sentinel character followed by a single-character involves “wedging” the CHRGET routine at $0073. This allows you to “wedge” CHRGET to allow your own code to examine the input stream as BASIC is poring over the input text. This technique causes extra time to be spent over the life of the BASIC program’s execution. I wanted to try to pare this down a bit more.

I’ve called this program “the Plug-in BASIC kernel” as it is meant for budding assembly-language coders to tinker with their own BASIC dialects. I’ve implemented only two commands to demonstrate how to use the kernel. The commands are “@C” ( clear the screen ) and “@B” ( change the border, background, and foreground text colors. )

The entire source is here:

; Plug-in BASIC Kernel
; Copyright (c) 2014 by
; Jim Lawless - jimbo@radiks.net
; MIT / X11 license
; See: http://www.mailsend-online.com/license2014.php

* = $c000

CHRGET = $0073
CHRGOT = $0079
SNERR = $AF08
NEWSTT = $a7ae
GONE = $a7e4
STROUT = $ab1e

   jsr intromsg

   lda #<newgone
   sta $0308
   lda #>newgone
   sta $0309
   rts

; table for commmands
table=*
   .word notimp-1 ; @a

   .word do_border-1 ; @b
   .word do_cls-1  ; @c

   .word notimp-1 ; @d
   .word notimp-1 ; @e
   .word notimp-1 ; @f
   .word notimp-1 ; @g
   .word notimp-1 ; @h
   .word notimp-1 ; @i
   .word notimp-1 ; @j
   .word notimp-1 ; @k
   .word notimp-1 ; @l
   .word notimp-1 ; @m
   .word notimp-1 ; @n
   .word notimp-1 ; @o
   .word notimp-1 ; @p
   .word notimp-1 ; @q
   .word notimp-1 ; @r
   .word notimp-1 ; @s
   .word notimp-1 ; @t
   .word notimp-1 ; @u
   .word notimp-1 ; @v
   .word notimp-1 ; @w
   .word notimp-1 ; @x
   .word notimp-1 ; @y
   .word notimp-1 ; @z

newgone = *
   jsr CHRGET
   php
   cmp #"@"
   beq newdispatch

; not our @ token ... jmp back
; into GONE
   plp
; jump past the JSR CHRGET call in GONE
   jmp GONE+3

newdispatch = *
   plp
   jsr dispatch
   jmp NEWSTT

dispatch = *
   jsr CHRGET
   cmp #'a'
   bcs contin1
   jmp SNERR
contin1 = *
   cmp #'z'
   bcc contin2
   jmp SNERR
contin2 =  *
   sec
   sbc #'a'
   cmp #'z'
   asl
   tax
   lda table+1,x
   pha
   lda table,x
   pha
   jmp CHRGET

msg .text "plug-in basic command not implemented..."
    .byte 0

notimp = *
   ldy #>msg
   lda #<msg
   jmp STROUT

intromsg = *
   ldy #>imsg
   lda #<imsg
   jmp STROUT 

imsg .text "plug-in basic kernel v 0.01a"
   .byte $0d
   .text "by jim lawless"
; please add your vanity text here for any
; customizations you make

   .byte 0

; syntax
;  @c
; clear the screen
do_cls = *
   lda #147
   jmp $ffd2

; syntax
; @b border,backgnd,char
; set border, background, and
; character color

do_border = *
   jsr $b79e ; get byte into .x
   stx $d020 ; set border
   jsr $aefd ; skip comma

   jsr $b79e ; get byte into .x
   stx $d021 ; set background
   jsr $aefd ; skip comma

   jsr $b79e ; get byte into .x
   stx $286  ; set text color
   rts

   end

Here’s how the program works.

Instead of wedging CHRGET, I changed the vector to GONE ( the routine that executes the next BASIC program token ) at locations $308 and $309 so that my routine would first take a look at the next token.

   lda #<newgone
   sta $0308
   lda #>newgone
   sta $0309
   rts

If that next token happened to be an “@” character, I would invoke my own dispatch routine. Otherwise, I would branch three bytes past the original GONE routine, popping the processor status from the original CHRGET call.

newgone = *
   jsr CHRGET
   php
   cmp #"@"
   beq newdispatch

; not our @ token ... jmp back
; into GONE
   plp
; jump past the JSR CHRGET call in GONE
   jmp GONE+3

In the new dispatch routine, I would check to see if the next character was in the range of ‘a’ through ‘z’ inclusive. If so, the letter would be translated to a value in the range of 0 to 25 inclusive. It would then be doubled and used as an offset into a table of machine-language routine addresses.

newdispatch = *
   plp
   jsr dispatch
   jmp NEWSTT

dispatch = *
   jsr CHRGET
   cmp #'a'
   bcs contin1
   jmp SNERR
contin1 = *
   cmp #'z'
   bcc contin2
   jmp SNERR
contin2 =  *
   sec
   sbc #'a'
   cmp #'z'
   asl
   tax
   lda table+1,x
   pha
   lda table,x
   pha
   jmp CHRGET

In order to change the code to add your own commands, simply point the entry in this table to your own routine’s address:

; table for commmands
table=*
   .word notimp-1 ; @a

   .word do_border-1 ; @b
   .word do_cls-1  ; @c

   .word notimp-1 ; @d
   .word notimp-1 ; @e
   .word notimp-1 ; @f
   .word notimp-1 ; @g
   .word notimp-1 ; @h
   .word notimp-1 ; @i
   .word notimp-1 ; @j
   .word notimp-1 ; @k
   .word notimp-1 ; @l
   .word notimp-1 ; @m
   .word notimp-1 ; @n
   .word notimp-1 ; @o
   .word notimp-1 ; @p
   .word notimp-1 ; @q
   .word notimp-1 ; @r
   .word notimp-1 ; @s
   .word notimp-1 ; @t
   .word notimp-1 ; @u
   .word notimp-1 ; @v
   .word notimp-1 ; @w
   .word notimp-1 ; @x
   .word notimp-1 ; @y
   .word notimp-1 ; @z

I have assembled the reference code to the common address $c000 (49152). To load the demo kernal, type:

load “plugin”,8,1

and then, type

sys 49152

…to activate it.

c64_1

c64_2

Let’s change the colors with the new @B command. The @B command expects three numeric-expression parameters: the border color, the background color, and the text color.

c64_3

c64_4

Now, let’s exercise the “@C” command to clear the screen. ( I find this one to be very handy. )

c64_5

c64_6

If you try a command that is not implemented, you’ll get a warning message, but it won’t generate a syntax error unless you’ve followed it with other parameters.

c64_7

These commands can be incorporated into BASIC programs themselves. You can download the source and *.P00 (PRG) file here:

http://www.mailsend-online.com/wp2/pluginbasic.zip

I’ve provided the above as something for others to tinker with.

Posted in Programming | Tagged , , | 1 Comment

Hello world!


C:\>debug
-e 200 "Hello, world!$"
-a
0B4F:0100 push cs
0B4F:0101 pop ds
0B4F:0102 mov ah,9
0B4F:0104 mov dx,200
0B4F:0107 int 21
0B4F:0109 ret
0B4F:010A
-g
Hello, world!
Program terminated normally

Greetings!

I am slowly moving assembly language / machine language code and related posts from my other blogs to this one.

I intend to write here about experiments with low-level code on a variety of computers and microprocessor trainers via emulators.

Posted in Programming | Tagged , , , | Leave a comment