mirror of
https://github.com/trebonian/visual6502.git
synced 2025-01-02 21:30:07 +00:00
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:
parent
90f57631c0
commit
27d0eb8fb2
125
6502timecodes.txt
Normal file
125
6502timecodes.txt
Normal 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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
53
macros.js
53
macros.js
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user