It's not really practical to attach a UART as complex as the 28L92 to NMI, as there are multiple interrupt sources and it would quickly become a programming nightmare to avoid a deadlock problem caused by a missed interrupt.
TTL 6502 Here I come
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: TTL 6502 Here I come
GARTHWILSON wrote:
Drass wrote:
I think I recall seeing a 100Hz IRQ in your POC 1 design, which is a nice round number. (I should check what tasks you assigned to the the "Jiffy" IRQ there).
It's not really practical to attach a UART as complex as the 28L92 to NMI, as there are multiple interrupt sources and it would quickly become a programming nightmare to avoid a deadlock problem caused by a missed interrupt.
x86? We ain't got no x86. We don't NEED no stinking x86!
-
White Flame
- Posts: 704
- Joined: 24 Jul 2012
Re: TTL 6502 Here I come
BigDumbDinosaur wrote:
In the C-64, timer A in CIA number 1 generated the jiffy IRQ. As the timer rate is ultimately slaved to the Ø2 clock rate, Commodore used a Ø2 rate in the C-64 that was evenly divisible by 60 or 50 so the IRQ would maintain reasonably accurate timekeeping
Both NTSC and PAL C64s had their CIA jiffy timer set for 60Hz, though. Looking at the ROM sources, on PAL it loads up the timer with $4025, and NTSC gets $4295. PAL ends up with 59.999269228 Hz, and NTSC with 60.001760047 Hz, with these numbers.
But in any case, yeah it was useless for exact timing because things would SEI, and the numbers aren't exactly right to begin with.
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: TTL 6502 Here I come
White Flame wrote:
BigDumbDinosaur wrote:
In the C-64, timer A in CIA number 1 generated the jiffy IRQ. As the timer rate is ultimately slaved to the Ø2 clock rate, Commodore used a Ø2 rate in the C-64 that was evenly divisible by 60 or 50 so the IRQ would maintain reasonably accurate timekeeping
Quote:
But in any case, yeah it was useless for exact timing because things would SEI, and the numbers aren't exactly right to begin with.
Of course, what would a 65xx peripheral device be without one or two hardware bugs?
There was also a nasty bug involving the timer B interrupt, which was behind a lot of the fake RS-232 errors that these computers experienced. If the CIA's interrupt status register was read one or two clock cycles before timer B was to underflow and interrupt, that IRQ might not ever come. Since CIA #2's timer B was the baud rate generator for the fake RS-232 receiver, the result of this little contretemps was usually a whole bunch of dropped bits and major corruption. It was a horrid mess.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: TTL 6502 Here I come
BigDumbDinosaur wrote:
It was possible to configure the C-64's VIC to generate a raster interrupt, but that feature was mostly used to produce the illusion of more sprites on the screen or to toggle the VIC between bitmap and text mode when the scan reached a certain raster line.
C74-6502 Website: https://c74project.com
Re: TTL 6502 Here I come
Quote:
In the C-64, timer A in CIA number 1 generated the jiffy IRQ. As the timer rate is ultimately slaved to the Ø2 clock rate, Commodore used a Ø2 rate in the C-64 that was almost evenly divisible by 60 or 50 so the IRQ would maintain reasonably accurate timekeeping
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: TTL 6502 Here I come
Rob Finch wrote:
The C64 had the time-of-day signal on the CIA driven by the AC power at 50 or 60Hz. It's strange they didn't use that for timing.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: TTL 6502 Here I come
Now I'm confused ...
As I understood it, the WDC65C02 fixes the spurious reads which afflict the NMOS 6502 during dead bus cycles. Specifically for indexed addressing, it does so by re-reading the last instruction byte rather than the "partial" target address. But, to my surprise, single-cycling the SBC shows the processor puts $8000 on the address bus in the cycle preceding the write when executing this:
LDY #0
STA $8000,Y
Did I make a mistake or does the 'C02 generate spurious reads during indexed store operations?
I ran into this issue when tracking down the source of some "flakiness" in the interaction with the NXP UART. The device has one of those I/O registers where otherwise harmless reads have specific side-effects. Of course, I happened to be using indexed addressing to configure the UART and I was seeing all sorts of seemingly unpredictable behavior; behaviour which in fact could be explained by a spurious read moving the goal posts on the configuration writes. More investigation confirmed the UART registers were not set up correctly, and after confirming with the single-cycle clock, a change to absolute addressing fixed everything!
. The UART is now solid (albeit with minimal testing at this point). Good news for the SBC, but it certainly left me wondering about those spurious reads.
Anyway, I really enjoyed working with the UART once out of that config quagmire. The interrupt mechanism is very well behaved, and I was able to get service routines working fairly quickly (using a buffering scheme I adapted from BDD's POC1 firmware - very nicely done BDD, thank you). I ended up with a little BIOS with the following functions (the C-like syntax below is for documentation only. Function arguments are actually passed in registers):
reset_io
chn = open(device, port)
close(chn)
byte = getc(chn)
putc(chn, byte)
It's a start, and I suspect I'll end up using and extending it further later. As it stands, the scheme handles interrupt driven I/O from concurrent channels and can be easily extended to multiple devices. Be that as it may, the main event is that the UART is now fully functional and reliable. Very happy with that.
The next step for the SBC is to get a simple file upload going to load software into RAM. At that point, the SBC will have met it's primary objective of being a test platform for the TTL CPU (and thanks to dr Jefyll's good suggestion, a terrific learning experience as well). I'll have a little cleaning up to do (e.g., missing LEDs, etc.) and then it will be time to order the boards for the TTL CPU itself!
Can't wait!
As I understood it, the WDC65C02 fixes the spurious reads which afflict the NMOS 6502 during dead bus cycles. Specifically for indexed addressing, it does so by re-reading the last instruction byte rather than the "partial" target address. But, to my surprise, single-cycling the SBC shows the processor puts $8000 on the address bus in the cycle preceding the write when executing this:
LDY #0
STA $8000,Y
Did I make a mistake or does the 'C02 generate spurious reads during indexed store operations?
I ran into this issue when tracking down the source of some "flakiness" in the interaction with the NXP UART. The device has one of those I/O registers where otherwise harmless reads have specific side-effects. Of course, I happened to be using indexed addressing to configure the UART and I was seeing all sorts of seemingly unpredictable behavior; behaviour which in fact could be explained by a spurious read moving the goal posts on the configuration writes. More investigation confirmed the UART registers were not set up correctly, and after confirming with the single-cycle clock, a change to absolute addressing fixed everything!
Anyway, I really enjoyed working with the UART once out of that config quagmire. The interrupt mechanism is very well behaved, and I was able to get service routines working fairly quickly (using a buffering scheme I adapted from BDD's POC1 firmware - very nicely done BDD, thank you). I ended up with a little BIOS with the following functions (the C-like syntax below is for documentation only. Function arguments are actually passed in registers):
reset_io
chn = open(device, port)
close(chn)
byte = getc(chn)
putc(chn, byte)
It's a start, and I suspect I'll end up using and extending it further later. As it stands, the scheme handles interrupt driven I/O from concurrent channels and can be easily extended to multiple devices. Be that as it may, the main event is that the UART is now fully functional and reliable. Very happy with that.
The next step for the SBC is to get a simple file upload going to load software into RAM. At that point, the SBC will have met it's primary objective of being a test platform for the TTL CPU (and thanks to dr Jefyll's good suggestion, a terrific learning experience as well). I'll have a little cleaning up to do (e.g., missing LEDs, etc.) and then it will be time to order the boards for the TTL CPU itself!
Can't wait!
C74-6502 Website: https://c74project.com
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: TTL 6502 Here I come
Drass wrote:
As I understood it, the WDC65C02 fixes the spurious reads which afflict the NMOS 6502 during dead bus cycles. Specifically for indexed addressing, it does so by re-reading the last instruction byte rather than the "partial" target address.
Quote:
But, to my surprise, single-cycling the SBC shows the processor puts $8000 on the address bus in the cycle preceding the write when executing this:
LDY #0
STA $8000,Y
Did I make a mistake or does the 'C02 generate spurious reads during indexed store operations?
LDY #0
STA $8000,Y
Did I make a mistake or does the 'C02 generate spurious reads during indexed store operations?
Quote:
The device has one of those I/O registers where otherwise harmless reads have specific side-effects.
Also, you have to be careful to not do a read on write-only registers, such as the channel command registers ($02 and $0A), as doing so may trigger some kind of hinkiness in the DUART.
Quote:
Of course, I happened to be using indexed addressing to configure the UART and I was seeing all sorts of seemingly unpredictable behavior; behaviour which in fact could be explained by a spurious read moving the goal posts on the configuration writes. More investigation confirmed the UART registers were not set up correctly, and after confirming with the single-cycle clock, a change to absolute addressing fixed everything!
. The UART is now solid (albeit with minimal testing at this point). Good news for the SBC, but it certainly left me wondering about those spurious reads.
Quote:
The interrupt mechanism is very well behaved, and I was able to get service routines working fairly quickly (using a buffering scheme I adapted from BDD's POC1 firmware - very nicely done BDD, thank you).
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: TTL 6502 Here I come
Drass wrote:
Did I make a mistake or does the 'C02 generate spurious reads during indexed store operations?
It's true the CMOS '02 introduced changes that address the NMOS '02 problem of partially-formed addresses appearing on the bus during indexing; and yes one tactic is to place PC on the bus during the "dead" cycle in question. But that's not to say you'll see PC appear in every case where an unused bus cycle occurs.
The fixes are not as predictable as all that, and there are irregularities not described in the doc. For example, dclxvi reported the anomaly summarized here. As shown in the original and amended charts below, there are inconsistencies even between almost-identical instructions!
BigDumbDinosaur wrote:
you may have discovered new errata in the 65C02.
-- 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: TTL 6502 Here I come
BigDumbDinosaur wrote:
you may have discovered new errata in the 65C02.
Dr Jefyll wrote:
Can you tell us what happens if you alter the code so the page crossing is guaranteed to happen (rather than guaranteed NOT to happen)?
1) If there is a page crossing, both LDA and STA absolute indexed correctly put PC on the address bus during the dead cycle (re-reading the last instruction byte).
2) If there is not a page crossing, LDA absolute indexed has no dead cycle, but STA does and generates a spurious read on that cycle.
Which I think agrees with your prediction Jeff, and seems to be the case for both the indexed with X and Y variants.
BigDumbDinosaur wrote:
I used the 65C816's VDA and VPA outputs to qualify memory cycles and was able to eliminate the problem. I'm not sure how you would go about achieving a similar behavior with the 65C02.
Dr Jefyll wrote:
It's comparatively harmless to read a byte you're about to write to ...
C74-6502 Website: https://c74project.com
Re: TTL 6502 Here I come
Thanks for reporting this, Drass. Yes, the followup agrees with my prediction but the initial observation was news to me.
This behavior is not entirely benign, even though the spurious read is from the same address which is about to be written to. It's not uncommon for an I/O device to place two registers at the same address, with all reads coming from one register and all writes going to the other register. So, writing to the latter register also entails an unexpected read of the former when 65C02 indexed addressing is used in the same manner as in your test.
The 'C02 lacks a VDA output, but there's a software workaround. Just rearrange the code in a way that guarantees a page crossing every time. For example, replace thiswith this:IO_PAGE-1 is a value whose LS byte is $FF, so any non-zero value of Y guarantees a page crossing. Only 255 IO registers can be addressed -- IO_PAGE+$FF is unreachable except by bypassing the workaround.
.If you're having THAT much fun, maybe you won't mind doing another experiment!
If you can spare us a moment, kindly try doing the writes with (ind),y address mode rather than abs,y. Both modes can result in page crossings. It'll be interesting to see how the dead-cycle addresses compare.
cheers
Jeff
This behavior is not entirely benign, even though the spurious read is from the same address which is about to be written to. It's not uncommon for an I/O device to place two registers at the same address, with all reads coming from one register and all writes going to the other register. So, writing to the latter register also entails an unexpected read of the former when 65C02 indexed addressing is used in the same manner as in your test.
The 'C02 lacks a VDA output, but there's a software workaround. Just rearrange the code in a way that guarantees a page crossing every time. For example, replace this
Code: Select all
STA IO_PAGE, y ; 0 <= y <= $FFCode: Select all
STA IO_PAGE-1, y ; 1 <= y <= $FF.
Drass wrote:
Took some time to figure this one out ... but who am I kidding, it's actually all part of the fun 
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
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: TTL 6502 Here I come
Drass wrote:
Dr Jefyll wrote:
It's comparatively harmless to read a byte you're about to write to ...
The same problem exists if MR0 is in context. The dummy read causes MR1 to come into context and the subsequent write is to the wrong register.
This behavior was one of the maladies that I had to grapple with in POC V1.0, which was resolved with the VDA/VPA logic. If, in fact, the 65C02 is randomly touching registers during intermediate cycles of an instruction I would consider that a product defect. It seems Jeff's solution might be the salvation if using index addressing to read and write the DUART registers.
Meanwhile, if we can get a coherent picture of exactly what the 'C02 is doing when index addressing is in use, that information could be disseminated to WDC as a report of an apparent product defect, since the behavior is not as described in the data sheet.
BTW, what is the date code of the 65C02 you are using? Also, I don't recall if you are using a 26C92 or 28L92.
x86? We ain't got no x86. We don't NEED no stinking x86!
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: TTL 6502 Here I come
Drass wrote:
Now I'm confused ...
As I understood it, the WDC65C02 fixes the spurious reads which afflict the NMOS 6502 during dead bus cycles...
As I understood it, the WDC65C02 fixes the spurious reads which afflict the NMOS 6502 during dead bus cycles...
BTW, I noted that you had said you were using an SC2692.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: TTL 6502 Here I come
Dr Jefyll wrote:
If you're having THAT much fun, maybe you won't mind doing another experiment! 
Quote:
try doing the writes with (ind),y address mode rather than abs,y
Quote:
The same problem exists if MR0 is in context.
Quote:
It seems Jeff's solution might be the salvation if using index addressing to read and write the DUART registers.
Quote:
what is the date code of the 65C02 you are using
Quote:
I noted that /OE doesn't appear to be qualified by Ø2. That could explain why the DUART is apparently getting flummoxed by spurious address generation. /OE could be going low before the address bus has settled, causing the 'C02 to touch two different DUART registers in rapid succession.
Quote:
How hard would it be for you to rework the logic to qualify /OE with Ø2?
C74-6502 Website: https://c74project.com
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: TTL 6502 Here I come
Drass wrote:
BigDumbDïnosaur wrote:
I noted that /OE doesn't appear to be qualified by Ø2. That could explain why the DUART is apparently getting flummoxed by spurious address generation. /OE could be going low before the address bus has settled, causing the 'C02 to touch two different DUART registers in rapid succession.
If you can believe the 65C02 timing diagram, all address bus lines should stabilize at the same time. Hence the UART will see a stable address at A0-A3 before the decoder asserts /CE on the UART, this being the result of prop delay through the glue logic. Continuing with this line of thinking, I'd say the address bus per se is not your problem. As you say, RWB is likely to be high at that time due to the previous cycle being a read, e.g., the MPU was fetching the MSB of the current instruction's operand. During the momentary period when the address bus is in a state of flux the wrong UART register might be selected, followed by selection of the correct register. That in itself might be harmless. However, with RWB being high at the time and /OE not being qualified by Ø2 and therefore continuously low, there is a strong possibility of a spurious read of the UART upsetting the apple cart.
x86? We ain't got no x86. We don't NEED no stinking x86!