mos6502 Archive

Commodore 128 Assembly #33: My Programming Environment

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)

Commodore 128 Assembly #32: SHA-256 Part 4

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.

Commodore 128 Assembly #31: VDC 80-Column Attributes & Graphics

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.

Commodore 128 Assembly #30: SHA-256 Part 3

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. It’s not really my style of hat, but it’s local, so I thought I’d show it off.

Also, I’ve created a Patreon page for my programming videos. There’s no obligation, as all the videos and code will remain free for everyone. But if you’d like to support the project, check it out there with my thanks!

Commodore 128 Assembly #29: VDC 80-Column Routines

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.

Commodore 128 Assembly #28: Programming the 80-Column 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.

Commodore 128 Assembly #27: SHA-256 Part 2

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.

Commodore 128 Assembly #26: Farm Game part #0

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. Along the way I’ll be doing tutorials on more of the 128’s features, like the 80-column display. I’ll start programming on it in part #1 later this week.

Commodore 128 Assembly #25: SHA-256 Part 1

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.

If you landed here and don’t know what SHA-256 is, the Part 0 video introduces it and lays out the algorithm step by step.

Commodore 128 Assembly #24: SHA-256 Part 0

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.

In this video, we introduce the concepts involved and outline the pieces that will go into it. The programming will start in part 1.

Commodore 128 Assembly Programming #23: Banking

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.

Looks like I still need to work on lighting. I added a lamp, but there are still some shadows. I hope that doesn’t make it too hard to read my handwriting.

Commodore 128 Assembly Programming #22: Worm part 6

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. Still trying to decide what, exactly.

Commodore 128 Assembly Programming #21: Worm part 5

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.

If you want to discuss this video or any of the series, a good place would be the C128 subreddit. I check in there daily.

Commodore 128 Assembly Programming #20: Understanding the 6502 Stack

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.

Commodore 128 Assembly Programming #19: Worm part 4

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.

6502 Assembly Language #18: Indirect Addressing

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.

Video production notes: The quality on these still isn’t very good. Seems like there are either glares or shadows, so that’s something to keep working on. For the audio, I tried recording that on my phone in my shirt pocket, so the video camera didn’t have to try to pick it up from several feet away. Then it was just a matter of laying one over the other with ffmpeg and working out the timing.

6502 Assembly Language #17: Pointers to Pointers

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. And it doesn’t take much work, because we only need to adjust two pointers and add one other to a list each time we move. That’s quite a bit faster than a couple other methods I was thinking of.

Next time, back to the code.

Commodore 128 Assembly Programming #16: Worm part 3

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.” That means we will have a list of pointers to those body parts, and pointers into that list.

Double pointers are challenging, so that will be a fun task I wasn’t expecting. I may do a whiteboard video to draw it out better than I explained it here. The pointer list will be in a 2K area of memory, wrapping around to the beginning if necessary, with two pointers into that list for the head and tail of the worm. Got the head pointer done in this video, and will add the tail pointer and the code to move the tail along in the next one.

6502 Assembly #15: Worm on the Commodore 128 Part 2

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.) and is still in wide use today. But when it comes to writing programs that actually run on something, you have to program for a particular platform. While the 6502 itself doesn’t change, the methods of input/output, printing things on the display, memory management, and so on vary greatly from one 6502-based system to another.

In other words, if you write a 6502 routine to multiple two values in memory, you can use that unchanged on any 6502 system. If you want to print those values on the screen, send them to a printer, or save them to a disk file, then it matters what system you’re on.

So I will be (and have been) writing these programs for the Commodore 128, for three reasons. First, it’s the system I’m familiar with, having owned a few back in the day, and I always wanted to do more with it. Second, it’s the most powerful system that the VICE emulator does. Since I’m using an emulator anyway, I might as well use the emulated machine that has the most power and features. Third, there seem to be very few people out there programming for the C128. There’s a lot of activity around the C64, with new games and products popping up regularly, but very little for the C128. A new YouTube channel just appeared called Nybbles and Bytes, where she plans to convert a Javascript game she wrote to the C128, and her video and some comments on it made me realize this isn’t well-traveled territory.

Fourth (insert Monty Python bit), if I ever buy a real Commodore again, it will be a C128, and then my programs will run on it.

That means I’ll be expanding into some of the C128’s more unique features, like the 80-column screen and banked RAM. The programming will still all be 6502, but we will get deeper into the C128’s hardware and some cool stuff you can do with it.

6502 Assembly Language #14: Addressing Modes

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. I didn’t figure anyone needed to see my face badly enough to redo the whole thing.

6502 Assembly Language #13: Worm Part 1

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

6502 Assembly Language #12: 10 PRINT

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. Technical details below the video.

I didn’t explain in the video how I found the problem, so I’ll do that here. First, here was the problem code:

        ldy #0                  ; loop 40 spaces
yloop:
        lda (NLINE),y
        sta (CLINE),y
        iny
        cmp #40
        bne yloop

I meant it to loop on the Y register, incrementing it from 0 up to 40, then falling out of the loop when Y==40. However, because I used CMP instead of CPY, it was comparing the accumulator (A) to 40 instead of Y. That seemed to work on the first few lines of the screen because 40 is the character code for a left parenthesis, and there was one of those in each line. So when it loaded that left parenthesis into A, that caused the loop to end so it could go on to the next line. On the fourth line, there were no left parentheses, so it looped forever.

What clued me in was when I let the code run and broke into it several times, and it was always somewhere in this loop, and then I noticed the Y register had all sorts of values, usually greater than 40. So I realized somehow it was getting past that comparison. Then it hit me I had the wrong opcode.

A technical note: For a webcam, I use my phone with an app called DroidCam that transmits the video to a web browser via wireless, and then I can capture that browser window in OBS and stick it in a corner of the screen. That’s handy, but it adds about a half-second delay, so my face is about a half-second behind the audio. It’s not a big deal, but it’s annoying. It annoys me anyway when I watch them to verify everything worked. So I fixed that by running the full video through an ffmpeg filter to crop that part of the video out, dropping the first 0.5 seconds, then another filter to overlay that cropped portion back over the full thing. I don’t know if it matches exactly yet, but it’s much better than it was. Only problem is that late in the video I expanded the C128 screen large enough to get into that space a bit, so it affected the bottom-right corner of that too. I’ll have to be more careful not to run them into each other next time.

Another note: I recorded this one the full size of the screen, with no shrinkage. These compress pretty well, since most of the screen isn’t changing most of the time. They’re larger at this size, but not too large to upload. I hope that makes them clearer for anyone who watches or downloads them in high quality.

One more: I noticed my last couple 6502 videos showed up twice on Bitchute. Turns out that’s because I’d given them my YouTube channel ID when I signed up, and at some point they started automatically pulling over videos that show up on my YouTube channel. That’s convenient, except that I really want to put them on Bitchute first to encourage people to use it. Also, the ones they get from YouTube seem to be lower quality. So I took the channel ID out to keep them from getting doubled-up.

6502 Assembly Language #11: Game of Life Part 4

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.

6502 Assembly Language #10: Game of Life Part 3

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. Next step will be to add some features like the ability to control the progress of the game with the keyboard, so we can slow it down and watch it work turn-by-turn.

I spent the last several minutes of this one trying to figure out which memory location keypresses arrive in, so I thought about cutting that out, but I did say at the beginning of this series that you’d get to see it all, so it’s in there.

Now that the holidays are over, I’ll post the next video in this series each Monday.

6502 Assembly Language #9: Game of Life Part 2

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.

6502 Assembly Language #8: Game of Life Part 1

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.

6502 Assembly Language #7: Debugging and Future Plans

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. The game will provide something to see on screen, and the kernel functions will show how to interact with hardware registers.

6502 Assembly Language #6: Printing a Number

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.

6502 Assembly Language #5: From Assember to Monitor

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”. I realized afterwards I had written “print printf…” so the “printf” was prnting out the “b27” and then “print” was printing the succesful return value of the printf, which was 1.

Assembly Language #04: Binary Division on the 6502

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.

Assembly #03: Intro to 6502 Instruction Set

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.

If you’re serious about learning 6502 assembly, there are some good books available. The one I used for a couple of examples in this video is Commodore 128 Assembly Language Programming, published by SAMS. It’s long out of print, of course, and hard to come by, but you can find a scanned PDF of it here.

I’m trying to decide what to program, now that I’ve covered the introductory materials. I’m open to suggestions, and also welcome any questions about the videos so far, at aaron@baugher.biz.

Intro to Binary & Hexadecimal and Bitwise Operations

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 hope it’s watchable enough. This was the fourth take, after recording it with my phone failed for various reasons (not even sure why on the last one, it just stopped), and switched to my old Flip camera.

Intro to 6502 Assembly Language Programming

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.

I did forget to mention a few instructions, mainly the ones having to do with comparing numbers and doing boolean operations. I think I’ll cover those in a video on the full instruction set, and maybe another video just on binary arithmetic and hexadecimal, since those are pretty much a necessity for assembly language work.

My camera kept refocusing once in a while, but I hope that’s not too distracting.