You could use an PIC or AVR microcontroller too, if you want to go that route.
CD4028 is a 1-of-10 decoder, and I'm just using it because I'm lazy to decode with gates.
CD4029 is a 4-bit counter that I'm just using 2 bits of, and letting it overflow because it doesn't matter.
I'm sure you can find some acceptable substitutes if needed. Or a microcontroller such as AVR90S2313/TINY2313. I think I tried to not use any "weird" stuff so it should be easily generalized to most compilers, or assembled by hand:
volatile u08 a=0;
SIGNAL(SIG_INTERRUPT0) {
a=a+1;
if(a>3) a=0;
}
main()
{
u08 junk;
u08 loop;
DDRB=0x3f; /* using portb[0:3] for LEDs, portb[4:5] for bank sel */
DDRD=~_BV(PIND2); GIMSK=_BV(INT0); /* setup interrupt input */
MCUCR |= _BV(ISC01) | _BV(ISC00); /* setup interrupt on rising edge */
sei(); /* enable interrupts */
while(1) {
junk=1;
for(loop=0; loop<a; loop++) { /* calculate decoded value, yes leftshift by value would be simpler but I dont think most :mu:C's have arbitrary shift operators */
junk=junk+junk; /* or *2, or leftshift 1, but all mcu's have add */
}
junk=junk |(a<<4); /* we still need encoded value, ok I cheated here, but this time it's a static value */
PORTB=junk; /* output it now! */
}
}
Then use INT0 to the pushbutton circuit, hook up any old crystal to it, and use the 4 low bits of PORTB as your LED drivers, and bits 5:4 as your transistor drivers. There, one chip microcontroller solution.
Of course I can't debug this code so I don't know if this really works