Page 1 of 1

6502 + Raspberry Pi Pico Idea???

Posted: Tue Jul 16, 2024 10:00 pm
by ASPEN32
Hi everyone!

So...I got another beginner's project (maybe a cheater's...) idea I'd like to implement using at most (or as little) as 2 or 3 chips - a 6502 mated with a Raspberry Pi Pico. Here's what I'd like to design...

* A 6502 SBC based around a 6502 CPU and a Pico.
* I would like the Pico to emulate RAM/ROM and VIA/UART through USB serial terminal software like PuTTY. I can supply the logic chips if necessary (74xx series, etc.)
* If necessary, I'd like to have removeable storage via SD card

For starters, I'd like to just see if there is a way I can test communications between the Pico and the 6502 and work up from there. I'm using a Rockwell R65C02 if it makes a difference. Does anyone know where a good place to start with this would be and how I can work up from that? I have experience with Arduinos and other microcontrollers so C is like a second language to me.

Thank you!!!

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Wed Jul 17, 2024 6:48 am
by drogon
ASPEN32 wrote:
Hi everyone!

So...I got another beginner's project (maybe a cheater's...) idea I'd like to implement using at most (or as little) as 2 or 3 chips - a 6502 mated with a Raspberry Pi Pico. Here's what I'd like to design...

* A 6502 SBC based around a 6502 CPU and a Pico.
* I would like the Pico to emulate RAM/ROM and VIA/UART through USB serial terminal software like PuTTY. I can supply the logic chips if necessary (74xx series, etc.)
* If necessary, I'd like to have removeable storage via SD card

For starters, I'd like to just see if there is a way I can test communications between the Pico and the 6502 and work up from there. I'm using a Rockwell R65C02 if it makes a difference. Does anyone know where a good place to start with this would be and how I can work up from that? I have experience with Arduinos and other microcontrollers so C is like a second language to me.

Thank you!!!
There are already several such projects, including at least one commercial one, so there is plenty of existing work you can base your build on. Just search - e.g. pico6502, neo6502 and you'll soon find others.

-Gordon

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Wed Jul 17, 2024 7:34 am
by barnacle
Look for a youtube channel by Rumbledethumps. He appears to have done what you want, at least for a small address range.

I'm still looking at his code to see what I can steal (er, educate myself with!) for my 65c02/pi pico/cfcard project (look in General Discussions) which is still very much in a state of flux - at the moment I have 80x30 text on a VGA generated by the pico, and input from a PS/2 keyboard; next stage is boot-loading the 65c02 from the pico and then two way communication on the 65c02 data bus.

Neil

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Thu Jul 18, 2024 7:31 am
by ojanhk
Hi, if you want some (very) basic code idea, I did something similar with a Teensy a few years ago. It’s not for Pico, but it’s very simple C code anyway. It helped me build my 6502 on a breadboard by adding real parts one after another: I started with the teensy emulating everything but the CPU, then added real RAM and removed disabled RAM emulation, etc, until I removed the Teensy completely.
Code is here: https://github.com/olivierjan/6502-SBC-using-Teensy

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Sat Jul 20, 2024 3:58 pm
by Osric
ASPEN32 wrote:
So...I got another beginner's project (maybe a cheater's...) idea I'd like to implement using at most (or as little) as 2 or 3 chips - a 6502 mated with a Raspberry Pi Pico. Here's what I'd like to design...

* A 6502 SBC based around a 6502 CPU and a Pico.
* I would like the Pico to emulate RAM/ROM and VIA/UART through USB serial terminal software like PuTTY. I can supply the logic chips if necessary (74xx series, etc.)
* If necessary, I'd like to have removeable storage via SD card

For starters, I'd like to just see if there is a way I can test communications between the Pico and the 6502 and work up from there. I'm using a Rockwell R65C02 if it makes a difference. Does anyone know where a good place to start with this would be and how I can work up from that?
I see you have plenty of answers of the form "Google is your friend" but as I started on basically the exact same path as you I thought I could share my experience.

Inspired by Ben Eater's videos (and later disappointed to discover that Garth wasn't credited for the core design ideas) I thought I'd start with a Pico W on a breadboard wired to be a semi-permanent in circuit debugger for the 6502 bus. The Pico W has GP0 - GP15 in order and this makes for very easy setting or inspecting the address bus; like you, I'm most comfortable in C but the micro python environment makes getting in and poking at the device so easy that it was worth learning micropython on the fly to be able to program the computer.

So to get started, I made a file named `bus.py` to make it possible to inspect the bus, and the address code looks like this:

Code: Select all

from machine import mem32, Pin
import time

SIO_BASE = 0xD0000000

GPIO_IN = SIO_BASE + 0x0004

GPIO_OUT = SIO_BASE + 0x010
GPIO_OUT_SET = SIO_BASE + 0x014
GPIO_OUT_CLR = SIO_BASE + 0x018
GPIO_OUT_XOR = SIO_BASE + 0x01C

GPIO_OE = SIO_BASE + 0x020
GPIO_OE_SET = SIO_BASE + 0x024
GPIO_OE_CLR = SIO_BASE + 0x028
GPIO_OE_XOR = SIO_BASE + 0x02C

for n in range(16 + 7):
    p = Pin(n, Pin.IN)
p = Pin(26, Pin.IN)
# address bus as outputs
MASK = 0x7FFFFF | (1 << 26)
DATA_MASK = 0x7F0000 | (1 << 26)
ADDR_MASK = 0x00FFFF


def address(a):
    "Set address lines"
    mem32[GPIO_OUT_CLR] = ADDR_MASK
    mem32[GPIO_OUT_SET] = a
    mem32[GPIO_OE_SET] = ADDR_MASK


def readaddress():
    "Get address lines"
    mem32[GPIO_OE_CLR] = ADDR_MASK
    return mem32[GPIO_IN] & 0xFFFF
So this lets you read the 16 GPIOs that make up the address bus in one shot. The next 8 GPIOs are not sequential, so you have to shift the high bit into place for the data lines (that's why the data mask is defined as 0x7F0000 | (1 << 26)):

Code: Select all

def dataraw(v):
    "Set data with bits positioned with the high bit offset"
    mem32[GPIO_OE_SET] = DATA_MASK
    mem32[GPIO_OUT_CLR] = DATA_MASK
    mem32[GPIO_OUT_SET] = v


def databyte(b):
    "Set data after moving high bit over"
    raw = ((b & 0x7F) << 16) | ((b & 0x80) << (26 - 7))
    dataraw(raw)


def datarawread():
    "Read the raw GPIOs masked for data pins only"
    mem32[GPIO_OE_CLR] = DATA_MASK
    return mem32[GPIO_IN]


def dataread():
    "Read a byte of data from the data bus."
    raw = datarawread()
    value = ((raw >> 16) | (raw & (1 << 26)) >> (26 - 7)) & 0xFF
    return value
Armed with just these two functions you can snoop on the data bus. I don't know if the Rockwell chip you are using will work properly with the clock halted, check your datasheet. The chip I have will patiently await the clock edges and I start with the clock low and wired to GPIO 28.

For better or worse, that accounts for all pins available on the Pico W design. For me, this is an asset that will stop me building too much functionality into the pico itself; it can respond to the bus and deliver "RAM" to the computer, but I'm not even doing that with it anymore. However back at the start, I had just the 6502 on the bus plus the pico, and had the pico serve up small programs on $FF00 by simply embedding and array into the micropython code and returning those values to the bus when the CPU read out of that address range. This enabled wiring up the 6522 VIA and a two line display to see that everything was working, before adding any ROM or RAM to the system.

Code: Select all

cycle = 0
ram = bytearray([0xEA] * 256)

ram[0xFC] = 0x00
ram[0xFD] = 0xFF


def clockmon(_):
    "Put up the monitor output on each rising clock edge"
    global cycle
    rw = Pin(27, Pin.IN).value()
    a = readaddress()
    if a == 0xFFFC:
        cycle = -1
    d = 0
    if rw and (a & 0xFF00) == 0xFF00:
        offset = a & 0xFF
        d = ram[offset]
        databyte(d)
    else:
        d = dataread()
    print(f"{cycle:06d} {a:04x}: {rw:01b}  {d:02x}")
    cycle += 1


pin = Pin(28, Pin.IN, Pin.PULL_DOWN)
pin.irq(trigger=Pin.IRQ_RISING, handler=clockmon)

from hello import code

for i in range(len(code)):
    ram[i] = code[i]
This produces a cycle counter, address, read write flag, and data bus monitor line for each tick of the clock. To change the clock to Pico control (I found early on I preferred to have a debounced button wired to pin 28 rather than software driven clock), you need something like this:

Code: Select all

def step():
  clock = Pin(28, Pin.OUT)
  clock.value(1)
  time.sleep(0.01)
  clock.value(0)
It ought to be possible to use the code as given with the pico wired to the address and data bus, the R/W signal wired to GPIO 27, and the clock wired to the CPU's clock. Hope that's helpful.

Photo

Edit: I forgot to say that the command line I use to get into the REPL is

Code: Select all

mpremote connect /dev/tty.usbmodem1101 mount . run bus.py repl
and this drops you into a python REPL where you can then call the functions above at the >>> prompt.

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Sat Jul 20, 2024 4:57 pm
by BigEd
(welcome Osric, and thanks for helping by sharing details of your project. Please note that attached images are preferred here, compared to linked images. Images are of course very welcome.)

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Sat Jul 20, 2024 6:48 pm
by BigDumbDinosaur
Osric wrote:
...I don't know if the Rockwell chip you are using will work properly with the clock halted, check your datasheet.

All CMOS versions of the 6502 will tolerate the clock being stopped in the high phase, which is a viable method of wait-stating the MPU to accommodate slow devices—my POC V1.3 unit uses this method.  Only static-core versions of the WDC 65C02 (and 65C816) will tolerate the clock being stopped in the low phase.  Note that the S in the current-production W65C02S6TxxG-14 WDC part number means “static core” (the xx field identifies the packaging).

As an aside, the 6T designation in the WDC part number means the core was made from a wafer fabricated with 0.6µ geometry at the TSMC foundry.  As Plasmo discovered with his experiments, the 6T parts can be substantially overclocked—he’s gotten one well past 30 MHz.  Of course, a beginning project won’t be run that fast, but it does give you an idea of how far the 65C02 technology has progressed since the days of the 1 MHz NMOS 6502.

Your best reference for starting from scratch with the 65C02 is Garth’s extensive 6502-oriented website.  Youtube videos can only go so far in passing on knowledge, and sometimes can lead you astray.  Garth’s site goes into considerable detail on the nuances of building a functioning system, as well as writing software to run it.  He also covers many other 6502-related topics that may be of interest.

Lastly, I’d like to caution you to be careful where you buy your parts.  Some eBay sellers are pushing counterfeit 65C02 MPUs, which are often re-marked NMOS parts.  We have a topic here on how to identify a fake part and where to go to purchase genuine WDC productMost eBay sellers are not authorized WDC sources, which means if you purchase from one of them, the odds of getting a bogus part are high.  If you acquire a 65C02 that doesn’t seem to work right and appears to be new, you should suspect that it is a fake.

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Sat Jul 20, 2024 7:35 pm
by Osric
BigDumbDinosaur wrote:
Osric wrote:
...I don't know if the Rockwell chip you are using will work properly with the clock halted, check your datasheet.

All CMOS versions of the 6502 will tolerate the clock being stopped in the high phase, which is a viable method of wait-stating the MPU to accommodate slow devices—my POC V1.3 unit uses this method. 

In this case the OP ought to modify the code to set the clock pin high when bus.py is loaded and change step to step down and back up rather than the way I have it, and it ought to work with the proposed chip.

For myself, the next step is to configure a. pico to drive VGA or monochrome monitors using the PIO capabilities, with the goal of doing DMA out of the RAM chip for the 6502 to create a simple text mode display for the computer. If I have problems I'll post about that in a new thread; I did look at Garth's site but it mainly had pointers to other content for video and I didn't immediately find a model to follow ... I think this is simple enough to do it from first principles (famous last words? we'll see).

P.S. Added an attachment similar to the linked photo; I noticed that img tags were turned off but didn't take the time to think about why that must be, sorry.

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Sat Jul 20, 2024 8:06 pm
by GARTHWILSON
Osric wrote:
In this case the OP ought to modify the code to set the clock pin high when bus.py is loaded and change step to step down and back up rather than the way I have it, and it ought to work with the proposed chip.
<snip>
I did look at Garth's site but it mainly had pointers to other content for video and I didn't immediately find a model to follow
The third-to-last diagram on the clock-generation page at http://wilsonminesco.com/6502primer/ClkGen.html and the description in the paragraph above it might be what you're looking for.

Re: 6502 + Raspberry Pi Pico Idea???

Posted: Sat Jul 20, 2024 8:10 pm
by BigEd
Thanks for adding the photo attachment! (I think IMG tags are off to encourage attachments - too many old threads are devalued because image hosting sites have died, or links have died.)