The T-State Counter was a quick and dirty hardware interface made out of parts lying around. It was made as an aid to measure the number of T-States a single or multiple instructions takes.
The board consists of a 74LS393 (Dual 4-bit binary counter) and a 74HCT574 (Octal D-type flip-flop) and a single 100nF capacitor. Later on a 3mm LED and 330 Ohm resistor where added for testing the XMEM signal and a CD audio connector was also added for testing CD audio playback through SAM.
The circuit is pretty simple and I didn't bother to make a schematic at the time. But here's a discription on how it's wired:
The two 4-bit counters of the 74LS393 are daisy changed into a single 8-bit counter (pin 8 connected to pin 1) and is clocked directly by the SAMs 6MHz CPU clock (CPU CLK to pin 13) so Each Z80 clock pulse (a T-State) the counter gets increased by one and after it has reached it's maximum value of 255 it rolls over to 0. The counters reset function is not used (pin 2 and pin 12 connected to GND).
The counters outputs are always active and can't be connected to the SAMs data bus directly. So the counters outputs are connected to the 74HCT74 data inputs instead. The 74HCT574 data ouputs are connected to SAMs data bus.
The CPU clock is also connected to the 74HCT574 clock input (CPU CLK to pin 11) so on each CPU pulse the counters value is clocked into 74HCT574.
For SAM to read out the counter, a very simplistic address decoder is used. SAMs PRINTL signal is connected to the 74HCT574 output enable (pin 1) and that's it. So whenever any of the printer ports are accessed the counter value is put on the SAMs databus and can be read.
To determine how many T-states an instruction or some short code takes, the counter is read right before the test instruction or test code and read again right after execution of that. Substracting the first value from the second will report the number of T-states it took.
Below some example assembly code. Execute using PRINT USR 3e4 to print the number of T-states the code takes.
HALT ;wait until in border area
DI ;disable interrupts
IN A,(&E8) ;read T-state counter
LD E,A ;and save it
;-- start ------
IN A,(&F8) ;12
IN A,(&F8) ;12
;-- end --------
IN A,(&E8) ;read T-state counter again
SUB E ;get difference
JR NC,$+4 ;jr no overvlow
NEG ;get positive difference
SUB 4+12 ;correction for IN and LD instruction
LD B,0 ;store in BC for basic
EI ;enable interrupts