The Life and Times of an 80’s Game Programmer – Putting it all together
[ 3 comments ]
How does game development back in the early 80’s compare to game development today?
For starters, the computers of that era were far less powerful and didn’t have anywhere near the graphics and audio capabilities of today’s power houses. My TRS-80 was monochrome and offered a graphic resolution of only 128 x 48 pixels and sound was generated by toggling the cassette output port on and off.
Back then, a computer generally ran at around 2 megahertz and a fast one did 4 megahertz. We played with RAM sizes of 4K to 64K and unless you were lucky enough to afford a floppy disk drive, you saved all your work on cassette tapes.
Compared to today, programmers worked with quite primitive equipment but we just got on with the job and developed to the best of our abilities with whatever we could afford.
There were no boundaries to creativity.
I developed most of my TRS-80 Model 1 games in Z-80 assembly language. This code compiles to raw machine language and almost all commercial arcade style games of the era were created in this language since it allowed the maximum processing speed from the technology of the day.
Programming in assembly language was not for the faint hearted, not so much because it was a hard language to learn but because each instruction did so little in comparison to other higher level languages. To print a word on the screen required a mini program in itself whereas languages such as BASIC could achieve this by simply executing the command PRINT”HELLO WORLD”.
Assembly language requires a thorough understanding of the operation of the computer and how the hardware operated and I enjoyed this feeling of total control of the system. Being tied so closely to the hardware also made for some spectacular system crashes when errors were made. Assembly language was a very “precise” language with little margin for error. A programmer had to have a clear understanding in his mind of what the computer was doing at all times.
I wrote all my code, routine by routine, with pencil and paper. I didn’t have a printer so my hand written notes served as the hardcopy of my code to peruse at any time. It also meant I could create code anywhere… even during classes in high school!
The teacher may have been talking chemistry but mind was piecing together the code to my next blockbuster game!
This also filled in the time during cassette tape loads. Loading data from cassette tape would take about 3 minutes to load the assembly language development program (Editor/Assembler) into the computer. It would then take another 5 minutes to load my source code that I had created so far. During this time I was creating new code on paper or debugging an error with my current code. When the tape finished loading, I transcribed my new lines to the Editor/Assembler.
I then saved my new work back to cassette tape (another 5 minutes) then compiled my code to machine language (3 more minutes) into an executable file.
After resetting the computer, I would load the compiled code into the computer for testing. If it worked, I would move on to create the next piece of code. If it failed, then the whole cassette loading process would repeat until I finally had it debugged and working correctly.
I would always use high quality cassette tapes for my development work and I would frequently clean the cassette tape heads with alcohol to maintain reliability.
For graphics design, there was no Photoshop or fancy graphics editors back then. I designed all of the graphics on graphic worksheets with a pencil and eraser. I would create pages of graphic objects and level layouts.
Then I would create a simple program in BASIC to recreate these graphics into the memory of the computer and save these to a cassette file. I documented all of the dimensions and memory locations of all the graphics so that I could access them from within my code.
When a game was finished, I created my own packaging and recorded each distribution cassette on my computer. My artwork was all hand drawn and quite amateurish but it was all I could afford.
The artwork, instruction sheet and cassette tape was then put into click seal “zippy” plastic bags for sale.
In summary, I think the basic process of game design and product manufacturing hasn’t changed too much. It’s just that it is more “refined” and better funded. I was only a kid at school with no money so I did everything myself on a shoestring budget. I am proud of what I achieved and can honestly say that not many could do what I did.
They were the early “Halcyon Days” of the game industry when we felt we were creating something new and special. These experiences will remain with us forever.
Back in the 80’s, with only around 32k available and no “games-engine” technology, developing games required that everything be hand-coded. That’s more then just the game – it was the graphics functions, sound functions, code to read the keyboard and joystick and game logic itself. Even all that data that games require to store information like graphics, music, scores, data for game levels, etc, etc had to be squeezed into that now-ridiculously small amount of memory.
This meant that any and all code had to be seriously optimized for performance, and imho its something that many of todays developers don’t need to be concerned with – we’re spoilt with immense amounts of RAM, the CPU/GPU speeds are so fast that they literally take care of what in the 80’s was often a challenge, and there are many “game engines” that have all of that complex code built right in – you just supply the artwork and the logic, and it does the hard parts.
This is why machine code was so critical back then. BASIC was a great programming language for most things, but its speed was way too slow to update the screen quickly, read the joystick or keyboard, update the player and alien locations or play sound effects. When I started off with more advanced game development, I would write the critical functions in Machine code – drawing the sprites, making the sounds. Those would be then called from within the game that was written in BASIC. It gave me the best of both worlds back then – the easier way to develop the game and its logic using BASIC, and the super-fast speed of machine code to do those really intensive tasks.
Later on, I started to code games completely in machine code. This is where I discovered that understanding not just the language was important, but the time taken for each CPU command to execute was just as important.
I recall a sideways scroller I was developing needed to have parallax scrolling stars and lots of sprites to be displayed. The hardest thing back then was everything had to be fed directly to the screen memory, and that meant well-oiled coding to draw sprites and elements onto the screen very quickly – and equally also erase them quickly before redrawing them. As fast as machine code is, when there is a lot of stuff to process its often not updated as fast as the TV screen refresh was (25 times a second) and this is why there were a lot of 80’s games that had flickering graphics.
I had a machine-code reference book that not only contained the op-codes (machine code commands) but the t-states of each. A t-state is the number of microseconds that a command would take to execute inside the processor.
For my game, I discovered that the way I’d been originally drawing to the screen was fast and was taking just a few microseconds… But when that’s a few microseconds * multiple sized images and sprites – ok, back to the issue of flickering.
While thinking about how to make a smooth scrolling screen-load of graphics, I thought that perhaps I could create the graphics in memory first, and then pipe that all back to the actual screen itself. That then lead to something that is now common-place in many game engines – a back buffer – a copy of a screen where you would build your graphics image of the game first, and then swap it out to the display. It avoided the flickering completely as all drawing and erasing happened off-screen first.
I tried it – it worked, but copying the information from one memory address back to the screen memory was still just slow enough to create a little wiggling on screen.
When I reviewed my reference book, I found that the t-states for simple commands to push (store) and pop (retrieve) data from a stack (a stack being an area of memory for the cpu to store data) was about 5 times faster then my copy code… And it was a single command, rather then 2 or 3 reuiqred to “get byte from memory” and “write byte to screen memory”.
The op-codes to work with this stack seemed to be a pretty good option. Once I’d drawn my game screen into memory, I told the code to change this “stack” memory location to the screen memory. I’d then simply push the data from the memory where I’d drawn the screen into this “stack” and it would fill the screen memory extremely quickly.
Viole! Amazingly smooth scrolling graphics and no more flickering.
So where I’m going with this small snippet is that this is what 80’s game programming was all about for me. It wasn’t just developing a game, it was the challenge of developing fast code wherever you could and spending a lot of time optimizing the way memory was used… This type of stuff is also why computer programmers in the 80’s were called geeks and nerds. You had to be “geeky” to enjoy the thrill of code optimization… Fun times!
As I said – today its all handled by the technology. We’ve come a long way, but like everything, this stuff had to start somewhere to even exist. 🙂
For those curious – I found and scanned all of my development notebook for the side-scroller. Its all the algorithms, concepts and Z80 code neatly handwritten with love and care. 😉
Hi, where can I find resourced on how to program like that?
I want to code a game for a microcontroller and a simple LCD display,so I need to learn how to do low level stuff like this. I’m able to draw sprites and animate them but I need resources on how to implement a full game!