16) Timer control
The Timer control block is located North of the DB3, DB4 drivers/buffers,
East from the Timer block.
Also, we have a little bit of logic for Timer Interrupt flag and PB7 IRQ generation West from the Timer block,
which technically also belongs to the Timer control block.
;---
Address decoding:
To make things simple:
We have three NOR gates, which generate three high_active control signals when PHI1 is low
(what is different from "PHI2 is high") AND when IO is selected AND when A2i is high.
R_TMR (read Timer) when A0i is low AND W/R# is low (read).
R_IRQ (read Timer underflow Interrupt flag) when A0i is high AND W/R# is low (read).
W_TMR (write timer) when W/R# is high (write). //Note: A0i doesn't matter here.
R_TMR and W_TMR are switched to GND by FETs during PHI1:
For R_TMR, one FET located West from the Timer block.
For W_TMR, one FET located West from the Timer block, and another FET located in prescaler counter Bit 0.
;---
Predivider control:
We have a predivider, basically a ten Bit down counter running at PHI2_in speed,
which is cleared when writing the Timer by W_TMR.
//Predivider counter Bits change with PHI2.
We have three latches for the prescaler factor, written with W_TMR.
Depending on A0i and A1i, only one of the latches can be set to 1, default is 0.
00: PRE1=1, PRE8=0, PRE64=0. No predivider, Timer is running at PHI2_in speed.
01: PRE1=0, PRE8=1, PRE64=0. Predivider factor 8, Timer is running at PHI2_in/8.
10: PRE1=0, PRE8=0, PRE64=1. Predivider factor 64, Timer is running at PHI2_in/64.
11: PRE1=0, PRE8=0, PRE64=0. Predivider factor 1024, Timer is running at PHI2_in/1024.
Active predivider counter Bits:
Three when PRE8=1.
Six when PRE64=1.
Else, all of the ten predivider Bits are active.
In the predivider block, we have a ten input NOR gate which generates the IS0 signal.
If IS0 is high, all of the active predivider counter Bits are zero. //I'm simplifying things a bit here.
;----
Timer control:
We have a Timer, basically an eight Bit down counter,
read with R_TMR, written with W_TMR,
Timer Bits change with PHI2.
The low_active CEN# signal enables Timer counting.
If PRE1 is high, CEN# always is active, and the Timer is running at PHI2_in speed.
;
IS0 is sampled with a transparent latch at PHI1,
means that if IS0 was high in the previous PHI2_in cycle, CEN# is active for the current PHI2_in cycle.
;
If the Interrupt flag is set, CEN# is active: the timer is running at full speed.
;
W_TMR also puts CEN# active, and I don't know why,
because the Timer counter circuity ignores CEN# when W_TMR is active.
The Timer uses a carry lookahead mechanism for the lower 5 Bits,
that's why we have that Tcin5 signal, we are getting there later in "18) Timer".
;---
Timer underflow Interrupt flag and IRQ generation:
6530 Interrupt flag basically is a RS flipflop built from two NOR gates.
Timer Bit 7 carry output TC# (low_active, signaling Timer underflow, changes with PHI2) is sampled with a transparent latch during PHI1.
TC# is active, when the (decrementing) Timer is at $00 in the current PHI2_in cycle (and will roll over to $FF in the next time).
If TC# was active in the previous PHI2_in cycle, the latch output does set the 6530 Interrupt flag (through an inverter)
during PHI1 in the current PHI2_in cycle.
We have another transparent latch, which samples the Interrupt flag during PHI2.
If the output of that latch is active, three things will happen:
;
CEN# is active, the Timer counts a step during the current PHI2_in cycle.
;
If the PB7 IRQ output is not disabled, AND RESET is not active,
the IRQ signal goes active during PHI2 of the current PHI2_cycle and tells the PB7 driver to pull PB7 to GND.
//If PB7 is tied to the IRQ# input of the 6502, this signals a 6530 Timer underflow IRQ# to the 6502.
;
When the Interrupt flag is read by R_IRQ during PHI2, read data bus D7r# is pulled low,
means the 6502 sees DB7 '1' what indicates that the 6530 Interrupt flag is set.
//read data bus D0..7r# lines which are not pulled to GND during PHI2 give us '0' on DB0..7.
//That's why DB0..6 are '0' when reading the Interrupt flag.
The Interrupt flag is cleared in the current PHI2_in cycle by reading/writing the Timer (if R_TMR OR W_TMR goes high).
;---
Now for the last part: disabling PB7 IRQ.
We have a latch which samples A3i# during Timer reads (R_TMR=high) OR Timer writes (W_TMR=high).
The output of that latch gives us the signal IRQ_DISABLE.
If IRQ_DISABLE is high, IRQ is disabled, and the Timer Interrupt flag won't cause that PB7 is pulled low.
When reading/writing the Timer,
A3i=0 disables and A3i=1 enables PB7 IRQ generation during PHI2 in the current PHI2_in cycle.
Also, the Interrupt flag is cleared in the current PHI2_in cycle.
Note, that the PB7 IRQ generation ignores the PRB7 and DDRB7 IO register Bits.
Also note, that RESET does not affect the 6530 Interrupt flag, Timer, prescaler, and prescaler factor.
RES makes sure that PB7 is not pulled low by IRQ while RES is active.
RES also sets the latch for the PB7 interrupt generation to "disabled".
But if there is something like an accidental Timer read during the RESET sequence of a 6502,
A3i could enable PB7 interrupt generation, and then there might be a falling edge on PB7 in the wrong moment...
If PB7 is tied to IRQ# of the 6502, there is no problem, because the 6502 does not mind an active IRQ# during its RESET sequence.
If PB7 is tied to NMI# of the 6502, there is a problem, because a falling edge on #NMI in the wrong time might disrupt the 6502 RESET sequence.
And that the RES# input of the 6530 is not synchronized with a clock actually makes things worse, because the 6502 _does_ synchronize its RES# input with a clock.
For more info, please read
Rockwell 6532 timer interrupt precautions.
Attachment:
si6530_16_timer_control.png [ 187.01 KiB | Viewed 657 times ]
Attachment:
6530_16_timer_control.png [ 327.86 KiB | Viewed 657 times ]