#include <REG51.H>

/* 12 MHz classic 8051: one machine cycle is 1 us. */
#define TIMER0_RELOAD_H 0xFC
#define TIMER0_RELOAD_L 0x18

volatile unsigned char millisecond_tick;
volatile unsigned char trace_count;
volatile unsigned char p0_snapshot;

void timer0_isr(void) interrupt 1
{
    TH0 = TIMER0_RELOAD_H;
    TL0 = TIMER0_RELOAD_L;
    ++millisecond_tick;
}

/* The Keil debug initialization script stops here to sample P0 and time. */
void trace_marker(void)
{
    ++trace_count;
}

static void delay_200ms(void)
{
    unsigned char start = millisecond_tick;
    while ((unsigned char)(millisecond_tick - start) < 200U) {
        ;
    }
}

void main(void)
{
    static unsigned char code pattern[8] = {
        0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F
    };
    unsigned char round;
    unsigned char step;

    TMOD = (TMOD & 0xF0) | 0x01;
    TH0 = TIMER0_RELOAD_H;
    TL0 = TIMER0_RELOAD_L;
    ET0 = 1;
    EA = 1;
    TR0 = 1;

    P0 = 0xFF;
    p0_snapshot = P0;
    trace_marker();
    for (round = 0; round < 2; ++round) {
        for (step = 0; step < 8; ++step) {
            P0 = pattern[step];
            p0_snapshot = P0;
            trace_marker();
            delay_200ms();
        }
    }
    P0 = 0xFF;
    p0_snapshot = P0;
    trace_marker();
    TR0 = 0;
    while (1) { ; }
}
