Skip to content

6502 Based Homebrews

Curt J. Sampson edited this page Apr 23, 2024 · 5 revisions

Hellorld! on 6502-based Homebrew Computers

The 6502 is one of the most venerable processors ever made and was featured in a plethora of machines, notably from Apple and Commodore. These homebrew computers take one of the greatest CPUs ever made and use it in some of the most fascinating ways to print "Hellorld!" Entries are in alphabetical order.

Quick links:

Barnacle's ROM-less 6502 Catelyn's 6502 Testbed CommodoreZ's Cactus Jayne's 6502 Homebrew
Kaos116's 6502 Maniek86's 6502 Makarcz's 6502 Kit Makarcz's MKHBC-8-R2
Makarcz's PAL-1 Mspeculatrix's Zolatron64 Steckschwein

Barnacle's ROM-less 6502

I'm (barnacle) looking at ways in which a single board computer can be used in the same way as a modern microcontroller development board - say an Arduino, a Nucleo, or some of the RISCV and ARM dev boards. Basically, write code on a development system and then upload to an SBC. This is a proof of concept of one way of doing this which has only RAM on the board - no rom/eprom/eeprom/flash/whatever. It takes a carefully crafted binary image which is simply generated from a hex file.

The whole point with this homebrew is to get data into the ram before the processor notices it. The lv8153 is a very handy chip, it takes a TTL/CMOS level UART packet and converts that to a parallel output without requiring any clocks; it auto-baud-rates up to about 20kb/s. Flipflop U1A is set by the reset and enables the lv8153s while disabling the 65c02 and holding it in reset. A packet of six bytes sets the address and data lv8153s and the byte written to the data decoder automatically writes to ram. A write to the fourth lv8153 resets U1A and that changes the bus access to the processor and takes it out of reset. It goes to the normal reset vector and takes it from there.

The lv8153s and the 6850 share the same serial line (I use an FTDI usb cable to provide both the data path and power) but run at different rates; once the system boots it programs the 6850 and life proceeds as normal. I included a loop where the UART simply echoes incoming data until it sees a '+' character so that it doesn't start outputing data until the host terminal is configured.

Code:

00000000   0D 0A 48 65  6C 6C 6F 72  6C 64 0D 0A  00 A9 03 8D  ..Hellorld......
00000010   00 A0 A9 95  8D 00 A0 20  52 FF 48 20  33 FF 68 C9  ....... R.H 3.h.
00000020   2B D0 F4 A0  00 B9 00 FF  48 20 33 FF  C8 68 D0 F5  +.......H 3..h..
00000030   4C 17 FF 48  AD 00 A0 29  02 C9 02 D0  F7 68 8D 01  L..H...).....h..
00000040   A0 60 AD 00  A0 29 01 C9  01 D0 05 AD  01 A0 38 60  ....)........8
00000050   18 60 20 42  FF 90 FB 60  FF FF FF FF  FF FF FF FF  . B...........
00000060   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
00000070   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
00000080   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
00000090   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
000000A0   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
000000B0   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
000000C0   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
000000D0   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
000000E0   FF FF FF FF  FF FF FF FF  FF FF FF FF  FF FF FF FF  ................
000000F0   FF FF FF FF  FF FF FF FF  FF FF 0D FF  0D FF 0D FF  ................

Full schematic available here!

Catelyn's 6502 Testbed

Sometimes you gotta build a computer to test things for your computer. Catelyn did just that with the 6502 Testbed seen here. At the heart is a 65C02, which is hidden under the address decode board alongside a 65C22 and 32K of RAM (only 16k is accessible in the current configuration). Above that are two ROMs, one is 512k of Flash (though only 32k is currently accessible) and the other is decoder for the 7-segment displays. Over on the bottom right is a 16C550 UART chip, which, along with the address decoding logic board, is removable to allow for more configurability for testing. While it may just be a testbed for something even cooler in the works, it can still "Hellorld!" with the best of them!

Code:

W2800: 48 65 6C 6C 6F 72 6C 64 21 0D 0A 00 00
W2000: A9 28 A2 00 20 17 81 60
G2000

CommodoreZ's Cactus

This one is very cool, not because of the code (it's really just PRINT "HELLORLD!" because it's running Basic), but because of what it's running on: The Cactus. The Cactus is homebrew 8-bit computer designed and built from the ground up by the talented CommodoreZ using individual cards that were all hand-wired on perfboard. At the heart is a W65C02S @ 1MHz with 32k SRAM, 2k NVRAM, a 16K EPROM and a host of other brilliant stuff. The front panel blinkenlights are a epic, but there is serial support, which means this homebrew can not only run OSI Basic, but also display "Hellorld!" on a terminal!

More on Cactus here!

Hellorld_Cactus_2

Jayne's 6502 Homebrew

I always love seeing Hellorld on homebrew systems, and this one is a really clean homebrew! The board itself is based on a Western Design Centre 65C02, clocked at 4MHz (though it can go to 14MHz), along with a 65C22 VIA and 65C51 ACIA for terminal communication. There is 128k of flash ROM (flash is cheap compared to EEPROM), but only the top 20k is actually decoded. Likewise with the RAM, only 40k of the 128k is usable. The 4k in-between AC00-ACFF is for I/O. Address decoding is done by a ATF16V8 programmable logic chip (GAL), and allows the memory map to be changed simply by burning a new GAL.

The firmware is from Daryl Rictor's SBC2 project, with a few tweaks for my memory map. The LCD code is Ben Eater's, though I hope to implement a direct CPU bus connection at somepoint, and maybe have memory mapped text that gets sent during regular interrupts

Code:

1000 - A2 FF 9A A9 FF 8D 02 A0 A9 E0 8D 03 A0 A9 38 20 5D 10 A9 0E 20 5D 10 A9 06 20 5D 10 A9 01 20 5D
1020 - 10 A2 00 BD 30 10 F0 07 20 73 10 E8 4C 23 10 60 48 65 6C 6C 6F 72 6C 64 21 00 48 A9 00 8D 02 A0
1040 - A9 40 8D 01 A0 A9 C0 8D 01 A0 AD 00 A0 29 80 D0 EF A9 40 8D 01 A0 A9 FF 8D 02 A0 68 60 20 3A 10
1060 - 8D 00 A0 A9 00 8D 01 A0 A9 80 8D 01 A0 A9 00 8D 01 A0 60 20 3A 10 8D 00 A0 A9 20 8D 01 A0 A9 A0
1080 - 8D 01 A0 A9 20 8D 01 A0 60

Kaos116's 6502 Homebrew

This is a really tidy homebrew on a single board. At the heart is a WDC 65C02, and it's supported by an AS7C1024 128k SRAM, AT28C256 256k EEPROM, a UM6551 interface adapter, and a GAL20V8 programmable logic array. There are also three expansion ports added in and (I believe) bit-banged serial input/output. All in all a very neat little homebrew! But, can it "Hellorld!"?

Code:

.org $c000
RESET       LDA #$1E                 ;* Init ACIA to 9600 Baud.
                    STA $BF03        ;* Stor in ACIA Control Register
                    LDA #$0B                ;* No Parity.
                    STA $BF02        ;* Stor in ACIA Command Register
                    LDA #<MSG        ;* Get low byte of MSG location
                    STA $2C            ;* Store it for later use
                    LDA #>MSG        ;* Get High byte of MSG location
                    STA $2D            ;* Store it for later use
                    JSR SHWMSG         ;* Show Welcome.
ECHO        AND #$7F                 ;* Change to "standard ASCII"
                    STA $BF00             ;* Send it.
WAIT          LDA $BF01             ;* Load status register for ACIA
                    AND #$10                 ;* Mask bit 4.
                    BEQ WAIT                     ;* ACIA not done yet, wait.
                    RTS                             ;* Done, over and out...
SHWMSG LDY #$0                 ;* Set counter (Y) to zero
PRINT       LDA ($2C),Y             ;* Load character with y offset
                   BEQ DONE             ;* If it's zero we are done
                   JSR ECHO                 ;* Send it out to terminal
                   INY                      ;* Increment Y for next character
                   BNE PRINT         ;* Do it again
DONE       RTS 

MSG         .byte "HELLORLD!",0
NMI:          RTI
IRQ:           RTI
                  .org $FFFA
                  .word NMI
                  .word RESET
                  .word IRQ

Maniek86's 6502

Maniek86 over on the Discord submitted their cool little 6502 homebrew, and it's packing an old-school 6502 at 1MHz, 32 KB of RAM, 2 / 16 KB selectable ROM, an Intel 8255 I/O chip, an integrated keyboard controller, and 3 expansion slots. This computer was mostly made out of scrap salvaged from other broken electronics. The LCD is ST7920 128x64 and is connected to Port A of 8255 via pin header.

Maniek86: "This one was actually challenging to do as I don't usually do a lot of stuff in assembly (I usually go with C or something else). It was a cool small project that helped me learn more about assembly."

Full schematic available here.

The code is quite long, so only an excerpt is included below.

Check out this link for the full code listing.

Code:

...
    LDX #$00            ; RS = 0 (instr)
    LDA #%00001100      ; Display on; cursor off; blink off
    JSR send_byte
    LDA #%00000110      ; Entry mode
    JSR send_byte
    LDA #%00000001      ; Clear display
    JSR send_byte
    ; We are in basic instruction set which is text only, so lets print the "Hellord!"
    LDY #$00            ; String pointer
    @loop:
    LDX #$FF            ; RS = 1 (data)
    TYA                 ; send_byte destroys Y, so we need to save it before loading char
    PHA
    LDA message, Y      ; load char and display it
    JSR send_byte
    PLA                 ; restore Y
    TAY
    LDA message, Y      ; we need to load again char as send_byte destroyed A too
    CMP #$00            ; if end of string, break
    BEQ end
    INY                 ; Increase Y
    JMP @loop
... 

Makarcz's 6502 Kit, MOS-6502 based SBC from eBay (kswichit)

The 6502 Microprocessor Kit is designed for self-learning the low level programming of 6502 CPU. Kit provides 32kB RAM for testing the 6502 instruction directly. The monitor program provides functions for memory examining, user registers for saving CPU status, insert/delete byte, and single step running.

Hardware features:

  • CPU: 6502, 8-bit Microprocessor @1MHz clock
  • Memory: 32kB RAM, 16kB EPROM
  • Decoder chip: GAL16V8 PLD
  • Display: 6-digit 7-segment LED
  • Keyboard: 36 keys
  • RS232 port: 2400 bit/s
  • Debugging LED: 8-bit GPIO1 LED
  • SystemTick: 10ms tick
  • Text LCD interface: direct CPU bus interface text LCD
  • Expansion header: 40-pin header

To see the eBay listing, click here.

More technical details: User's Manual, Hardware schematic, Program examples, please visit https://kswichit.net/6502/6502.html

Code: Github

:180200004C71024D4F532036353032204B69740048656C6C6F726C64CD
:18021800210048AD02902980D0F96860201A028D009060201A028D0169
:180230009060201A02A90120240260A938202402A90C202402203202C4
:18024800A200A000205002608AC900D0089818698020240260C901D086
:1802600008981869C02024026060201A02202B0260203B02A200BD03F7
:1802780002F006206A02E8D0F5A000A201205002A200BD1002F0062001
:070290006A02E8D0F500004E
:05030000203B0200009B
:00000001FF

Makarcz's, modern KIM-1 replica

Check out the seller's page and also KIM-1 and KIM clones manuals/resources, including PAL-1.

Code: Github

MOS hex dump:

;1802004CB202F6F9B8B8BFD0F9B8B8BFD0B8B8B8BFD0B8DEB8BFD01194
;180218B8DE00BFD0B8DE00F3D0B8DE00F3F7B8DE00F3F7B8DE00F31039
;180230F7B8C000F3F7B8C086F3F7B8C08600F7B8C0860000B8C0860F7C
;180248000000C086000000008600000000F600000000F6F90000000513
;180260F6F9B80000F6F9B8B800F6F9B8B8BFAA090B0D0F111300040BA0
;180278FF8A489848AE7702A0FF88D0FDCAF002D0F668A868AA60A20F04
;18029000AC76028E4017BD70028D4217B903028D4017A9018D7702081A
;1802A8207902C8E8E006D0E660A97F8D4117A9008D7602A9308D780BA2
;1802C002208F02CE7802D0F8EE7602EE7602EE7602EE7602EE76020B9B
;1002D8EE7602AE7602BD0302C9AAF0D238B0D40929
;00

MKHBC-8-R2, MOS 6502 based system

This is a generic purpose MOS 6502 based homebrew micro designed and built by Makarcz. The system's name acronym stands for "MK's Homebrew Computer - 8 bit - Revision 2". The system is intended as a hobbyist computing / microcontroller expandable platform. The CPU of choice is MOS 6502 compatible microprocessor. The design is a passive backplane multiboard computer. Backplane consist of 2 buses:

  • Non-buffered 3-slot CPU bus with all signals exposed for CPU, RAM and graphics cards.
  • Buffered 4-slot I/O expansion bus for other peripherals.

Console I/O is implemented over a serial port / UART (9600 baud) and a custom homebrew character terminal device (PropTermMK) built around Parallax Propeller microcontroller with added mass storage on a SD card. File I/O is impelemented over the same serial port communication channel as console I/O with a custom protocol called SDSAP - SD (card) Serial Access Protocol. It is slow, but it works and there was no need to implement a fully blown file system in MOS 6502 assembly (something that the author didn't find as a fun activity at the time, he preferred messing up with the SPIN code on the Propeller instead) - Propeller based PropTermMK device takes care of the file storage in its own firmware. System boots to a rudimentary operating system, which is a simple command processor / monitor kind of program. It consists of two parts:

  1. A firmware, written fully in MOS 6502 assembly language, which consists of a command interpreter, monitor program, low level real-time clock driver, bootstrap sequence, memory check / banked RAM detection, serial port / UART driver, interrupt service code, file I/O (requires PropTermMK) and a jump table,
  2. A ROM library, written in C (CC65 compiler) selection of system functions for date/time setup and presentation, memory dump, binary file loader, string I/O, memory copying / initialization and 16-bit multiplication. These functions are accessed from the calling code in a similar fashion as implemented in CP/M OS - user sets up a number of system function to be called and its parameters in the shared memory section, then there is a single (always the same) entry point / address to call to execute that function.

Other features (as of today - 11/22/2023):

  • Real Time Clock with non-volatile battery backed SRAM for BIOS settings (DS1685).
  • Banked RAM (128 kB: 16 kB x 8).

Memory Map.

  • $0000 - $7FFF: Base RAM, 32 kB.
  • $6000 - $7FFF: Optional Video RAM, 8 kB (shared with the base RAM space).
  • $8000 - $BFFF: Banked RAM, 16 kB space x 8 banks = 128 kB.
  • $C000 - $C7FF: I/O space, 8 slots x 256 Bytes = 2 kB.
  • $C800 - $FFFF: EPROM, 14 kB.

In the works (as of 11/22/2023):

  • Parallel I/O card - testing a prototype on the breadboard.
  • GPU card - design phase.
  • New mobo - being assembled using point-to-point soldering technique.

Plans (as of 11/22/2023):

  • Add sound.
  • Add more proper file I/O and direct access to a mass storage device.

Code (hellorld):

8000 : A9 0C 85 E0 A9 80 85 E1 20 F6 FF 60 48 65 6C 6C
8010 : 6F 72 6C 64 21 0D 0A 00 00 00 00 00 00

Full system design and code on github. (note - as of 11/22/2023, the code published on github is not up to date with above description - there is no file I/O / SDSAP code published, author plans to do it very soon, holding off updates due to some recent design changes coming to the system)

Full view of the system. Populated backplane view. The making of the "hellorld" program on MKHBC-8-R2.

Check out the running of hellorld program on MKHBC-8-R2 on Youtube.

MSpeculatrix's Zolatron64

The Zolatron64, designed and built by the very capable MSpeculatrix, is easily one of the most beautiful homebrews I've seen yet. But it's no slouch from a hardware perspective either. Here's a breakdown of each card:

  • CPU board: 65C02 processor; AS6C62256 32KB RAM chip; AT28C256 EEPROM (32KB in use); 1MHz oscillator; reset button
  • GPIO board: 65C22S VIA, providing 16 general-purpose I/O (GPIO) connections, timers and more
  • Serial board: 6551 ACIA to provide a serial connection which is used as main I/O
  • Dual UART board: NXP SC28L92 chip to provide two UARTs for serial applications (replaced by the Serial board)
  • Raspberry Pi board: Raspberry Pi Zero 2W which provides a serial console and mass storage
  • Parallel printer board: 65C22 VIA providing a Centronics compatible 25-pin connector for hooking up to a dot matrix printer
  • Extended memory board: 128KB SRAM chip, available to the computer as 16 8KB banks.

That's all well and good, but can it Hellorld? You bet it can!

Here's the code using a command to directly poke bytes and get it printing!

! 2000 A2 00 BD 11 20 F0 07 20 1E FF E8 4C 02 20 4C 0E
! 2010 20 48 45 4C 4C 4F 52 4C 44 21 10 00
JMP 2000

Or, check the full assembly code here!

Check out this website for more information on the Zolatron64!

Steckschwein

The Steckschwein is a 65C02 based homebrew computer. It's design goal was to build an 8bit computer that could have existed back in the 80s oder 90s, using (mostly) period correct chips. It's operating system steckOS is also homebrew and among EhBasic, TaliForth2 and lots of other stuff, it of course runs Hellorld!, too! The screenshot is taken from the Steckschwein emulator.

.include "steckos.inc" ; system includes 

appstart $1000         ; set the load address, this will go into the first 2 bytes
                       ; of an commodore style PRG file

.code                  ; begin of code segment
    ldx #0
loop:
    lda hellorld,x 
    beq exit
    jsr krn_chrout     ; output character via steckOS. Everything beginning with krn_ is in the kernel jumptable 
    inx 
    bne loop

exit:
    jmp (retvec)       ; jump to return vector to get back into the shell
.data                  ; begin of data segment, page aligned, hence the rather big binary
hellorld:   .asciiz "Hellorld!"

steckschwein_hellorld sbc_0 6