Created plain-text documentation for the 6502 clock time codes. Added function

that creates the text expression of the time codes seen in the documentation
to macros.js and expert-allinone.js.

Added documentation file: 6502timecodes.txt
Added function: allTCStates()
This commit is contained in:
mmfoerster 2017-09-19 20:01:47 -04:00
parent 90f57631c0
commit 27d0eb8fb2
3 changed files with 231 additions and 0 deletions

125
6502timecodes.txt Normal file
View File

@ -0,0 +1,125 @@
6502 Time codes.
There are two things that are critical for correct instruction execution in
the 6502 (indeed, for any CPU chip): the pattern of bits in the instruction
register AND the pattern of "time code" bits from the timing control block of
circuits.
Both sets of bits (IR and time code), in combination, control the output
bits of the PLA block of circuits. PLA outputs, in turn, affect the RCL block
of circuits, and their control outputs directly operate the connections among
the registers, busses, and ALU on the other end of the chip die to actually get
the instructions' work done.
The 6502's timing control has ten states (effectively) and six explicit
output bits. Only the explicit output bits affect the PLA. The output bits are
labelled T0, T+, T2, T3, T4, and T5. The bits are considered active when their
logic states are low. There are two states where two of these explicit output
bits are active at the same time. There are also two states where none of the
explicit output bits are active. All other states have only one output bit
active at a time.
The two states with two bits active together are T0 with T+, and T0 with T2.
The two states with all explicit bits inactive are referred to as T1 and T6.
Those two states can only be distinguished within the timing control block of
circuits by paying attention to a logic node that is responsible for clearing
(making inactive) the explicit output bits T2 through T5. The clearing node
at logic high (active) corresponds to the T1 state, and low corresponds to the
T6 state. For the visual6502, this is node 1357.
The notation developed for trace/debug output, and the notation presented
hereafter in this document, lists the explicit output bits in numeric order
followed by square brackets around the non-explicit internal state of T1 or T6.
When one or more of the explicit bits is active, the square bracketed label will
be blank.
Wherever one of the explicit bits is inactive, a blank placeholder of ".."
is present for it. This also applies to the bracketed label.
For example, the T0 state is presented as:
T0 .. .. .. .. .. [..]
...and the T1 state is presented as:
.. .. .. .. .. .. [T1]
The low-profile "blank" notation of ".." assists visual examination of
trace/debug output by keeping consistent placeholders for bits when they are
inactive, with minimized visual clutter. Aligning everything in fixed positions
contributes to rapid recognition of changes.
Time codes seen around instruction execution
All instructions, with a few exceptions, always end with T0 in their time code
for the last cycle. The presence of T0 indicates, "last cycle".
The strictly 2-cycle instructions always end with the time code:
T0 .. T2 .. .. .. [..]
All other instructions end with the time code:
T0 .. .. .. .. .. [..]
The mentioned exceptions to last-cycle T0 time codes are the conditional branch
instructions. When they do not take the branch, their last cycle time code is:
.. .. T2 .. .. .. [..]
When they do take the branch, and the branch does not cross a memory page, their
last cycle time code is:
.. .. .. T3 .. .. [..]
When the branch instructions take the branch, and the branch crosses a memory
page, they end with a T0 last cycle just like all the other instructions do.
Instructions that vary in the number of cycles required to execute, other than
the conditional branch instructions, end with a T0 cycle for both the minimum
and maximum execution duration. This covers instructions that use indexed
addressing modes that require one more cycle when page crossing is required to
access the correct memory address. This situation is already covered by
statements above ("All instructions ... always end with T0..."): it has been
specifically (re)stated here for such instructions for reassurance emphasis.
For all instructions, if the previous instruction's last cycle was a cycle with
T0 in it, its opcode fetch cycle will be a time code of:
.. T+ .. .. .. .. [..]
If the previous instruction's last cycle did not have T0, its opcode fetch cycle
will be a time code of:
.. .. .. .. .. .. [T1]
Restated, instructions begin with T1 instead of T+ after a conditional branch
instruction that did not branch, or that branched without page crossing.
Instructions appear to work equally well either way. This is because a new
instruction's first actions do not begin during opcode fetch. Their earliest
effect can be only in the first half of the next cycle, T2, when the IR is set
from the predecode register.
This implies that an instruction's actions may extend as far as the second half of the opcode fetch of the next instruction, in concert with the T+ time code
bit. Not all instructions may necessarily use this: it could be an unused
constraint for some instructions.
Branch instructions definitely don't use T+ or T0 (since two cases out of three
don't even cause those time codes to arise).
In sequence, all of the possible time codes during normal instruction execution
are:
.. T+ .. .. .. .. [..] OR .. .. .. .. .. .. [T1]
.. .. T2 .. .. .. [..] OR T0 .. T2 .. .. .. [..]
.. .. .. T3 .. .. [..]
.. .. .. .. T4 .. [..]
.. .. .. .. .. T5 [..]
.. .. .. .. .. .. [T6]
T0 .. .. .. .. .. [..]
The time code:
T0 T+ .. .. .. .. [..]
arises when RES is down when a T0 F1 clock state is clocked in. This can be
either the T0 that is usually scheduled for an instruction's last cycle, or
the T0 caused by instruction abort.

View File

@ -14023,6 +14023,59 @@ function listActiveTCStates() {
return s.join("+");
}
// Show all time code node states (active and inactive) in fixed format,
// with T1/T6 indication in square brackets. ".." for a node indicates
// inactive state, "T"* for a node indicates active state.
function allTCStates()
{
var s = "";
var allHigh, thisHigh;
thisHigh = isNodeHigh( nodenames[ 'clock1' ] );
allHigh = thisHigh;
if ( !thisHigh ) s += "T0"; else s += "..";
s += " ";
// T+ in visual6502 is called T1x in
// http://www.weihenstephan.org/~michaste/pagetable/6502/6502.jpg
// Notated as T+ for compatibility with PLA node names
thisHigh = isNodeHigh( nodenames[ 'clock2' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T+"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't2' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T2"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't3' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T3"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't4' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T4"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't5' ] )
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T5"; else s += "..";
s += " [";
// If all of the time code bits are high (inactive)...
if ( allHigh ) {
// ...distinguish T1 from T6
// If bits T2 through T5 are actively being cleared...
if ( isNodeHigh( 1357 ) ) {
// ...then this is T1
s += "T1";
} else {
// ...else T2 through T5 are clear because the bits ran off the end
// of the T2 through T5 complex: this is T6
s += "T6";
}
} else {
s += "..";
}
s += "]";
return s;
}
function readBit(name){
return isNodeHigh(nodenames[name])?1:0;
}

View File

@ -304,6 +304,59 @@ function listActiveTCStates() {
return s.join("+");
}
// Show all time code node states (active and inactive) in fixed format,
// with T1/T6 indication in square brackets. ".." for a node indicates
// inactive state, "T"* for a node indicates active state.
function allTCStates()
{
var s = "";
var allHigh, thisHigh;
thisHigh = isNodeHigh( nodenames[ 'clock1' ] );
allHigh = thisHigh;
if ( !thisHigh ) s += "T0"; else s += "..";
s += " ";
// T+ in visual6502 is called T1x in
// http://www.weihenstephan.org/~michaste/pagetable/6502/6502.jpg
// Notated as T+ for compatibility with PLA node names
thisHigh = isNodeHigh( nodenames[ 'clock2' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T+"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't2' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T2"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't3' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T3"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't4' ] );
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T4"; else s += "..";
s += " ";
thisHigh = isNodeHigh( nodenames[ 't5' ] )
allHigh = allHigh && thisHigh;
if ( !thisHigh ) s += "T5"; else s += "..";
s += " [";
// If all of the time code bits are high (inactive)...
if ( allHigh ) {
// ...distinguish T1 from T6
// If bits T2 through T5 are actively being cleared...
if ( isNodeHigh( 1357 ) ) {
// ...then this is T1
s += "T1";
} else {
// ...else T2 through T5 are clear because the bits ran off the end
// of the T2 through T5 complex: this is T6
s += "T6";
}
} else {
s += "..";
}
s += "]";
return s;
}
function readBit(name){
return isNodeHigh(nodenames[name])?1:0;
}