A couple people have asked me what tools I use during these programming videos, so I thought I’d go through the list. The list is below the video here too. FreeBSD i3 (x11-wm/i3 x11/i3status) Emacs (editors/emacs) org-mode for planning (.org) asm-mode for assembly files (.a) magit git (devel/git) tmux (sysutils/tmux) ACME cross assembler rlwrap (devel/rlwrap) Vice (emulators/vice) OBS (multimedia/obs-studio) DroidCam (Google Play on phone) ffmpeg (multimedia/ffmpeg)
Didn’t get a lot of code written in this one. I got started on the trickiest part of the algorithm, where we need to process a sliding window of pointers through a block of data, and spent a lot of time trying to figure out how best to do it. I think I have it worked out now, so it should be easier from here on out.
More on the 80-column display. First we go through how to set attributes like color, flash, and underline for characters on the text display, then turned to the VDC’s graphics bitmap mode.
Continuing on with the SHA-256 calculator, we write more routines for copying blocks of memory in different ways, and the remaining low-level functions required by the algorithm. Next time we’ll be moving up a step or two to higher-level parts of the program. The hat is a Lewis Round Barn hat from the Old Tyme Association. If you’ve been to the Adams County Fair outside Mendon, you know what that’s about.
Started writing routines to drive the 80-column display. I’m hoping to use these in the Farm game, but they’ll be generally useful for any program that uses the RGBi display. Next time I’ll get into the graphical bitmap, which few programs explored for that display.
Here’s a whiteboard tutorial on programming the 80-column screen on the Commodore 128. It’s very different from the 40-column VIC display, since you have no direct access to 80-column screen memory and have to program it indirectly by reading and writing to the VDC’s registers, which requires a handshaking process through a pair of registers at $D600 and $D601 in the C128’s I/O block. There will be another video soon demonstrating how to use the little routines here to do actual work.
Continuing on with the sha256 hash calculator, we create some of the intermediate functions that use the boolean and bit-shifting routines we wrote in the last session.
No coding in this one, just introducing a new project: a game in the spirit of Stardew Valley. I say “in the spirit of” because it would be impossible to duplicate the game on an 8-bit system, even if copyright weren’t an issue. But I think it’ll be a good challenge to see how much of it can be done, with expectations scaled back drastically in terms of graphics and sound.
Started programming on the sha256 program. So far, the easy parts have been fairly easy, creating routines to do boolean operations and bit-shifts on 32-bit values. I think it’ll get tougher as we start putting those pieces together to form the various formulas, but it should keep coming together piece by piece. I realized as I was watching it to check the recording quality that I could simplify the first couple routines a lot and lose the INX/DEX stuff, so that’ll be first on the agenda for next time.
Now that the Worm program is finished, I’m starting two new projects to work on in parallel. The other one will be a game, once I work out some details. This one should be easier. It’s a 6502 implementation of a SHA-256 hash calculator. I thought it’d be interesting to see how well an 8-bit system could handle calculations that were designed for 32-bit (or more) processors, and how difficult it would be to implement.
Memory management (banking) in the C128 is unlike the C64 or other 8-bit Commodores, since it uses the MMU to switch blocks of ROM and RAM in and out of service. This can seem kind of complicated at first, but it’s essential to taking full advantage of the resources that the C128 provides, so I thought I’d do a whiteboard tutorial on how banking works and how to do it in assembly.
The Worm game is finished! It works pretty much how the BSD version does, which was the goal. It could be prettied up further than that with multiple colors and sounds or other new features, so if anyone wants to fork the source from the repository and do that, or use it in any other way, feel free. I’m ready to move on to something else, probably a more complex game with bitmap graphics, sprites, and sound.
In this session, we change the color scheme and show how to fill color RAM to set the foreground color for text characters. We add a delay between moves and change the keyboard routine so a key can be held down without repeating too fast, and also to put a time limit on moves. Next time we’ll be adding a final score display and a “play again” question, as well as a graceful exit back to BASIC.
There may be some stack pointer manipulation coming up in the next Worm video, so I thought I’d do a mid-week video explaining the 6502 stack in detail. This one goes over how to use it and demonstrates what happens under the hood, instruction by instruction, then how to manipulate the pointer manually if you need to. It also touches on the pitfalls in using the stack and what to watch out for.
It’s customary when making videos about 1980’s technology to wear a funny or ironic retro t-shirt. I have only one of those, so instead, enjoy one of my collection of local farmer hats. In this one we add code to keep the tail pointer-to-pointer (TAILP) updated, to handle collisions with digits on the screen, and to keep the worm at the proper length, growing it when it “eats” digits. All the worm functionality is finished now, so next time we’ll work on the end-game score display, and a better keyboard-entry routine.
I covered these addressing modes in video #14 on the addressing modes in general, but I’ve had a couple of questions about the indirect modes specifically. I thought it might help to draw out examples on the whiteboard, since they are more complicated than the other modes. Hopefully watching this along with the examples in #14 will make it clearer. Indirect addressing, especially the Y-indirect (indirect indexed), is a powerful mode that lets you setup pointers into memory that can be adjusted on the fly, as we do with HEADP and TAILP in the worm program.
While working on the Worm program in #16, I realized we need to use pointers to pointers, which is kind of a complicated concept. I didn’t think my impromptu explanation there was very clear, so I thought it’d work better to draw it out visually and walk through what happens. This method will allow us to keep track of the parts that make up the worm, in order from head to tail, so we can drop the tail characters as the worm moves along.
Continuing with the Worm game. I thought I had worked out how to make the tail end of the worm go away, and then once I started to describe it I realized it wouldn’t be that simple. We have to keep track of each “body part” of the worm in order from front to back, so we always know which one is the next to drop off as the worm “moves.
In this video we continue working on the Worm game started in #13, adding collision detection and the random placement of a digit on the screen for the player to guide the worm to. Next time, we’ll start by debugging why the digit is always 5 instead of randomly 1-8 and always appears in the third quadrant of the screen. This series is undergoing a slight re-branding. When I started it, I was focused only on the 6502 microprocessor, which is found in many different computers and products from the 1980s (Commodore computers, Nintendo Entertainment System, Atari consoles, etc.
This is sort of a bonus video in the middle of the week, to cover something I should have done near the beginning of the series. Someone on an assembly forum asked about 6502 addressing modes, and someone else said they seemed awfully complicated, so I wished I had a video I could point them to that explains them. So here it is. The sun went down while I was recording, so the webcam got darker than I realized.
Starting a new project on the Commodore 128: the game Worm, an old game for text-based terminals. In this first part, we lay out the screen border and write the code to move the head of the worm around. The next part should cover detecting collisions with the border and making the body of the worm work. I’ve created a top-level page on my blog that will link to this series of videos and related resources here: 6502 Assembly Language Programming
With the Game of Life working at the end of the last session, I thought we’d do something a little different this time, converting a famous one-line BASIC program into assembly. In the process, we had to write code to scroll the screen as new lines appear at the bottom. Enjoy several minutes in the middle of me rubbing my furrowed brow as I struggle to figure out why it’s broken at one point.
In this session we added a “press a key to continue” feature to the program, and then worked out the bug that was keeping certain cells from updating properly. Then I talked a bit about the possibility of refactoring the algorithm for walking through the cells and determining their neighbors to make it faster, and whether to do that next time or move on to another project. Comments and suggestions are welcome.
I realized after recording the last video that my method of converting the work area into the game board was overly complicated, so the first order of business this time was to simplify that. That also got rid of the buggy behavior we ended with last time. Then we do some self-modifying code to save bytes, which is cool but also shows how easily that can result in bugs. Got that working, but there still seem to be a few cells that don’t work right.
Continuing with our Game of Life, we work out the code to calculate the number of neighbors for each cell and then rebuild the cell grid for each turn. Also improved the randomness of the initial grid layout. There’s a bug somewhere that’s throwing off the rebuild, so debugging that will be the first task for next time.
I started coding Conway’s Game of Life in 6502 assembly. This video covers the initial setup, laying out the game grid, filling in random (“random”?) cells, and thinking about how to process neighboring cells. I expect the full game to take a few more videos, as I have some ideas to add after getting the basic game working.
I finally finished the next entry in my 6502 Assembly Language series yesterday, and it took overnight to process and publish. In this one I debug the print-a-number code from #6, and then talk a bit about what to do next. I think I’m going to write a version of Conway’s Game of Life, as a way to develop an operating system kernel along the way. A game will need basic functions like “print a character at coordinates x,y”, so I think that’ll be an interesting way to do it.
Continuing on from the last video, we start working on code to print a number on the screen, one digit at a time. Debugging to come in the next installment.
Continuing with the code we wrote in #4, we compare the code the assembler understands, with comments and labels, to the machine code it produces, using the machine language monitor in the Commodore 128 to disassemble it. We also convert the binary division routine from #4 to handle 16-bit dividends, and then 32-bit. Also discussed the issue of where to store working values in memory. A side note: I was puzzled during the video why my perl command was printing a 1 after the expected value of “b27”.
We walk through an assembly language routine to divide one 8-bit value by another on the 6502. It was a little darker in there than I realized, so I hope it’s watchable, since I don’t want to do it all over. As usual, questions and comments are welcome. The next chapter will incorporate this routine into a larger bit of code.
This video introduces the 56 op-codes in the 6502 assembly language instruction set, and gives examples of the commonly used ones, using a Commodore 128 monitor. Here’s the list of op-codes divided up by function. This is the third video in my ongoing 6502 assembly language series. If you’re not familiar with the 6502 hardware, or with binary math and bitwise operations, check out the two previous videos in the series for info on those.
I’ll be doing videos to demonstrate the 6502 instructions soon, and you can’t understand several of them without a basic understanding of binary math. It’s not hard, but it’s something that isn’t taught in math classes anymore, or is touched on as a concept but not really absorbed. This video demonstrates how to write binary numbers and translate them to decimal, how to add them, and how to convert to hexadecimal (base 16).
I plan to do some demonstrations of assembly language programming, so I thought I’d do a short intro. This is about the 6502 family of microprocessors, which were used in many computers of the 1980s, and are still produced by the millions for embedded hardware and hobby projects. The 6502 is a pretty easy CPU to program, because it has a fairly small set of instructions, and yet it’s powerful enough to do interesting things.