6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Oct 06, 2024 10:51 pm

All times are UTC




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Thu Mar 15, 2018 2:37 pm 
Offline

Joined: Thu Mar 15, 2018 2:03 pm
Posts: 12
Hello! I'm Aaron -- First post! Woo-hoo!

I'm not a credentialed EE, just an enthusiastic electronics hobbyist who's worked with microcontrollers for a while and has finally resolved to take on 6502 project. I've got what I believe to be a good (if somewhat weird) design worked out, but my question is far more general and perhaps eye-rollingly noobish. Here goes:

So, my memory system comprises an assortment of buffer and register ICs with tri-state outputs and output-enable (OE) pins. The OE signals to each IC are, according to the address decoding logic, mutually exclusive. That is, only one OE should be asserted at any time. OE is further predicated on Phi2, the period of which is a massive ~560ns in this design, so there's no way that the outputs of one IC could still be driven when another IC takes over. I see no potential for bus conflicts during actual system operation.

...but what about at system startup? It seems likely that, for some tens of ns--perhaps longer--after power is applied, the OE signals of multiple ICs may be effectively asserted because the controlling logic isn't "awake" yet and hasn't had time to de-assert them (and de-asserting takes some time, too). So multiple ICs may be putting conflicting garbage onto the data bus. Is this just...ok? Too brief of an event to be damaging? I'm guessing so. I noticed that the TI datasheets for "AC" series logic mention putting pull-up resistors on the OE pins to ensure high-Z at startup (even that makes me scratch my head a bit), but I'm using "HC" series logic and there's no such warning in the datasheets for those parts. Further, I don't see pull-ups used for this sort of thing in any example schematics, or indeed in schematics of commercially-sold 6502-based equipment. *shrug*

I suppose it's possibly silly to worry about something that only happens for tens of ns and only during system startup, but...these are the sorts of things that irritate me and make me realize that I'm missing some obvious rule-of-thumb or something.

...Thanks for reading!


Top
 Profile  
Reply with quote  
PostPosted: Thu Mar 15, 2018 5:34 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8415
Location: Midwestern USA
Aaron wrote:
Hello! I'm Aaron -- First post! Woo-hoo!

Welcome to our 65xx world.

Quote:
...but what about at system startup? It seems likely that, for some tens of ns--perhaps longer--after power is applied, the OE signals of multiple ICs may be effectively asserted because the controlling logic isn't "awake" yet and hasn't had time to de-assert them (and de-asserting takes some time, too).

Well, assuming your microprocessor (MPU) reset circuit works properly, all of the MPU's outputs would be deasserted at reset and hence your glue logic should not be asserting any /OE or /WE inputs on your memory and I/O hardware. Can you post a (monochrome) schematic so we can help you analyze this? Glue logic behavior during reset is usually predictable, but having multiple sets of eyes looking at your circuit never hurts.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Thu Mar 15, 2018 6:32 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10949
Location: England
Indeed, welcome!

Broadly, I'd say yes, the conflict, if any, is going to be too short to be problematic - if you're using logic gates. If you'd built your glue logic out of an FPGA, then it will take some fractions of a second to load its configuration, so that might be a different case. (But note that FPGA pins are all inputs at reset time, and therefore external resistors could set appropriate values.) Similarly if you built the glue logic with a Propeller or a PIC or other microcontroller, startup might take some little time.

But note that other things also take time: the time for the power rail to ramp up, and the time for a crystal oscillator to start oscillating. I would guess tens of milliseconds for both.


Top
 Profile  
Reply with quote  
PostPosted: Thu Mar 15, 2018 10:20 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8415
Location: Midwestern USA
BigEd wrote:
Broadly, I'd say yes, the conflict, if any, is going to be too short to be problematic - if you're using logic gates. If you'd built your glue logic out of an FPGA, then it will take some fractions of a second to load its configuration, so that might be a different case. (But note that FPGA pins are all inputs at reset time, and therefore external resistors could set appropriate values.) Similarly if you built the glue logic with a Propeller or a PIC or other microcontroller, startup might take some little time.

I note that Microchip (formerly Atmel) states that all outputs on their CPLDs are high-Z at initial power-on, assuming a monotonic rise of Vcc. Although I haven't fully explored it, I have not noticed any undefined logic states in both versions of POC V2 (Atmel ATF1504AS CPLD) during reset.

Quote:
But note that other things also take time: the time for the power rail to ramp up, and the time for a crystal oscillator to start oscillating. I would guess tens of milliseconds for both.

I've noticed in the past that the oscillators I use in my POC units take 30-50 milliseconds to produce a usable output. The Maxim DS1813 reset generator I use in my POC units holds reset low for 150 milliseconds minimum after Vcc has risen to at least 4.5 volts. By then, the clock generator has stabilized. Reset is also used to put the CPLD into a known state, which means all chip selects are in the deasserted condition until reset clears.

POC V1.1 used discrete logic and never caused any undefined behavior while reset was low.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Mar 16, 2018 2:43 pm 
Offline

Joined: Thu Mar 15, 2018 2:03 pm
Posts: 12
Thank you both for the kind welcome and the quick replies!

BigDumbDinosaur wrote:
Well, assuming your microprocessor (MPU) reset circuit works properly, all of the MPU's outputs would be deasserted at reset and hence your glue logic should not be asserting any /OE or /WE inputs on your memory and I/O hardware. Can you post a (monochrome) schematic so we can help you analyze this? Glue logic behavior during reset is usually predictable, but having multiple sets of eyes looking at your circuit never hurts.


Yes! Schematic below. (My reply is delayed because I hadn't drawn one yet. It was just handwritten notes and thoughts.) I suppose "startup" was ambiguous. I should have said "power on." I wasn't referring to the reset time, but rather to the time between when power is first applied to the circuit and the time the logic gates find valid states.

...although I suppose the same concern (if real) would apply during operation as well--for example, if as some posts advise, one chooses not to pay attention to Phi2 for read-only devices. But if you have multiple ROMs in your system and a decoder (e.g. 74HC138) supplying the output-enables, might not a transition between two addresses lead to momentary "conflicts" on the bus if the transition causes one device to be selected and another to be deselected? I suppose this is a scenario that would suggest pull-ups on the OE pins (to hasten their disabling)? I see that being done in some circuits, though mainly for the 65xx peripheral ICs (Here's an example where this is done for the 6551 and others.) This isn't a situation that applies to my own circuit, I don't think, as it's easy enough for me to pay attention to Phi2, and my whole external memory system is read-only besides. (More on that down below.)

BigEd wrote:
Broadly, I'd say yes, the conflict, if any, is going to be too short to be problematic - if you're using logic gates. If you'd built your glue logic out of an FPGA, then it will take some fractions of a second to load its configuration, so that might be a different case. (But note that FPGA pins are all inputs at reset time, and therefore external resistors could set appropriate values.) Similarly if you built the glue logic with a Propeller or a PIC or other microcontroller, startup might take some little time.


That's sort of what I thought, and I don't see people designing to avoid it. It feels like one of those "just don't worry about it" situations, but I couldn't help asking. No programmable logic in this circuit, no. Just 74HCxxx.

Here's the requested schematic:
Attachment:
2a03MCUschematic.png
2a03MCUschematic.png [ 16.37 KiB | Viewed 3668 times ]


Doubtless this looks pretty strange, so here's the overdue explanation: The CPU in use is actually a Ricoh RP2A03G, the customized 6502 found in the Nintendo Entertainment System. The goal of this circuit is to give an MCU (Arduino) easy control of the internal audio functions of the 2A03, which are mapped internally at addresses $40xx. The MCU will (hopefully) just clock the data it wants to write into the BYTE4 flip-flop (IC5), clock the address offset xx into the BYTE6 flip-flop (IC6), and then assert NMI. The 2A03 should then perform the desired write.

The diode matrix implements the following code:
$0000: JMP $0000
$0003: LDA #$xx ; operand xx is supplied by the BYTE4 flip-flop
$0005: STA $40xx ; operand xx is supplied by the BYTE6 flip-flop
$0008: RTI
$000A: $03 ; this is the low byte of the NMI vector. A0-A3 are the only addr lines used, so this is also address $FFFA

Bytes not supplied by the matrix or by the flip-flops read as zeros. This includes the reset and IRQ/BRK vectors.

The stack is read-only, and will reside in the same physical location in memory as the interrupt vector table, most of which is zero. The result of this is that, when an NMI is taken, the stack pushes will go nowhere, but on RTI, PC will be restored by popping zeros from the vector table, returning execution to $0000--which is what's desired.

Phew!

Anyway. That's the idea!


Last edited by Aaron on Sat Mar 17, 2018 2:27 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 17, 2018 9:38 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10949
Location: England
Now that's an interesting idea and an interesting circuit! I'm a big fan of diode ROMs, perhaps partly because they are rarely seen. (I think it would be good for you to repost that in the hardware thread with a suitable title - you might not catch your audience in this thread!)


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 17, 2018 5:24 pm 
Offline

Joined: Thu Mar 15, 2018 2:03 pm
Posts: 12
BigEd wrote:
Now that's an interesting idea and an interesting circuit! I'm a big fan of diode ROMs, perhaps partly because they are rarely seen. (I think it would be good for you to repost that in the hardware thread with a suitable title - you might not catch your audience in this thread!)


I'll certainly do that--but perhaps in a week or so, when I've had a chance to prove that it works. (I've got all the bits, now I just need the time!) My first thought was to have a small RAM that would be filled with 6502 code by the Arduino while the 2A03 was held in reset, but when I investigated the 6502 instruction set and realized that I only needed four instructions, a RAM--or, indeed, any memory IC--seemed like overkill. And, of course, a missed opportunity to do something bizarre! :)

This will not be the first 2A03/Arduino project. There are two others, one of which is a simple variation on the other. These use the Arduino as the memory, with the Arduino madly watching the address and control lines. This seems like an interesting approach too, but the hardware is surprisingly similar in complexity to what I've done here, and the code is definitely more fragile. I'll be sticking to my own approach for now.

More as the project develops!

(The next project I hope to embark on will be a general-purpose MCU based on the Ricoh 5A22, the Nintendo-customized 65C816. That'll be a much more involved circuit, methinks!)


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 17, 2018 5:30 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10949
Location: England
Works-in-progress are fine posts too, here - which is a good thing, as some projects are never finished.

(Feel free to Introduce Yourself too.)


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 18, 2018 1:52 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Aaron, anyone who notices opportunities to do something bizarre -- and worries about missing such opportunities! -- is good folks as far as I'm concerned. :) Welcome! I think I like your inline operands even better than your diode matrix!

But you've made a minor booboo, I think. You said, on RTI, PC will be restored by popping zeros from the vector table, returning execution to $0000. But it seems to me you want a BRK, not an RTI. BRK reads vector table as desired. RTI uses the (uninitialized) stack pointer S to read something probably not desired! :roll: :P

BTW on this forum you'll find if you look carefully there's a monospaced font available for code. Like this:
Code:
$0000: JMP $0000
$0003: LDA #$xx ; operand xx is supplied by the BYTE4 flip-flop
$0005: STA $40xx ; operand xx is supplied by the BYTE6 flip-flop
$0008: RTI
$000A: $03 ; this is the low byte of the NMI vector. A0-A3 are the only addr lines used, so this is also address $FFFA

cheers,
Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 18, 2018 4:34 am 
Offline

Joined: Thu Mar 15, 2018 2:03 pm
Posts: 12
Dr Jefyll wrote:
Aaron, anyone who notices opportunities to do something bizarre -- and worries about missing such opportunities! -- is good folks as far as I'm concerned. :) Welcome! I think I like your inline operands even better than your diode matrix!

But you've made a minor booboo, I think. You said, on RTI, PC will be restored by popping zeros from the vector table, returning execution to $0000. But it seems to me you want a BRK, not an RTI. BRK reads vector table as desired. RTI uses the (uninitialized) stack pointer S to read something probably not desired! :roll: :P

BTW on this forum you'll find if you look carefully there's a monospaced font available for code. Like this:
Code:
$0000: JMP $0000
$0003: LDA #$xx ; operand xx is supplied by the BYTE4 flip-flop
$0005: STA $40xx ; operand xx is supplied by the BYTE6 flip-flop
$0008: RTI
$000A: $03 ; this is the low byte of the NMI vector. A0-A3 are the only addr lines used, so this is also address $FFFA

cheers,
Jeff


Jeff! :o You might have just saved me (almost) half a dozen diodes! But first: Will S really not be initialized at reset? Visual6502 says it'll be $FD, but my original code above should be happy with $FD-$FF or even $00. But if it's not guaranteed to have any particular value, then I see what you mean.

In any case, your BRK suggestion is fantastic and seems like a clear winner. Let me reason it out: So, it doesn't matter to BRK that I'm already in the NMI handler, and BRK is endlessly reentrant (yes?), so I can use BRK to (effectively) jump to $0000. (And for a savings of one diode over RTI.) BRK will push the return address and status onto the stack (wherever that is), and as I'm BRK-ing like mad and never RTI-ing, the stack will eventually just wrap around (which doesn't matter in this circuit). If that works, I wonder: Might I also replace JMP $0000 with BRK? That would save me four more diodes (three for the JMP opcode, and one more because my NMI vector would go from $03 to $01). Presumably, if that worked, it would have a negative (but probably inconsequential) impact on my NMI handling latency.

Let me cogitate over this some more, because I certainly wouldn't mind cutting my diode count by a full third.

Sorry 'bout the code font thing. I ought to have noticed the Code button, but was half asleep as I composed the post.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 18, 2018 5:03 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Quote:
I wonder: Might I also replace JMP $0000 with BRK?
(Ha! Great idea to use BRK as a replacement for the JMP 0000 that's at xxx0 -- somehow I missed that, doh! My excuse is I was fooling with two other ideas, both quite entertaining, and I'm almost finished writing one of them up -- below:)

First, here's your original memory map (as I understand it) except I've replaced the RTI at xxx8 with BRK as discussed.
Code:
xxx0:  4C  jmp abs opcode
xxx1:  00
xxx2:  00
xxx3:  A9  lda# opcode
xxx4:  **  (port)
xxx5:  8D  sta abs opcode
xxx6:  **  (port)
xxx7:  40
xxx8:  00  brk opcode (was: rti)
xxx9:  00 (not used)
xxxA:  03  lo-byte of NMI vector
xxxB:  00  hi-byte of NMI vector
xxxC:  00  lo-byte of RST vector
xxxD:  00  hi-byte of RST vector
xxxE:  00  lo-byte of IRQ/BRK vector
xxxF:  00  hi-byte of IRQ/BRK vector

; Plan A: the pattern as shown repeats every 16 bytes throughout all 64K
; Plan B: (discussed below) a similar pattern repeats every 16 bytes throughout lowest 32K


When A15 is low my new schematic (Plan B) gives a similar pattern to Plan A; the only difference is the 03 at xxxA becomes 00, which is inconsequential. When A15 is high the Plan B map has four bytes of 03, then four bytes of 00, repeating throughout the 32K. The new schematic put the two unused NAND sections to work, thus eliminating one of the decoder IC's! :mrgreen:
Attachment:
2a03MCUschematic - mod-jl.png
2a03MCUschematic - mod-jl.png [ 33.48 KiB | Viewed 3609 times ]
Still need to double-check this, though. Like most of us, I'm capable of gross blunders from time to time.

More subtly, and WRT using BRK as a replacement for the JMP 0000 at xxx0: some 65xx chips are vulnerable "interrupt highjacking," which is the gray-area behavior you get when a hardware interrupt is roughly coincident with a software interrupt (ie, BRK). Which vector will the CPU fetch? I don't know these details offhand. But I'm inclined to say it doesn't matter, as long as none of our NMI's actually get lost. To be on the safe side we could just keep the JMP 0000 at xxx0.

-- Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Last edited by Dr Jefyll on Sun Mar 18, 2018 5:38 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 18, 2018 5:38 am 
Offline

Joined: Thu Mar 15, 2018 2:03 pm
Posts: 12
Hi Jeff -- Ah! You beat me to it. I was considering the now extremely underutilized second '138 and how to get rid of it. To make sure I understand the hijacking concern (which, according to the nesdev forums, is a valid concern on the 2A03): The BRK in the NMI ISR would be considered safe because it could be avoided by simply ensuring that the MCU provided sufficient delay between NMIs to prevent them from ever landing on it. Obviously, with BRK in place of JMP $0000, no (reasonable) timing tricks would guarantee safety. Yes? I think I'm keeping up. :) Great suggestions, Jeff. I really appreciate it!


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 18, 2018 5:57 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
Fun, eh? :) Btw you can save 3 diodes if you use register Y instead of A. The LDA# opcode is $A9; the equivalent for Y is $A0. Likewise the STA abs opcode is $8D; for Y it's $8C.

There's one other idea, but I don't think we'll need it. To gain an extra byte, move the ISR lower so it begins at 0002 instead of 0003. ie; the NMI vector would point to 0002. Yes, the byte at 0002 is the hi-byte of the operand of the JMP instruction... but the hi-byte is kinda-sorta a don't care; we can mess with it. It's gratifyingly tricky. The byte at 0002 would do double duty -- both as an operand and as an opcode! :twisted:

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Last edited by Dr Jefyll on Sun Mar 18, 2018 6:33 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 18, 2018 6:31 am 
Offline

Joined: Thu Mar 15, 2018 2:03 pm
Posts: 12
I hadn't taken the diode pruning too seriously in the beginning, but it's a fun exercise, yes. And while certainly not needed, the $0002 NMI vector is yet another diode saved as well, so...*shrug*... why not? :)


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 18, 2018 6:43 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
I edited that last post; it now describes the operand hi-byte as a "kinda-sorta" don't care. But if we use Y then the opcode/operand will be $A0 -- and the main loop will run at $A000, always repeating a JMP $A000. That's alright but only if, in my schematic, you feed A14 (eg) to the NAND and decoder, not A15.

If it were imperative to gain another byte then the double-duty operand/opcode would be worth it. But merely to save a diode... I dunno. Sorry for the sleepy, half-baked posts. Off to bed now!

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: