6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 8:08 pm

All times are UTC




Post new topic Reply to topic  [ 558 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 38  Next
Author Message
 Post subject: Re: TTL 6502 Here I come
PostPosted: Sun Apr 10, 2016 11:44 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
A brief update on the 65C02 implementation. It turns out that the circuits required for the remaining incompatibilities are straight forward and compact after all! Here is what it looked like:

  • A single 7474 latch captures the /SO pin transition and generates a low-going pulse to the PRE input of the V Flag flipflop in the status register. The ALU can easily clobber this depending on what instructions are being executed at the time, but so far as I can tell, there is not need to protect against this. It's a "programmer beware" scenario for this one. (Btw, I realize the 6502 has an /SO pin, but I had left it unimplemented to this point. Feels good to get it done now).
  • /VP required only a single NAND gate! Turns out a couple of signals which trigger the Constant Generators for the vector addresses could be easily used as inputs to a NAND to generate /VP.
  • /ML was trickier. /ML goes low on the Modify cycle of Read/Modify/Write instructions. The Rockwell data sheet says the signal should of high again after the Write cycle, but the WDC data sheet specifies /ML should remain low for three cycles to the end of the instruction sequence (essentially to the next opcode fetch in the Read/Modify/Write/Opcode-fetch sequence which all RMW instructions share). The WDC spec is easier to implement since the end of the instruction is a clear point to bring /ML high again. So, a specific signal from the microcode sets the /ML flipflop on PHI2 of the Read cycle and the end of the instruction sequence clears it.
  • STP and WAI are also triggered by specific signals from the microcode. A couple of NAND gates take RDY and BE low as necessary to stop the clock and tri-state the busses. The interrupt signals are used to free RDY and BE once again thereafter. Thankfully, Dieter (ttlworks) made quick work of dealing with the bi-directional nature of RDY on the 65C02., which would have stumped me completely :)

And that's it! This shoulld all fit on the cards nicely and it all seems well worth it - I think the processor is now pin-compatible and cycle-accurate for all "documented" features of the 6502, 6510 and 65C02. :shock: Wow. Never thought I would get to this point!

Cheers,
Drass

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Mon Apr 11, 2016 1:38 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8506
Location: Midwestern USA
Drass wrote:
  • STP and WAI are also triggered by specific signals from the microcode. A couple of NAND gates take RDY and BE low as necessary to stop the clock and tri-state the busses. The interrupt signals are used to free RDY and BE once again thereafter. Thankfully, Dieter (ttlworks) made quick work of dealing with the bi-directional nature of RDY on the 65C02., which would have stumped me completely :)

STP and WAI on the real 65C02 don't do anything to BE. If the desire is to stop the MPU and kick it off the buses both RDY and BE have to be pulled low together. WAI internally stops the clock in the high phase and pulls RDY low, which means WAI is the software analog of hardware pulling down RDY. All STP does is internally stop the clock in the high phase. After being stopped with WAI the 65C02 restarts on any hardware interrupt, whereas it only responds to RESET if stopped with STP.

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


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Mon Apr 11, 2016 3:41 am 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
Thanks for the note BDD. I should have been more clear. WAI does pull RDY low as you point out. But STP in fact pulls low the second input of a NAND gate it shares with RDY internally, such that either input going low will stop the clock. So, in effect, STP stops the clock and leaves RDY unaffected. Sorry for the confusion. The same goes for BE and the busses, where a NAND gate allows STP to tri-state the busses without affecting BE.

Now, I was under the impression that STP puts the buses in a high-impedance state, but as I went to confirm, I was left unsure. The WDC's Programming the 65816 page 200 states "Like the WAI instruction, the STP idles the processor after being executed. Further, the processor I/O buffers are disabled, making the bus available." - which I took to mean that the busses were tri-stated. But it's ambiguous since elsewhere in the manual no reference is made to the buses when STP is described in more detail.

BDD, to confirm, you are saying that the 65c02 STP only stops the clock and leaves the buses alone. Correct?

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Mon Apr 11, 2016 2:59 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8506
Location: Midwestern USA
Drass wrote:
BDD, to confirm, you are saying that the 65c02 STP only stops the clock and leaves the buses alone. Correct?

The data sheet indicates that the only effect STP has on the MPU is to internally stop the clock in the high phase. Stopping the clock will cause the MPU to stop executing instructions and reduce its current draw to a very low level, micro-amperes, in fact.

Furthermore, the operations chart in the 65C816 data sheet (page 42) indicates that the MPU drives MLB, RWB and VPB high, and drives VDA and VPA low when stopped with STP or WAI. RWB is one of the signals that would go to the high-Z state if BE were negated. Therefore, it can be implied that the MPU does not high-Z the buses when stopped with STP or WAI.

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


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Tue Apr 12, 2016 12:44 am 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
Thank you. The reference to the 65C816 data sheet is very helpful.

Of course, in my case, I can stop the clock but I can't duplicate that kind of current draw :) Anyway, it's nice it to get the correct STP behaviour nevertheless.

I was able to note also that I had implemented MLB incorrectly. The Rockwell data sheet had me thinking that MLB should be left high for the Read cycle but the 65C816 data sheet cleared that up. All corrected now.

Best,
Drass

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Mon Apr 18, 2016 12:21 am 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
I was looking at some of the unofficial opcodes when I ran across some nice examples of how these are a result of "don't care" states in the 6502 opcode decoder (aka the PLA). This has been examined elsewhere at some depth (e.g. http://visual6502.org/wiki/index.php?title=6507_Decode_ROM) but a more basic look was helpful to me so I though I would share this. The unofficial LAX is a nice example. On the 6502,

$A4 is LDY <zpg>,
$A5 is LDA <zpg>, and
$A6 is LDX <zpg>,

which indicates the lower two bits of the opcode determine the target register for the load operation, as follows:

00 = Y
01 = A
10 = X
11 = *don't care*

to implement this with some gates, we might write it in boolean terms as:

Y = /OP1 & /OP0
A = OP0
X = OP1

That of course leaves the "11" combination as a "don't care" which, according to the boolean expressions above, triggers a write to both A and X. So we get $A7 = LAX <zpg> (lower two bits = 11 = A and X) which loads both A and X from memory.

There is a nice parallel also in SLO <zpg>. Here, opcode $05 is ORA <zpg>, $06 is ASL <zpg> and $07 is a combination of the two - the unofficial SLO <zpg>, which both shifts memory left and ORs the result with the accumulator. Here is the microcode I use for for ASL:
$05: ASL <zpg>
Code:
DPL := *PC; PC += 1
B := *zDP
T := 0 ASL B; SETF(NZC)
*zDP := T
IR := *PC; PC += 1; END
And this is what ORA <zpg> looks like:
$06: ORA <zpg>
Code:
DPL := *PC; PC += 1
B := *zDP
A := A OR B; SETF(NZ); IR := *PC; PC += 1; END
Rather neatly, the microcode for SLO performs the ASL and then, on the last step, includes the OR operation from the last line of the ORA sequence, as follows:
$07: SLO <zpg>
Code:
DPL := *PC; PC += 1
B := *zDP
T := 0 ASL B; SETF(NZC)
*zDP := T
A := A OR B; SETF(NZ); IR := *PC; PC += 1; END
Once again, the lower two bits of the opcode tell the tale. Looking at the "aaabbbcc" format for the opcode (http://www.llx.com/~nparker/a2/opcodes.html), ORA belongs to the cc = 01 ALU only opcodes while ASL to RMW ones where cc = 10. In each case, the "aaa" parameter selects the operation. So aaa = 000 refers to ORA if cc = 01 or to ASL if cc = 10. The $07 SLO opcode where cc = 11 triggers both, albeit each at a different cycle of the instruction sequence.

Incidentally, the microcode above for SLO would not work for me because of a change I made earlier to accommodate TSB and TRB in the 65C02 microcode - namely, inhibiting the B data latch on write-cycles. The TSB/TRB microcode needed that to allow the unmodified value of B, which is latched in cycle 3 below, to survive the store operation in cycle 4:
Code:
1: DPL := *PC; PC += 1
2: B := *zDP
3: B := *zDP; T := A OR B
4: *zDP := T
5: A AND B; SETF(Z); IR := *PC; PC += 1; END
Meanwhile, SLO in the NMOS 6502 microcode requires exactly the opposite. Latching B on the write cycle in this case supplies the modified value after the ASL operation to the subsequent OR, which is correct.

So, it seems a further change may be necessary to allow both requirements to co-exist, by for example, inhibiting the B data latch on write-operations but only for TRB/TSB opcodes. I can do that simply by latching B on write cycles only when bit 0 of the opcode OP0 = 1 (since TSB and TRB have OP0 = 0 and SLO opcodes have OP0 = 1). Alternatvely, I can use the microcode-select-bits to inhibit the B latch only for the 65C02 microcode. That's probably cleaner, but I should have a closer look at the other unofficial opcodes before going any further. I know some can be done with only microcode changes, but others look a little nasty. We'll see.

Cheers,
Drass.

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Mon Apr 25, 2016 3:05 am 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
Looking more closely at the undocumented opcodes, it turns out many can be implemented in microcode only, and be cycle accurate to boot!

So far as I can tell, the following opcodes can be cycle accurate with no changes to circuitry:

NOPs and Multi-Cycle NOPs, KIL, LAX, RLA, RRA, SLO, SRE, DCP, ISC, SBC, ALR, XAA

Now, there are a few opcodes that require an AND operation between two registers:

ANC, SAX, SHX, SHY, LAS, AXS

As I understand it, this ANDing is the result of values combining in the SB bus of the NMOS 6502 simply by having the output enable signals for two registers firing at once. Unfortunately, the same trick won't work for TLL logic. As it is, the ALU can only operate on a single register and the B Data Latch. To use the ALU on two registers for this special AND requires transferring the value of a register to the B data latch prior to the ALU operation.

Since the B data latch only reads from the data bus, the only way for existing circuitry to achieve the transfer is a write to memory, with the B data latch capturing the value being written. An alternative is to implement a second B latch which captures the output of the ALU and then feeds the B input of the ALU once again. This has the advantage of allowing an ALU operation as part of the register transfer (SHX and SHY can use this ... SHX = store X AND high-byte(target_address) + 1 into the target_address.). The obvious disadvantage is the additional circuitry required. And all this, of course, requires extra cycles. A final alternative, which could yield cycle accurate behaviour at the expense of yet more hardware, is to add dedicated AND circuitry just for these opcodes - which seems a little heavy handed.

Then there are a couple of difficult opcodes ... TAS (S = X AND A, M = S AND HIGH(arg) + 1) and AHX (A & Y & HIGH(arg)), which require even more gymnastics to pull off. And the nastiest of them all: ARR, which seems to have a list of side-effects an arm long. :twisted:

I'm pleased that most undocumented opcodes be done in microcode, and that seems very worthwhile to implement. Cycle exact behaviour for ALL undocumented opcodes, however, seems beyond reach, at least not without major surgery on the current design. We'll have to see how things evolve.

Best,
Drass

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Mon Apr 25, 2016 7:33 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Here's a couple of possibilities which might be interesting: If you build your busses as open-collector, you'll get a wired-AND effect much like the 6502's, I think. Or, if you were using multiplexors to corrall the various bus drivers, you can use NAND instead and again get some trivial logical combination for free.


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Mon Apr 25, 2016 11:00 pm 
Offline
User avatar

Joined: Sun Oct 18, 2015 11:02 pm
Posts: 428
Location: Toronto, ON
BigEd wrote:
Here's a couple of possibilities which might be interesting: If you build your busses as open-collector, you'll get a wired-AND effect much like the 6502's, I think. Or, if you were using multiplexors to corrall the various bus drivers, you can use NAND instead and again get some trivial logical combination for free.
Thanks for these suggestions!

I like the idea of a wired-AND as this seems faithful to what the 6502 is doing in reality and, I assume, the same circuit can handle three inputs just as well as two. Open collector is definitely not something I would have thought of so thank you for pointing it out. Not quite sure how I would fit this into the current design but it's sure worth thinking about. I'm going to sit with it for a bit, and finish up the microcode for the other opcodes in the meantime.

Cheers,
Drass.

_________________
C74-6502 Website: https://c74project.com


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Tue Apr 26, 2016 6:59 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
The idea to build an open_collector bus for implementing a wired_AND between registers sure is good,
and 74573 latches with push_pull outputs could be "converted" into having "open collector outputs"
by making creative use of LL101 or BAT41 Schottky diodes...

I'm just afraid that having an open_collector bus might create some other problems,
because the fast version of the CPU is supposed to run at (nearly) 8 MHz,
and there might be quite some capacitive load on that bus.


...this sort of reminds me to the "ghost interrupt" problematic when multiple 6522 open_collector
/IRQ outputs are wired together.
You can't use a pullup resistor with a too low resistance here, and because of the capacitance
of the pins on an open_collector IRQ line, it takes some time until the logic level at /IRQ
reaches logic high level again.
This effect isn't critical when the CPU is running at 1 MHz, but at higher clock frequencies it is.


Looks like we need to spend some more thoughts on this.


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Tue Apr 26, 2016 7:54 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Yes, in effect you end up building a diode-resistor logic gate, or something like it, and it won't be fast. In the 6502 case, the number of bus drivers which might actually be driving at the same time is probably 3 or 4, so using an actual NAND might be feasible. Of course, it increases the wiring.


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Tue Apr 26, 2016 8:39 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
Took a closer look at the undocumented opcodes which do an ALU operation between two registers.

;---

$9E SHX absy // T := X & (H+1)

$9C SHY absx // T := Y & (H+1)

$9B TAS absy // T := A & X & (H+1); S := A & X

$9F AHX absy // T := A & X & (H+1)

$87 SAX zp // T := A & X

$CB AXS imm // X := (A & X) - #imm

;---

From the equations, it appears that it could be done with:

(A & X) -> R bus // read decoder

(H+1) -> B bus // always comes together with writing T

;---

Placing (A & X) on the R Bus:
2* 74574 as shadow registers for A,X
2* 7408 for the AND
1* 74541 as bus buffer, output enable comes from the read decoder.

Placing (H+1) on the B bus:
1* 74574 as shadow register for DPH
2* 74283 for incrementing.
1*74541 as bus buffer, output enable comes from the write decoder.
...means, that one write enable just writes T,
and another write enable writes T while placing (H+1) on the B bus.

;---

It's just a half_baked idea, of course, and it needs to be tested...


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Tue Apr 26, 2016 10:12 am 
Offline
User avatar

Joined: Fri Nov 09, 2012 5:54 pm
Posts: 1431
Now for the fanciest opcode ever... ARR.
Tried to test ARR on my C64:

.2000 A0 00 98 18 D8 6B FF D8
.2008 99 00 24 08 68 99 00 25
.2010 C8 D0 EF 60

This short little test program runs a loop with
$00..$FF in the Y register, does a TYA, then ARR #$FF,
then stores the result and a copy of the status register
as a table into memory.

;---

ARR binary mode is simple:

Code:
       ---       ---
A-----|   |tmp1 |   |tmp2
      | & |-----|ROR|------*---> Result
#imm--|   |     |   |      |
       ---       ---        ---> Flag evaluation
                  ^
                  |
                 C_Flag

tmp1 := A & #imm
tmp2 := "ROR" tmp1 //C_Flag goes into tmp2.7

//Result = tmp2

N_Flag := tmp2.7 // = ROR input carry
Z_Flag := set if tmp2=$00
C_Flag := tmp2.6
V_Flag := tmp2.6 XOR tmp2.5


It isn't a 'real' ROR of course:
C_Flag goes into Bit 7, but it isn't modified by that 'shift right'.

;---

ARR decimal mode is not simple:

Code:
 
                   ---
                  |   |  "correction"
                 -|det|-----------
                | |   |           |
                |  ---            V
       ---      |  ---           ---
A-----|   |tmp1 | |   |tmp2     |   |
      | & |-----*-|ROR|------*--| + |-> Result
#imm--|   |       |   |      |  |   |
       ---         ---       |   ---
                    ^        |
                    |         ---> Flag evaluation
                   C_Flag

tmp1 := A & #imm
tmp2 := "ROR" tmp1 //C_Flag goes into tmp2.7

Now for those little boxes labeled 'det' and '+',
the BCD "correction":

if (tmp1 & $0F) > $04
then Result.3..0 := tmp2.3..0 + $06
else Result.3..0 := tmp2.3..0 + $00

if (tmp1 & $F0) > $40
then Result.7..4 := tmp2.7..4 + $60 ; C_Flag :=1; //nothing else would set C_Flag in ARR decimal mode !
else Result.7..4 := tmp2.7..4 + $00 ; C_Flag :=0;

N_Flag := tmp2.7 // = ROR input carry
Z_Flag := set if tmp2=$00
V_Flag := tmp2.6 XOR tmp2.5

On my C64, ARR in binary mode and ARR in decimal mode take the same amount of cycles,
checked this with CIA2 timer A.


Top
 Profile  
Reply with quote  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Tue Apr 26, 2016 3:35 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3367
Location: Ontario, Canada
BigEd wrote:
Yes, in effect you end up building a diode-resistor logic gate, or something like it, and it won't be fast.
ttlworks wrote:
You can't use a pullup resistor with a too low resistance here, and because of the capacitance
of the pins on an open_collector IRQ line, it takes some time until the logic level at /IRQ
reaches logic high level again.

It's true the resistor is a limiting factor, speed-wise. But diode/open-collector logic needn't include a resistor. As Arlet pointed out here, the other alternative is to precharge the capacitance of all eight bus lines. This requires 8 pullup FETs (or one FET and 8 pullup diodes). Then during the appropriate clock phase you enable data from the open-collector drivers. Each individual bus line will either stay high or promptly go low -- but there'll be no RC delay.

-- 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  
 Post subject: Re: TTL 6502 Here I come
PostPosted: Tue Apr 26, 2016 3:40 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Even better! And precharge is also used in the NMOS 6502, so it's very authentic.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 558 posts ]  Go to page Previous  1 ... 5, 6, 7, 8, 9, 10, 11 ... 38  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 30 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:  
cron