Ideas for "Romless" 6502 using PIC16?
Ideas for "Romless" 6502 using PIC16?
Hey everyone!
Just seeing if I could get some direction and/or advice. Lately I've been fascinated with the PIC16's and particularly I chose to start playing with a whopper, the PIC16F887 in the DIP40 package. The main reason why is for it to replace the ROM on my next 6502 design, but then it can double as my I/O device for keyboard/audio/SDcard.
Attached is a proto-schematic of what I'm thinking so far. Essentially the PIC is attached to the data bus through a '245, selected through a '138 (or a CPLD, etc). Here it should be selected when the 6502 is looking for a reset vector, but there are other configurations possible such as DMA in conjunction with the BE/RDY line, etc. After bootloading, the PIC16 could send interrupts on a timer or when keyboard/SDcard data is ready, giving the PIC16 plenty of time to set up the data bus while leaving the 6502 to do none of the hard lifting. It wouldn't be as fast as interfacing with a VIA, but most of the internal programming of the PIC16 would optimize what data does need to be transferred.
Any ideas on what might work best? Any links from previous builds? I'm open to suggestions of any kind!
Thanks guys.
Chad
EDIT: Added Black and White version of the picture. Sorry BDD!
Just seeing if I could get some direction and/or advice. Lately I've been fascinated with the PIC16's and particularly I chose to start playing with a whopper, the PIC16F887 in the DIP40 package. The main reason why is for it to replace the ROM on my next 6502 design, but then it can double as my I/O device for keyboard/audio/SDcard.
Attached is a proto-schematic of what I'm thinking so far. Essentially the PIC is attached to the data bus through a '245, selected through a '138 (or a CPLD, etc). Here it should be selected when the 6502 is looking for a reset vector, but there are other configurations possible such as DMA in conjunction with the BE/RDY line, etc. After bootloading, the PIC16 could send interrupts on a timer or when keyboard/SDcard data is ready, giving the PIC16 plenty of time to set up the data bus while leaving the 6502 to do none of the hard lifting. It wouldn't be as fast as interfacing with a VIA, but most of the internal programming of the PIC16 would optimize what data does need to be transferred.
Any ideas on what might work best? Any links from previous builds? I'm open to suggestions of any kind!
Thanks guys.
Chad
EDIT: Added Black and White version of the picture. Sorry BDD!
Last edited by sburrow on Fri Oct 27, 2023 10:13 am, edited 1 time in total.
Re: Ideas for "Romless" 6502 using PIC16?
sburrow wrote:
Hey everyone!
Just seeing if I could get some direction and/or advice. Lately I've been fascinated with the PIC16's and particularly I chose to start playing with a whopper, the PIC16F887 in the DIP40 package. The main reason why is for it to replace the ROM on my next 6502 design, but then it can double as my I/O device for keyboard/audio/SDcard.
Just seeing if I could get some direction and/or advice. Lately I've been fascinated with the PIC16's and particularly I chose to start playing with a whopper, the PIC16F887 in the DIP40 package. The main reason why is for it to replace the ROM on my next 6502 design, but then it can double as my I/O device for keyboard/audio/SDcard.
However in my case, the µC isn't acting as a ROM as such - it's not fast enough to keep up with the 65xx @ 16Mhz so I do it differently. (Although I did consider having the µC clock the 65xx at one point)
But I don't see any reason your way shouldn't work if the PIC can sample the ROM select signals (A13:15] and respond fast enough. (I know very little about PICs - like their max. clock speed?)
Ah - just done a quick search - 32Mhz - might be fast enough for a 6502 at 8Mhz... Hard to know though.
Is the buffer needed? Can't you tri-state the pins on the PIC?
Could the PIC generate the /PIC116F signal to save an IC?
In Ruby, I also connect A8:15 to the µC too. A0:7 are pulled high - that way the µC can access the top 256 bytes of RAM in a mutually exclusive way and communication is via the Rdy signal (65xx executes WAI)
In my original 6502 board I used a GAL to soak-up the glue TTL - R/W qualification, address decode for a VIA, etc.
There is latency in the way I do it though - the ATmega needs time to switch the buses over - tristate/release, etc. PIC might be faster. I do get about 33KB/sec transfer over the interface though which is fast enough.
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Ideas for "Romless" 6502 using PIC16?
Not a hundred miles away from my STM thoughts here: viewtopic.php?f=4&t=7711 (I have the board downstairs but I haven't got around to building it or writing any software yet) though in that case I am doing only the initial program load - any size that fits in the STM's flash - by faking the data that the 6502 sees during boot, and using the STM as an SPI serial port thereafter.
The STM is reasonably nifty when it comes to changing port directions but disappointingly slow at responding to interrupts (so you couldn't use it as a standalone peripheral or memory where you needed it to do something on e.g. a chip select _unless_ you also use it to control the 6502's clock).
Neil
The STM is reasonably nifty when it comes to changing port directions but disappointingly slow at responding to interrupts (so you couldn't use it as a standalone peripheral or memory where you needed it to do something on e.g. a chip select _unless_ you also use it to control the 6502's clock).
Neil
Re: Ideas for "Romless" 6502 using PIC16?
drogon wrote:
But I don't see any reason your way shouldn't work if the PIC can sample the ROM select signals (A13:15] and respond fast enough.
drogon wrote:
There is latency in the way I do it though - the ATmega needs time to switch the buses over - tristate/release, etc. PIC might be faster. I do get about 33KB/sec transfer over the interface though which is fast enough.
barnacle wrote:
The STM is reasonably nifty when it comes to changing port directions but disappointingly slow at responding to interrupts
Things to think about, thank you!
Chad
Re: Ideas for "Romless" 6502 using PIC16?
sburrow wrote:
drogon wrote:
But I don't see any reason your way shouldn't work if the PIC can sample the ROM select signals (A13:15] and respond fast enough.
To get the µC to act as a slow VIA - clock-stretching? Or again flipping the clock switch... It all starts to get a bit messy though...
Quote:
drogon wrote:
There is latency in the way I do it though - the ATmega needs time to switch the buses over - tristate/release, etc. PIC might be faster. I do get about 33KB/sec transfer over the interface though which is fast enough.
barnacle wrote:
The STM is reasonably nifty when it comes to changing port directions but disappointingly slow at responding to interrupts
Things to think about, thank you!
Chad
Actually a single chip CPLD solution that did UART, SPI and VIA - although it doesn't really need to do full VIA, just 2 x 8-bit ports with handshaking and separate timers, so separate blocks inside the same chip...
Other things in a similar light to this include the PiTubeDirect project - this connects a Raspberry Pi directly to the bus on a BBC Micro at 2Mhz. a 1GHz Pi can emulate the FIFOs used in the original Acorn Tube interface but AIUI the code is tight and almost on the limits. (There are architectural issues with very high speed/precise timings on the Pi - nothing really to do with it's CPU clock though).
The other projects are using the RP2040 µC. It's better suited for this - as it's used in the Neo6502 and Pico6502 projects - the RP2040 emulates RAM and I'm not sure what else, but it's probably able to emulate a VIA, ACIA, etc. if someone writes the code.
But is that getting a bit far away from the goal? It's a tricky one to know or judge. In my Ruby project in the ATmega there is about 8000 lines of *.c and *.h files plus the FAT32 library plus my own real-time bare-metal OS/Harness that I run everything under... But what would the equivalent be in (say) VHDL to describe a VIA or ACIA? Or is it not even worth drawing those sorts of parallels ...
... although I do look back at some other "period" systems - the Apple II being the most successful - and it moved from a raft of TTL to VLSI chips, combining more and more functionality into custom ICs from '77 to about '85... Even up to '91 with the whole of an Apple IIe on a single plug-in card for the Macintoshes of that time... And today I get cycle-accurate Apple II and BBC Micro emulators in my web browser... Are we just progressing on from that?
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Ideas for "Romless" 6502 using PIC16?
If I recall correctly, the RP2040 has a couple of clever-bugger digital interfaces that take a lot of load off an emulator.
AVR has some very fast interrupts on even some older models: I could accurately generate PAL video using the internal timing, with no glitches or jitter. But it required it to be asleep and responding to a timer interrupt to have determinative interrupt response times, though. Which meant that I had a program which apart from half a microsecond or so when it went to sleep at the end of each line, ran entirely as an interrupt routine...
I think we have a number of things to consider: are we using an attached microcontroller as
Neil
AVR has some very fast interrupts on even some older models: I could accurately generate PAL video using the internal timing, with no glitches or jitter. But it required it to be asleep and responding to a timer interrupt to have determinative interrupt response times, though. Which meant that I had a program which apart from half a microsecond or so when it went to sleep at the end of each line, ran entirely as an interrupt routine...
I think we have a number of things to consider: are we using an attached microcontroller as
- a generic I/O device
- a storage device
- a boot controller
- generic memory
Neil
Re: Ideas for "Romless" 6502 using PIC16?
barnacle wrote:
If I recall correctly, the RP2040 has a couple of clever-bugger digital interfaces that take a lot of load off an emulator.
Quote:
AVR has some very fast interrupts on even some older models: I could accurately generate PAL video using the internal timing, with no glitches or jitter. But it required it to be asleep and responding to a timer interrupt to have determinative interrupt response times, though. Which meant that I had a program which apart from half a microsecond or so when it went to sleep at the end of each line, ran entirely as an interrupt routine...
This:
https://www.youtube.com/watch?v=09zhGUbVxdU
is running entirely on the ATmega. My plan was to use the ATmega as a video peripheral from the 6502, but when I tested it, it really wasn't fast enough for a good experience.
Quote:
I think we have a number of things to consider: are we using an attached microcontroller as
Neil
- a generic I/O device
- a storage device
- a boot controller
- generic memory
Neil
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Ideas for "Romless" 6502 using PIC16?
drogon wrote:
Can a CPLD emulate a VIA and an ACIA/UART? I've not really looked at them past the old GALs, although I have been dabbling with an FPGA which would be a billion times more capable but the complexity?
Actually a single chip CPLD solution that did UART, SPI and VIA - although it doesn't really need to do full VIA, just 2 x 8-bit ports with handshaking and separate timers, so separate blocks inside the same chip...
-Gordon
Actually a single chip CPLD solution that did UART, SPI and VIA - although it doesn't really need to do full VIA, just 2 x 8-bit ports with handshaking and separate timers, so separate blocks inside the same chip...
-Gordon
Bill
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Ideas for "Romless" 6502 using PIC16?
drogon wrote:
In the "romless" threads here I did consider a system, but never got round to even posting it let alone testing it - that was to have a switch on the clock, so that one way clock pulses came from the oscillator and the other way it could be "hand-cranked" from the µC. So the µC gets the clock, resets the 6502, then because we know the exact number of clock pulses that the '02 need during reset, vector fetch and so on, we can hand-crank the 6502 and feed it data as required, so after its done the JMP (resetV) we feed it instructions in the order LDA #xx ; STA $yyyy to get it to fill RAM with the boot code then a final JMP to the start and switch the clock over. You need to pay attention to R/W and so on, but that's do-able.
PIC16 is not particularly fast, despite all the boasting Microchip used to do about it. Topping out at 20MHz, it does a little under 5 MIPS, which is approximately equal to 2.5MIPS of a 65c02 since the 65c02 has a much richer instruction set and can do the job with half as many instructions. The difference is more severe with interrupts; and to do the equivalent of the 65c02's 4- or 5-clock LDA address,X takes the PIC16 48 clocks.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Ideas for "Romless" 6502 using PIC16?
GARTHWILSON wrote:
That's more or less what I did, which is described in the topic at viewtopic.php?p=91876#p91876 . It's completed and tested, but unfortunately the main computer project I plan to put it in has been on the back burner for a while.
PIC16 is not particularly fast, despite all the boasting Microchip used to do about it. Topping out at 20MHz, it does a little under 5 MIPS, which is approximately equal to 2.5MIPS of a 65c02 since the 65c02 has a much richer instruction set and can do the job with half as many instructions. The difference is more severe with interrupts; and to do the equivalent of the 65c02's 4- or 5-clock LDA address,X takes the PIC16 48 clocks.
PIC16 is not particularly fast, despite all the boasting Microchip used to do about it. Topping out at 20MHz, it does a little under 5 MIPS, which is approximately equal to 2.5MIPS of a 65c02 since the 65c02 has a much richer instruction set and can do the job with half as many instructions. The difference is more severe with interrupts; and to do the equivalent of the 65c02's 4- or 5-clock LDA address,X takes the PIC16 48 clocks.
Thank you all for the input!
Chad
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Ideas for "Romless" 6502 using PIC16?
sburrow wrote:
But I'm guessing you are not wanting to use it as an I/O device past the bootloader stage?
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Ideas for "Romless" 6502 using PIC16?
GARTHWILSON wrote:
sburrow wrote:
But I'm guessing you are not wanting to use it as an I/O device past the bootloader stage?
But another secondary concern (and going off topic a bit) is running the VIA at high speeds. Not to give away all my plans, but I'm not seeing a great deal of viability with the 65816 + VIA. Correct me if I'm wrong, but the addresses and CS lines must be set by the time PHI2 rises. On the 6502, that's no problem because it drives all of the addresses during PHI2-low also. But on the 65816, it drives the lower addresses, but those higher addresses are not yet available until PHI2 rises. If I were using an external 74HC138 or some such to select the VIA, I can see where it would lead to problems. The only option would be to adjust the rising edge of the clock on the VIA to come after PHI2 has already risen, but at higher speeds it's not as easy to divide the speed down for those type of logic situations. If you know more about it than me, I'm all ears. It would certainly be faster than the PIC. Maybe I could use them together somehow, or connect the PIC to the VIA through serial connection or something.
Thank you Garth.
Chad
Re: Ideas for "Romless" 6502 using PIC16?
sburrow wrote:
One of the reasons why I'm wanting to use the PIC as an I/O device (despite it's speed) is because it has a great number of pins, is programmable, and as we know I/O does not need to be accessed all the time like RAM or ROM. What I'm planning on doing is when the PIC is accessed (kind of like a VIA would), I'll have some logic to set RDY low until the PIC has time to respond, put what info it needs on the data bus, then bring RDY back high. Not ideal, but the payoff seems great.
The 65xx sets the Rdy low by executing a WAI instruction and the ATmega kick-starts it again by sending it an interrupt. It's as simple as that. (ish).
So for the most part, the ATmega sits in the loop polling the Rdy input and when it goes low, it pulls BE low then can attach itself to the RAM, read the RAM for a command/data, do what it needs to do, write data back to the RAM, then release BE and send an interrupt.
Normally the ATmega doesn't restart the 65xx until it's done, but I buffer up serial data on the 65xx side, so it sends a buffer when the buffer is full, a "flush" command, or it requests input - then it sends all the data at once to the ATmega, then once the ATmega has copied it and fed it into the interrupt-driven serial output, it lets the 6502 go again.
I have thought about overlapping other operations, (e.g. filesystem) but I don't feel it's worth it.
Quote:
But another secondary concern (and going off topic a bit) is running the VIA at high speeds. Not to give away all my plans, but I'm not seeing a great deal of viability with the 65816 + VIA. Correct me if I'm wrong, but the addresses and CS lines must be set by the time PHI2 rises. On the 6502, that's no problem because it drives all of the addresses during PHI2-low also. But on the 65816, it drives the lower addresses, but those higher addresses are not yet available until PHI2 rises. If I were using an external 74HC138 or some such to select the VIA, I can see where it would lead to problems. The only option would be to adjust the rising edge of the clock on the VIA to come after PHI2 has already risen, but at higher speeds it's not as easy to divide the speed down for those type of logic situations. If you know more about it than me, I'm all ears. It would certainly be faster than the PIC. Maybe I could use them together somehow, or connect the PIC to the VIA through serial connection or something.
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Re: Ideas for "Romless" 6502 using PIC16?
drogon wrote:
The 65xx sets the Rdy low by executing a WAI instruction and the ATmega kick-starts it again by sending it an interrupt. It's as simple as that. (ish).
So for the most part, the ATmega sits in the loop polling the Rdy input and when it goes low, it pulls BE low then can attach itself to the RAM, read the RAM for a command/data, do what it needs to do, write data back to the RAM, then release BE and send an interrupt.
-Gordon
Chad
Re: Ideas for "Romless" 6502 using PIC16?
sburrow wrote:
drogon wrote:
The 65xx sets the Rdy low by executing a WAI instruction and the ATmega kick-starts it again by sending it an interrupt. It's as simple as that. (ish).
So for the most part, the ATmega sits in the loop polling the Rdy input and when it goes low, it pulls BE low then can attach itself to the RAM, read the RAM for a command/data, do what it needs to do, write data back to the RAM, then release BE and send an interrupt.
-Gordon
Chad
There are "stubs" in the OS to handle files, etc. so applications call the relevant things in the OS and off it goes.
Also, when running BCPL on the '816, the ATmega also acts as a floating point co-processor... You put 2 numbers plus the op-code into the memory at $FF00, do the WAI thing, and when you return the result is in $FF00 and off you go...
Basically, there is a list of codes that the 65xx uses to communicate to the ATmega.
There is latency as the Atmega needs to switch ports to input or output mode from tristate, pull BE low, output the address + r/w to the RAM to get the data from it, do the thing, write the data back, then tristate its lines and let the 65xx run. The 128 byte 'window' is because the hardware and software vectors in the top of $FFxx, so there is a 128 byte window and 4 bytes for commands and return codes. I could probably reduce latency if I coded it all in avr assembler, but C is good enough.
-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/