sjgray wrote:
Each bank [...] has it's own zero page and stack.
Thanks, Steve. I think this reveals the 6509 is not a specially designed CPU -- instead it's just a sidecar hung on the 6502 (sort of like the 2A03, which uses a stock 6502 mask but with a bit of extra logic added around the perimeter).
Here is my version of add-on logic for a 6509 look-alike. If my understanding of the 6509 is correct, then this circuit, connected to a 6502, should reproduce 6509 behavior. [Edit: confirmed -- see subsequent posts.]
Attachment:
6509_look-alike.png [ 11.21 KiB | Viewed 8008 times ]
I drew this with 6502 in mind but offhand see no reason it wouldn't be OK for the 'C02 or even the '816. The circuit detects the opcode fetch of the two modified 6509 instructions,
STA (Ind),Y and
LDA (Ind),Y (op-codes $
91 and $
B1). The data access occurs later -- either during in cycle 5 or 6. It'll be cycle 5 only if the access is a read and no page crossing occurs, as per normal 6502 behavior. During cycle 5 (and cycle 6, if it's present) the Indirect memory bank is selected by the 74_157 mux. If it's a read with no page crossing, cycle 6 will be absent, as per normal 6502 behavior. In that case the circuit uses SYNC to ensure it'll be the Execution bank that's selected for the opcode fetch in the cycle which follows cycle 5.
Note:- I haven't bothered to draw the output port logic that provides the two bank addresses.
- the '377 is an octal, edge-triggered register similar to '374 or '574, but clocking with /EN high ignores the new input data on D and reloads the data already on Q. IE: the output remains unchanged.
- The XOR gate protects against the false opcode fetch that occurs whenever an interrupt is recognized. There's a risk that a $91 or $B1 opcode will get fetched but not executed. If this happens the circuit mustn't respond. To recognize the beginning of the cpu's interrupt sequence we look for the unique circumstance of the address bus failing to increment in the cycle following an opcode fetch. No increment means the least-significant address line, A0, will fail to toggle. The output of the XOR gate will be low, thus inhibiting the circuit.
- To simplify the circuit D1 could be ignored (like D5). This would render the circuit susceptible to triggering from opcodes $93 and $B3, but these are undefined op's anyway.
mdpenny wrote:
"hacking" an '02 with external logic would likely impose limits on performance
Right, Martin -- certainly that's a legitimate concern for this circuit (in its present form). For example in some situations there'll be no valid bank address until SYNC has had time to propagate into the mux. At NMOS CPU speeds that's a fairly trivial delay, but for a modern 'C02 running at, say, 14 MHz, it's much more of an issue. Hmmm....
For the '816 you could make use of VPA and VDA signals, which would inform you
in cycle 5 whether there's a page crossing. Having that advance notice means
you could use fully synchronous logic and eliminate the performance limit. IOW you could 6509-ify an '816 and run it at the full 14 Mhz.
The FPGA approach is attractive too, of course. (I mean with the cpu core implemented on FPGA.) The add-on approach could be abandoned for something more elegant and resource-efficient!
Since the goal seems to be to run pre-existing CBM-II code, the question arises whether the FPGA core would have to accurately reproduce undefined 6502 op's. Do CBM-II applications use illegal instructions?! (This issue would also affect the 'C02 and '816 add-on look-alikes.)
-- Jeff
Edits: Fix typo. Improve clarity. Fix booboo: '377 register, not '273.
Edit (2018): Improve clarity. Fix booboo: the Enable on a '377 is active low, not active high. The updated diagram reflects this. Also, the original logic (shown below) unnecessarily imposed
two gate delays between SYNC and the mux.
Attachment:
previous version of logic.png [ 1.93 KiB | Viewed 8008 times ]