From 27d0eb8fb2a59f70aa74fcf4c8cc806dfef83bc9 Mon Sep 17 00:00:00 2001 From: mmfoerster Date: Tue, 19 Sep 2017 20:01:47 -0400 Subject: [PATCH] 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() --- 6502timecodes.txt | 125 +++++++++++++++++++++++++++++++++++++++++++++ expert-allinone.js | 53 +++++++++++++++++++ macros.js | 53 +++++++++++++++++++ 3 files changed, 231 insertions(+) create mode 100644 6502timecodes.txt diff --git a/6502timecodes.txt b/6502timecodes.txt new file mode 100644 index 0000000..61f3f17 --- /dev/null +++ b/6502timecodes.txt @@ -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. + diff --git a/expert-allinone.js b/expert-allinone.js index 5449bbd..dc2db67 100644 --- a/expert-allinone.js +++ b/expert-allinone.js @@ -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; } diff --git a/macros.js b/macros.js index e71b8cb..bb05e01 100644 --- a/macros.js +++ b/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; }