I'm starting work on a PIC-based replacement for the 6551 and 6850 UART chips and would like to document the efforts here. An important system design goal is for software transparency -- e.g. applications already written to interface with a 6551 or 6850 should continue to work when connected appropriately to this UART replacement. I've already constructed a 65c02-based test system to for system testing purposes and brought it up with a real 68B50 documented in another thread in this section.
I've selected the PIC24FJ32GA102 for the project. It is an inexpensive 16-bit MCU capable of up to 16 MIPS speed and available in 28-pin narrow DIP form (ideal for breadboards). More importantly, it has what Microchip calls a PMP (parallel master port) interface on it. This hardware peripheral includes functionality that allows it to be directly read from and written to by the 6502 bus (with a tiny amount of logic to convert the RWB signal to RDB and WRB signals) when operated in slave mode (Microchip calls this PSP, or parallel slave port). Of course it also has a fully functional UART (two actually) as well as a large number of other potentially useful hardware peripherals which are outside the scope of this project.
In PSP mode, the PIC24FJ32GA102 can be configured with up to two address lines, in addition to chip select, RDB, and WRB. This allows accessing up to eight registers -- four for reading and four for writing. This is adequate to fully implement the registers used in the 6850 and 6551 UARTs, but not other popular uarts which have additional registers.
In drilling down into the hardware timing details on the PIC24FJ32GA102 for operation, I have come across a timing limitation which concerns me. On page 13-29 of the PIC24F Family Reference Manual (Chapter 13, Parallel Master Port), the worst-case timing for CSB and RDB to data out valid is specified as 80 nS. If I use the usual method of gating the RWB signal with PHI2 to generate the RDB and RWB signals, this constrains the minimum clock period to 2 * (80 nS + Tdsr (15 nS) + Tgpd (15 ns)) which corresponds to an F(max) of only 4.5 MHz. Tdsr is the 65c02 read data setup time, and Tgpd is the worst-case timing delays through the logic that generates the RDB signal. Needless to say this is disappointing, and even reducing Tgpd to zero doesn't help much (F(max) increases to about 5.3 MHz.
It occurs to me that I may be able to use the RWB signal without being gated by the clock for reading. This would change the constraint on the minimum clock period to 80 nS + Tah (10 nS) + Tgpd (5 nS) + Tast (?) which corresponds to an F(max) of something under 10.5 MHz depending on the exact value of Tast. Here Tah is the 6502 address hold time, Tgpd is the gate propagation time for the inverted RWB signal, and Tast is the address stable time (not specified) which is the time required for the address lines to stabilize after PHI2 falls (and after the address hold time Tah). While not great, I can live with this, especially for 3.3 volt operation.
The one problem with the second approach is that it may expose the data bus to contention. This is where I appeal to others experience. What are the downsides associated with the PIC seizing the data buss before PHI2 rises? This would probably only happen at slower clock rates but it is a concern nonetheless. No other peripherals would have their chip select lines asserted at this time, so the only possibility for contention is between the 65c02 and the PIC.
There are also timing constraints on writing to the PIC, but they look easy enough to work around and don't appear tight enough to constrain F(max) further.
Edit: For anyone coming across this thread for the first time, the PIC-UART code is published on Github here:
https://github.com/jason6502/pic-uart