From cdc8260db19ca06f437115d096bfa1c4e8655fd8 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Fri, 15 Mar 2013 23:17:38 -0600 Subject: [PATCH] Added NES controller code --- main.c | 124 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 93 insertions(+), 31 deletions(-) diff --git a/main.c b/main.c index 4d3ef45..1973d4c 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,8 @@ volatile bool tick = false; // Set high when clock ticks uint16_t time = 0; // Tenths of a second elapsed since boot // Clocks are in deciseconds +uint16_t score_a = 0; +uint16_t score_b = 0; uint16_t period_clock = 600 * 30; uint16_t jam_clock = 600 * 2; enum { @@ -19,22 +21,30 @@ enum { TIMEOUT } state = JAM; +uint8_t controller = 0; + #define MODE BIT0 #define SIN BIT1 #define SCLK BIT2 -#define XLAT BIT4 +#define XLAT BIT3 // Connect GSCLK to SCLK // Connect BLANK to XLAT // TRUST ME, THIS TOTALLY WORKS +#define NESCLK BIT4 +#define NESLTCH BIT5 +#define NESSOUT BIT7 + #define bit(pin, bit, on) pin = (on ? (pin | bit) : (pin & ~bit)) const uint8_t seven_segment_digits[] = { -#if 0 +#if defined(WIKIPEDIA) 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 -#else +#elseif defined(TOPDOWN) 0x7e, 0x48, 0x3d, 0x6d, 0x4b, 0x67, 0x77, 0x4c, 0x7f, 0x6f, +#else + 0x7b, 0x09, 0xb3, 0x9b, 0xc9, 0xda, 0xfa, 0x0b, 0xfb, 0xdb #endif }; @@ -76,11 +86,18 @@ write(uint8_t number) void write_num(uint16_t number, int digits) { + uint16_t divisor = 1; int i; + for (i = 1; i < digits; i += 1) { + divisor *= 10; + } + for (i = 0; i < digits; i += 1) { - write(seven_segment_digits[number % 10]); - number /= 10; + uint16_t n = (number / divisor) % 10; + + write(seven_segment_digits[n]); + divisor /= 10; } } @@ -89,8 +106,8 @@ blip() { int i; - for (i = 0; i < 1000; i += 1) { - __delay_cycles(1000); + for (i = 0; i < 12; i += 1) { + __delay_cycles(1); } } @@ -131,21 +148,77 @@ setup_dc() void draw() { - write_num(0, 2); // Score B +#if 1 + uint16_t clk; + + write_num(score_a, 3); - write_num(jam_clock % 600, 3); - write_num(jam_clock / 600, 1); + clk = ((period_clock / 10) / 60) * 100; + clk = clk + ((period_clock / 10) % 60); + write_num(clk, 4); - // XXX: Do some kind of animation if period_clock < 200 - write_num((period_clock / 10) % 60, 2); - write_num((period_clock / 10) / 60, 2); + clk = ((jam_clock / 600) % 10) * 1000; + clk = clk + (jam_clock % 600); + write_num(clk, 4); - //write_num(0, 2); // Score A + write_num(score_b, 2); +#else + int i; + + for (i = 0; i < 12; i += 1) { + write_num(sizeof(seven_segment_digits) - 1, 1); + } +#endif latch(); pulse(); } +/* + * Probe the NES controller + */ +uint8_t +nesprobe() +{ + int i; + uint8_t state = 0; + + P1OUT |= NESLTCH; + P1OUT &= ~NESLTCH; + + for (i = 0; i < 8; i += 1) { + state <<= 1; + if (P1IN & NESSOUT) { + // Button not pressed + } else { + state |= 1; + } + P1OUT |= NESCLK; + P1OUT &= ~NESCLK; + } + + return state; +} + +void +update_controller() +{ + uint8_t val = nesprobe(); + + if (val & 0x80) { + switch (state) { + case JAM: + jam_clock = 300; + state = LINEUP; + break; + default: + jam_clock = 600 * 2; + state = JAM; + break; + } + } +} + /* * Run logic for this decisecond */ @@ -160,30 +233,17 @@ loop() period_clock -= 1; } - if (P1IN & BIT3) { - switch (state) { - case JAM: - jam_clock = 300; - state = LINEUP; - break; - default: - jam_clock = 600 * 2; - state = JAM; - break; - } - } - draw(); } int main(void) { - int jiffies = 0; + uint16_t jiffies = 0; WDTCTL = WDTPW + WDTHOLD; // Disable Watchdog Timer - P1DIR |= MODE + SIN + SCLK + XLAT + BIT6; // P1 output bits - P1DIR &= ~(BIT3); + P1DIR |= MODE + SIN + SCLK + XLAT + NESCLK + NESLTCH + BIT6; // P1 output bits + P1DIR &= ~(NESSOUT); P1OUT = 0; @@ -191,7 +251,7 @@ main(void) setup_dc(); // Enable interrupts - CCTL0 |= CCIE; // Trigger interrup on A checkpoint + CCTL0 |= CCIE; // Trigger interrupt on A checkpoint TACTL = TASSEL_2 + MC_1; // Set timer A to SMCLCK, up mode TACCR0 = 0x4444; // Interrupt 60 times per second @@ -199,6 +259,8 @@ main(void) // Now actually run for (;;) { + update_controller(); + if (tick) { tick = false; jiffies += 1;