Working on my own version of a 65C02-based SBC. Everything is open source and permissively licensed.

Similar projects worth following
My take on a 65C02 based SBC.

Source and Schematics can be found at:


I came across the various Ben Eaters 6502 Computer videos and addition to being impressed with his style, skill and knowledge, I also became intrigued. Back as an undergrad at JHU, one of my courses was in microprocessor architecture, and a project was a 6502 breadboard setup. I can't recall the full specifics; I am pretty sure that other than RAM and ROM (maybe 8k of each), there were no other 6502-family chips used in the project. Just some logic gates, switches and LEDs. Still, I had a blast with the project and took my time to plan every detail, both from a hardware placement standpoint to software design. When all was done, I was extremely proud of what I did and was also shocked when the Prof was just as impressed. He kept my wirewrap (no pushboards back then) and code as a prototype example for display in the course.

My first computer was, as with many, an Apple ][, which was also 6502 based, and I spent many, many, many hours coding on that, in both assembly and Basic. The skills I learned doing assembly language programming are still valuable to this day.

So when I saw Ben's videos, I was hooked. I decided to work on my own version... Here you go. All code and examples are available under permissive Open Source licenses, so please don't hesitate to use, and re-use, what you need.

Project Guidelines:

I'll be focusing on the 65C02 and its companion chips (eg: the 6522). Also, as much as possible, I'll make things as generic as possible so even if your design differs from mine, there will still be a lot that you can use, re-use or hack. I'll use more contemporary chips and solutions where it makes the design significantly more elegant, but won't let that over-shadow the actual retro nature of the project. 

  • Episode 5: Writing data from the 6502 to the Pi Pico

    Jim Jagielski02/20/2024 at 16:28 0 comments

    In the last episode we talked about the Input side of I/O on the JJ65C02 project, which involved the Pi Pico interfacing with the PS/2 Keyboard and sending the corresponding ASCII character to the 6502, via the VIA chip. In this episode we're looking at the Output side, where the 6502 needs to send data to the Pi Pico to then send out to the VGA monitor. We'll see how the Pi Pico reads from the 8 data lines and ensures compliance with the 6502 timing diagrams. We use a simple PIO program and the Pi Pico's interrupt system to fill our output buffer on route to the VGA subsystem.

  • Latest Video: all about the miniOS

    Jim Jagielski01/30/2024 at 10:18 0 comments

    In this latest video, we'll focus on miniOS, the operating system for the JJ65C02 project, which implements RAM testing, XMODEM file transfers, running and loading RAM images (pre-compiled 6502 codebases), WOZMON, and a port of the EhBASIC interpreter. miniOS is pure 65c02 source code and is available on GitHub. It's a great OS/boot-loader for BE6502-inspired projects.

  • The JJ65C02 Video Series

    Jim Jagielski01/12/2024 at 20:17 0 comments

    Episode 1 just dropped:

  • Thoughts on sprites

    Jim Jagielski12/28/2023 at 14:14 0 comments

    Implementation musings

    Now that the main details regarding the integration of the 6502 SBC and the Pi Pico I/O support chip are worked out, and working, I find myself mulling over details on how to add in sprite functionality (I know, I know... I should be working on adding audio to the Pico, but that isn't as intriguing right now). On one hand, I again want to resist the urge to make the JJ65C02 effort a Pi Pico-based system, with the 6502 as an afterthought, and instead want to focus on providing just enough capability to make it useful, but still be true to the whole retro vibe. In other words, I don't want this project to turn into another example of the tail wagging the dog.

    Due to the limitations imposed, the video setup is a single frame-buffer, bit-mapped display, and so any sprite (or tile) work needs to be able to quickly update the video buffer by drawing the sprite, but also quickly erase the sprite cleanly (restoring the background) as well as handle transparency. By this, I mean that sprites aren't drawn on top of the background (as a layer) but actually drawn IN the background.

    Some systems handle this by modifying the actual scanline data before it's rendered on the screen:

    1. Grab the scanline data from the frame buffer (the background)
    2. Draw the corresponding row data for the sprite overtop that scanline data
    3. Push the edited scanline to the VGA rendering system to have it printed out on the screen

    The advantage is that the actual frame buffer itself is never directly modified. The disadvantage is that this is pretty complex to fold into the current DMA driven design.

    Instead I'm looking into the following flow:

    1. Grab the memory area that the sprite will be written to from the frame buffer (VRAM)
    2. Store that away (backup)
    3. Now using a mask, write the sprite to that area
    4. Store away the x,y coordinates of the recent write
    5. When moving the sprite, restore the original memory area from the stored backup
    6. Jump to 1

    Sprite Details

    A sprite size of 16x16 fits nicely into a 640x480 screen and provides enough detail and depth to be useful. The actual sprite data itself will use 1byte/pixel, even though we only use 4bits/pixel internally. This is done so we can autogenerate the mask data from the actual sprite itself; by using $FF as code for transparent "color", we can load in the actual sprite data itself, and via shifting a single byte to a nibble, create the real sprite dataset and mask internally to the Pico and store them there, instead of transforming these on the fly, which takes time. In essence, the sprite data is sent from the 6502 to the Pico, which then takes take of converting it to a native format that can then be directly written to VRAM.

    There is one catch, and it is bothersome. Because we store (internally, on the Pico) 2 pixels per byte, the byte itself must be aligned with an even X coordinate. That is, if we wanted to draw the sprite starting at, say (1,100), then we would need the 2nd nibble of the 1st byte of that sprite data (the last 4bits) to be written to the 1st nibble of the corresponding VRAM byte (recall that pixel (0,100) and (1,100) are stored in a single byte). A simple hack is to simply force X to be even to ensure byte alignment, and that is likely the 1st route I'll try. Again, this is because we will be writing the sprite data to VRAM directly via DMA, and not pixel-by-pixel. There might be some way around this by extending masking transparency for the special case where X is odd, but it all depends on the performance impact of doing that.

    Internal to the Pico, the sprite will be a struct with 5 fields:

    1. the color-encoded bitmap (8x16=128bytes)
    2. the mask (also 128bytes)
    3. the stored background (128bytes again)
    4. Stored X coordinate
    5. Stored Y

    Altogether we're looking at ~390bytes per sprite stored on the Pico (padding??). Considering that we're only using ~153k of the Pi Pico RAM, that gives us room for plenty of sprites, though limiting it to something like 32 makes sense. Also, 8 bytes on the...

    Read more »

  • Thoughts on BASIC

    Jim Jagielski12/18/2023 at 14:08 0 comments

    Now that a lot of the hardware work has been done on the latest revision of JJ65C02, it's time to circle back and dive into the software side of things. My previous logs have described the updates to my miniOS for the system, and the integration with the Pi Pico, but the next stage is to see how best to update EhBasic to add graphics capabilities. This meant another deep-dive into the source for EhBasic and some thoughts about it which seemed like a good idea to post.

    As noted in an older logEhBasic was chosen over some other BASIC alternatives that exist out there. I touched on some reasons for picking it, instead of the others, but there were other factors that went into that decision. First of all, although not ideal, EhBasic did, at least, have pretty clear licensing behind it. The others had (and still have, IMO) somewhat questionable IP provenance: what are the exact copyright considerations for these codebases? They don't seem to have been released into the Public Domain, or under an Open Source license, which really means that we actually don't have any rights to use them. Sure, MSBasic and others have been around for awhile, and some could (and have) argue that if Gates were going to complain or sue, they would have done so by now. But for someone who takes these things seriously, that isn't good enough. 

    I also mentioned how of all the others, EhBasic was the easiest to port over to the ca65 toolchain, a non-trivial concern. Since I've baselined that development tool for all my work, and since it seems that most other serious 6502 hackers use it as well, providing an up-to-date port seemed like a worthwhile effort.

    And finally, the code itself is well-enough architectured that after some time looking it over and playing around with it, you get a good understanding of how it all works, which is important when you want to fix or enhance it.

    Which leads me into the next "theme" of this post, which is modifying EhBasic to support LOAD and SAVE.


    Now miniOS does not include any sort of file-system capability; it's expected that in addition to the actual console of the SBC (the PS/2 keyboard and VGA monitor), that any sort of file transfers will be done using the RS232/serial interface. This means that, at a core level, both LOAD and SAVE will use XMODEM as the actual xfer mechanism, and that all LOAD and SAVE need to do is setup the correct pointers so that XMODEM knows where to read or write. This itself was trivial.

    The real trick was that EhBasic doesn't store the text version of the BASIC program, but rather stores away its tokenized version which has already been "translated" from its original text. In essence, when you SAVE the program, you don't get (receive) the text version of your program, but a sort of binary version of it, meaning you can't then take that file and edit it with a standard text editor to make changes. It also means that you can't write the BASIC program on the host machine and then load it to EhBasic to run as-is. LOAD and SAVE all operate on this internal version of the BASIC program, not the original source itself.

    The simple way around this is to use the functionality of whatever terminal emulator you have and save/load the source of the program by doing a LIST and then a text capture of what is printed, or a slow text paste of the source at the EhBasic prompt (so it thinks you are typing in the program). This is ugly and I'm looking into how to instead implement  PLOAD and PSAVE which work on the actual source.


    Also as previously mentioned, I want to add to EhBasic the ability to use the graphics primitives provided by the Pi Pico support chip. Currently, one can easily call them using an extended set of ANSI/Xterm escape sequences (see here) but I was thinking that creating DRAW, PLOT, etc... BASIC commands might be easier. Adding the commands isn't really complicated, but the actual glue which then converts the BASIC parameters...

    Read more »

  • Pi Pico integrated with miniOS

    Jim Jagielski12/09/2023 at 19:12 0 comments

    The PCB for my JJ65C02 SBC is fully populated and work was done on integrating my miniOS with the Pi Pico I/O support chip. It now fully uses the PS/2 keyboard and VGA output as the system "console". I updated the miniOS to drop the old memory hexdump feature in preference to a port of WOZMON. WOZMON itself was updated to fully support the ca65 toolset, auto-conversion of lowercase input to uppercase, and an easy Quit command to return to the miniOS main menu.

    The system itself is running at 4MHz and is rock solid.

    On my TODO is further improvements to the miniOS and EhBASIC interpreter (ie, adding native graphics) and some initial testing on sound output. I'll also be pushing the speed a bit more and see if I can get to 6MHz.

  • Faster "EEPROM"

    Jim Jagielski12/08/2023 at 21:30 0 comments

    Like many, as I've starting ramping up the clock speed on my 6502-based SBC, it's the limited speed of the EEPROM (the AT28C256) which is the main limiting factor. A great replacement is to switch over to the DS1230Y Nonvolatile SRAM chip, which is pin compatible with the AT28C256 but much, much faster.

    Using the TL866II+ programmer, you can upload your "ROM" image quite easily as well:

    minipro -p "DS1230Y(RW)" -w ./minios.rom

  • PCBs delivered!

    Jim Jagielski11/24/2023 at 12:38 0 comments

    My order of PCBs just got delivered. They look fantastic and I'm quite happy with the quality and the speed of the shipment. Can't wait to start populating them.

  • Update Demo: Pi Pico I/O Support chip

    Jim Jagielski11/20/2023 at 16:16 0 comments

    Lots of work done over the last week or so on the I/O support chip for the JJ65C02 project. As a reminder, this Pi Pico is used for PS/2 keyboard input handling as well as VGA output and terminal emulation.

    Most of the work was on the ANSI/VT100 emulation side, adding in a blinking cursor, support for a large subset of Escape Sequences and more robust and reliable performance. I've also added in some extensions to the official Escape Sequences which allow me to draw graphics while in "terminal mode". These will be added to my port of EhBasic.

    All code and resources are available under permissive Open Source licenses on GitHub.

  • Raspberry Pi Pico Video and PS/2 Keyboard

    Jim Jagielski11/13/2023 at 18:01 0 comments

    I've pretty much completed the core library code for the VGA out and PS/2 Keyboard input handling on the Pi Pico, to be used as an A/V support chip on my JJ65C02 system and figured it was time for an update and even a video.

    The Pico outputs basic VGA at 640x480 with 16 colors. The entire frame is bit-mapped which allows for exacting graphics. The 16-color (4-bit) color palette is based on standard RGB with an extra Intensity bit, all of which are translated to the 0-0.7V VGA levels via a standard resistor ladder (I found that 470ohms for the RGB signals and 1kohms for the Intensity signal seems to work best).

    The VGA library supports Hunter-Adams graphics library with some additions, such as multiple fonts, scrolling, and a simple "text mode". The overall goal is to support a useful subset of Xterm/VT100 escape codes in addition to graphics primitives.

    I also use the Pico for PS/2 keyboard input handling, and the conversion of the scancodes to ASCII values (upper case, lower case, and control codes).

    Now that the basics are in place, I'll be ordering PCBs and interfacing the Pico with the 6502 board itself. Keyboard input will be transferred from the Pico to a VIA chip (with IRQ handling) and ASCII will be sent to the Pico via a different VIA port with a simple DATA_READY signal pin. With the single GPIO pin left over on the Pico, I've connected that to a simple audio amp circuit, so that I can eventually add audio waveform creation to the Pico as well.

    I'm avoiding the temptation to add a LOT of functionality to the Pico; it is, after all, a support chip, not the core of the system.

    You can see some of the basics running in the below video demo.

View all 18 project logs

Enjoy this project?



Peabody1929 wrote 11/03/2023 at 23:48 point

I'm looking forward to seeing a schematic update with the RP2040 included in the design.

  Are you sure? yes | no

Jim Jagielski wrote 11/14/2023 at 18:12 point

The schematic can be found at :-)

  Are you sure? yes | no

hubidrei wrote 10/21/2023 at 15:52 point

Why not let the RP2040 do all the RAM, ROM, IO. Like the NEO6502? 

The hard part is the programming of the RP2040.

  Are you sure? yes | no

Jim Jagielski wrote 10/23/2023 at 14:05 point

The main reason is that I want to use it _just_ for the things that don't have viable "retro" alternatives. With Video and Sound, the old-school chips simply aren't available anymore, but that's not the case with RAM or ROM.

I want to avoid the trap that projects like the Commander X16 and others fell into: in those projects, it seems like the 6502 is an after thought. You aren't programming the 6502; instead you are using the 6502 to program/run the Vera chip (for example).

The draw of real retro computing, IMO, is that it forces you to be creative and innovative, by seeing the limitations as a challenge to work through, not as something to work _around_.

  Are you sure? yes | no

Dan Maloney wrote 10/12/2023 at 17:13 point

Thanks for bringing this project over to! Looking forward to more details

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates