Software Transparent 6551/6850 UART Replacement
Software Transparent 6551/6850 UART Replacement
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
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
Last edited by jmp(FFFA) on Sat Nov 14, 2015 4:17 pm, edited 1 time in total.
Re: Software Transparent 6551/6850 UART Replacement
(That chapter 13 as a pdf - see p31)
Any chance you can use RDY to make the device a one-wait-state access?
Any chance you can use RDY to make the device a one-wait-state access?
Re: Software Transparent 6551/6850 UART Replacement
BigEd wrote:
Any chance you can use RDY to make the device a one-wait-state access?
I'll also dig through some Microchip datasheets to see if any PICs with the PMP peripheral have faster timings. Pity I can't do that with their handy selection tool: http://www.microchip.com/maps/Microcontroller.aspx
Re: Software Transparent 6551/6850 UART Replacement
For anyone who has implemented wait state logic on the 65c02 before, is this a reasonable way to generate a 1-cycle wait state on the 65c02? I don't have much room left on my breadboard and would like to keep the gate count as low as is practicable.
The "rdy" logic output will be open drain in order to drive the 65c02 RDY line.
The circuit described by the Verilog code below should be adequately approximated with a 74HC74, and a 74HC03 with suitable pull-ups depending on the clock frequency being used. I have half a 74HC74 already available, so I would just need to add the 74HC03 to complete the circuit below.
Here is the schematic I was trying to describe in Verilog above:
It doesn't work because cs_uart is never de-asserted while RDY is low. I'm going to need another flip flop to make it work, or maybe a counter. Very little room left on the breadboard at the moment, but hopefully I'll figure something out that will avoid any major rearranging of parts.
The "rdy" logic output will be open drain in order to drive the 65c02 RDY line.
The circuit described by the Verilog code below should be adequately approximated with a 74HC74, and a 74HC03 with suitable pull-ups depending on the clock frequency being used. I have half a 74HC74 already available, so I would just need to add the 74HC03 to complete the circuit below.
Code: Select all
module RDYCTRL(
input clk, // PHI2
input csn_uart, // UART CS (negative logic)
output reg rdy // to 65c02 rdy line via open drain gate
);
// start wait state if 65c02 is running and cs_uart is asserted (goes low)
wire startn = ~rdy | csn_uart;
// set FF output (rdy) low when startn goes low (asynchronous)
// restore rdy on next positive edge of PHI2
always @(posedge clk or negedge startn) begin
if (startn == 1'b0)
rdy <= 1'b0;
else
rdy <= 1'b1;
end
endmodule
It doesn't work because cs_uart is never de-asserted while RDY is low. I'm going to need another flip flop to make it work, or maybe a counter. Very little room left on the breadboard at the moment, but hopefully I'll figure something out that will avoid any major rearranging of parts.
Re: Software Transparent 6551/6850 UART Replacement
OK, a little further thought and I came up with this circuit to generate a 1-wait-state delay when CS is asserted on a slow device:
There are probably more clever ways to do it as well, probably using a counter instead of the second FF which would have the added benefit of allowing you to select more than one wait state. Since I only need one at the moment, this should do. Unfortunately, I need to find room for another HC74 on the breadboard since I need separate asynchronous clears.
There are probably more clever ways to do it as well, probably using a counter instead of the second FF which would have the added benefit of allowing you to select more than one wait state. Since I only need one at the moment, this should do. Unfortunately, I need to find room for another HC74 on the breadboard since I need separate asynchronous clears.
Re: Software Transparent 6551/6850 UART Replacement
Maybe you'll find this useful. Michael collected my circuits for a single wait-state and for dual wait-states here. (Thanks, Michael!)
Note that, for a system running close to specified limits, a single wait-state roughly triples the time available for the slow device (eg EPROM) to respond -- details here.
cheers,
Jeff
Note that, for a system running close to specified limits, a single wait-state roughly triples the time available for the slow device (eg EPROM) to respond -- details here.
cheers,
Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: Software Transparent 6551/6850 UART Replacement
Dr Jefyll wrote:
Maybe you'll find this useful. Michael collected my circuits for a single wait-state and for dual wait-states here. (Thanks, Michael!)
Edit: I see another flaw in my second circuit above that will prevent it from working properly. It will asynchronously lower RDY until the next rising edge of PHI2 which will happen during the same cycle -- not the next cycle as I intended. So I need to modify it again by either adding another FF or replacing the second FF with a counter.
I see that Jeff's circuit is 100% synchronous to the PHI2 clock -- A close examination of the 65c02 timing diagrams suggests that this approach should work fine and will greatly simplify the logic required.
Last edited by jmp(FFFA) on Fri Oct 16, 2015 7:04 pm, edited 1 time in total.
Re: Software Transparent 6551/6850 UART Replacement
The essential innovation I was missing is that the wait state generator can be synchronous with the rising edge of PHI2. Here is Jeff's circuit converted to work with a standard DFF. The JKFF version is still better because the logic paths are shorter, but since I already have 1/2 a spare 74HC74 on the board and a couple of spare NAND gates, this should be equivalent:
Re: Software Transparent 6551/6850 UART Replacement
On a related note: with WDC CPU's the RDY pin is bi-directional, so it may be advisable to include a series resistor when driving RDY from an ordinary gate (ie, a gate with totem-pole outputs rather than open-collector). The resistor is to limit current if the gate tries to drive RDY high while the CPU is driving it low. At the end of my other post I've appended an illustration pertaining to this. Comments and questions belong in that thread, of course, not here.
I'm watching your project with interest, jmp(FFFA)! The PMP (parallel master port) is a cool feature, and what you're doing is a great way to put its capabilities to work.
Slightly OT little-known fact:
the WDC 65c265 microcontroller has a comparable feature which they call the Parallel Interface Bus (PIB). It's a group of interrupt-rigged "mailbox" registers accessible by both the '816 core and by an externally-connected device. (From what little I know about the BBC "Tube" interface, this seems similar.) You could have a host processor with one or more '265s sitting on its bus, each acting independently but under the master's control. Or, let the '265s all be peers.
I'm watching your project with interest, jmp(FFFA)! The PMP (parallel master port) is a cool feature, and what you're doing is a great way to put its capabilities to work.
Slightly OT little-known fact:
the WDC 65c265 microcontroller has a comparable feature which they call the Parallel Interface Bus (PIB). It's a group of interrupt-rigged "mailbox" registers accessible by both the '816 core and by an externally-connected device. (From what little I know about the BBC "Tube" interface, this seems similar.) You could have a host processor with one or more '265s sitting on its bus, each acting independently but under the master's control. Or, let the '265s all be peers.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: Software Transparent 6551/6850 UART Replacement
OK, since I've spent so much time thinking about generating wait states recently, I figured I'd wrap things up with this circuit which will generate anywhere from 1 to 8 wait states depending on how you hook it up:
Thanks to Jeff for putting me on the right track with his two existing wait state circuits.
And Jeff is right that RDY is open-drain on the 65c02 so I would be using a 74HC03 for the inverter between the HC164 A output and the RDY line with a suitable pullup resistor on it (see my earlier circuits for examples). 2.2k is probably reasonable for lower speeds, but 1k or even lower if you're running 10 MHz+. The exact value depends on speed and loading and your best bet is to hook an oscilloscope up and make sure the slew rate is reasonable when RDY is pulled high. I would be uncomfortable just using a serial resistor here unless this was the only circuit connected to the RDY line in which case it should be OK so long as it was large enough to prevent more than a few milliamps through it and small enough to raise the signal quickly after the 65c02 is done holding it low (e.g. after a WAI instruction).
Thanks to Jeff for putting me on the right track with his two existing wait state circuits.
And Jeff is right that RDY is open-drain on the 65c02 so I would be using a 74HC03 for the inverter between the HC164 A output and the RDY line with a suitable pullup resistor on it (see my earlier circuits for examples). 2.2k is probably reasonable for lower speeds, but 1k or even lower if you're running 10 MHz+. The exact value depends on speed and loading and your best bet is to hook an oscilloscope up and make sure the slew rate is reasonable when RDY is pulled high. I would be uncomfortable just using a serial resistor here unless this was the only circuit connected to the RDY line in which case it should be OK so long as it was large enough to prevent more than a few milliamps through it and small enough to raise the signal quickly after the 65c02 is done holding it low (e.g. after a WAI instruction).
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Software Transparent 6551/6850 UART Replacement
jmp(FFFA) wrote:
And Jeff is right that RDY is open-drain on the 65c02 so I would be using a 74HC03 for the inverter between the HC164 A output and the RDY line with a suitable pullup resistor on it (see my earlier circuits for examples). 2.2k is probably reasonable for lower speeds, but 1k or even lower if you're running 10 MHz+. The exact value depends on speed and loading and your best bet is to hook an oscilloscope up and make sure the slew rate is reasonable when RDY is pulled high. I would be uncomfortable just using a serial resistor here unless this was the only circuit connected to the RDY line in which case it should be OK so long as it was large enough to prevent more than a few milliamps through it and small enough to raise the signal quickly after the 65c02 is done holding it low (e.g. after a WAI instruction).
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: Software Transparent 6551/6850 UART Replacement
Dr Jefyll wrote:
I'm watching your project with interest, jmp(FFFA)! The PMP (parallel master port) is a cool feature, and what you're doing is a great way to put its capabilities to work.
Re: Software Transparent 6551/6850 UART Replacement
GARTHWILSON wrote:
Just put a 22pF capacitor across the resistor and you'll be fine for any speed, even with a much higher resistance.
There may be some undesirable effects (e.g. droop) in cases where you are rapidly switching between logic states if your series capacitor holds too much charge, but that just means you'd need to switch to a smaller valued capacitor.
Thanks for pointing this out. I still like the wire-OR arrangement as it's a more general solution, but direct drive via a parallel RC combination is useful especially for those cases where you only have one slow peripheral on your bus.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Software Transparent 6551/6850 UART Replacement
The tiny input capacitance of the RDY input, combined with the resistor by itself, form a pole. Putting the capacitor across the resistor cancels that pole. The two capacitances do form an AC voltage divider, but if the RDY input has 5 or 10pF, the voltage swing will still be enough with the 22pF across the resistor. As long as there's no pull-up or pull-down resistance (and the input DC current is negligible), there will be no overshoot or droop problems. Do a LaPlace transform on it if you like; but an oscilloscope probe will have enough capacitance to change the circuit and misrepresent what's going on there when the probe is not connected.
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?
- BigDumbDinosaur
- Posts: 9427
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Software Transparent 6551/6850 UART Replacement
Another method is to pull RDY up to Vcc through a suitable resistor (I use 3.3K) and isolate it from the controlling gate with a low power Schottky diode (anode toward RDY), such as the attached. The prop time through the diode under forward bias is vanishingly small and it recovers in 10ns or less.
Ironically, this doesn't have to be a really fast circuit, as the raison d'être of negating RDY is to waste some time.
Ironically, this doesn't have to be a really fast circuit, as the raison d'être of negating RDY is to waste some time.
- Attachments
-
- schottky_lo_pwr_sd103a-105077.pdf
- Low Power 10ns Schottky Diode
- (78.31 KiB) Downloaded 211 times
x86? We ain't got no x86. We don't NEED no stinking x86!