diff --git a/animations/amphibian.c b/animations/amphibian.c index 9066d2f..4144236 100644 --- a/animations/amphibian.c +++ b/animations/amphibian.c @@ -128,31 +128,13 @@ static uint8_t amphibian_getChunk(unsigned char const nBitPlane, {0x06, 0x30, 0xC6}, {0x07, 0xF0, 0xFE}}}; + static uint8_t const nOffsetTable[] PROGMEM = + {UINT8_MAX, 0, 4, 8, 12, 8, 4, 0}; + uint8_t const nOffset = pgm_read_byte(&nOffsetTable[(nFrame >> 1) % 8]); if ((nChunkX <= 2) && (nChunkY >= 2) && (nChunkY <= 5) - && (((nFrame >> 1) % 8) != 0)) + && (nOffset != UINT8_MAX)) { - uint8_t nOffset; - switch ((nFrame >> 1) % 8) - { - case 1: - case 7: - nOffset = 0; - break; - case 2: - case 6: - nOffset = 4; - break; - case 3: - case 5: - nOffset = 8; - break; - case 4: - default: - nOffset = 12; - break; - } - return pgm_read_byte(&aEye[nBitPlane][nChunkY-2+nOffset][nChunkX]); } else diff --git a/animations/gameoflife.c b/animations/gameoflife.c index f849075..453f058 100644 --- a/animations/gameoflife.c +++ b/animations/gameoflife.c @@ -106,7 +106,7 @@ typedef uint8_t field_t[FIELD_YSIZE][FIELD_XSIZE]; /******************************************************************************/ -void setcell(field_t pf, coord_t x, coord_t y, cell_t value) { +static void setcell(field_t pf, coord_t x, coord_t y, cell_t value) { if (value != dead) { pf[y][x / 8] |= shl_table[x & 7]; } else { @@ -144,25 +144,23 @@ void nextiteration(field_t dest, field_t src) { uint8_t tc; for (y = YSIZE; y--;) { for (x = XSIZE; x--;) { + cell_t cell; tc = countsurroundingalive(src, x, y); switch (tc) { -// case 0: -// case 1: -// /* dead */ -// setcell(dest, x,y, dead); case 2: /* keep */ - setcell(dest, x, y, getcell(src, x, y)); + continue; break; case 3: /* alive */ - setcell(dest, x, y, alive); + cell = alive; break; default: /* dead */ - setcell(dest, x, y, dead); + cell = dead; break; } + setcell(dest, x, y, cell); } } } diff --git a/borg_hw/borg_hw.h b/borg_hw/borg_hw.h index a7837d1..65c4348 100644 --- a/borg_hw/borg_hw.h +++ b/borg_hw/borg_hw.h @@ -1,8 +1,7 @@ #ifndef BORG_HW_H #define BORG_HW_H -//Linebytes gibt die Zahl der Bytes pro Zeile in der -//Pixmap an, also Spaltenzahl/8 aufgerundet +// LINEBYTES holds the amount of bytes per line within the framebuffer (pixmap) #define LINEBYTES (((NUM_COLS-1)/8)+1) diff --git a/borg_hw/borg_hw_andreborg.c b/borg_hw/borg_hw_andreborg.c index 8dccf3b..8df9963 100644 --- a/borg_hw/borg_hw_andreborg.c +++ b/borg_hw/borg_hw_andreborg.c @@ -1,4 +1,3 @@ - #include "../config.h" #include "../makros.h" @@ -8,25 +7,27 @@ #include "borg_hw.h" /* -// Diese #defines werden nun durch menuconfig gesetzt + // those macros get defined via menuconfig, now -// 16 Spalten insgesamt direkt gesteuert, dafür 2 Ports -#define COLPORT1 PORTA -#define COLDDR1 DDRA + // 16 columns total directly controlled, therefore 2 ports + #define COLPORT1 PORTA + #define COLDDR1 DDRA -#define COLPORT2 PORTC -#define COLDDR2 DDRC + #define COLPORT2 PORTC + #define COLDDR2 DDRC -// Der andere Port übernimmt die Steuerung der Schieberegister -#define ROWPORT PORTD -#define ROWDDR DDRD -// Clock und reset gehen gemeinsam an beide Schieberegister -// der reset pin ist negiert -#define PIN_MCLR PD4 -#define PIN_CLK PD5 -//das dier sind die individuellen Dateneingänge für die Schieberegister -#define PIN_DATA1 PD6 -#define PIN_DATA2 PD7 + // the other port controls the shift registers + #define ROWPORT PORTD + #define ROWDDR DDRD + + // both clock and reset are connected to each shift register + // reset pin is negated + #define PIN_MCLR PD4 + #define PIN_CLK PD5 + + // these are the individual data input pins for the shift registers + #define PIN_DATA1 PD6 + #define PIN_DATA2 PD7 */ #define COLDDR1 DDR(COLPORT1) @@ -39,90 +40,80 @@ #define SIG_OUTPUT_COMPARE0 SIG_OUTPUT_COMPARE0A #endif - -//Der Puffer, in dem das aktuelle Bild gespeichert wird +// buffer which holds the currently shown frame unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; - -//Eine Zeile anzeigen -inline void rowshow(unsigned char row, unsigned char plane){ - //Die Zustände von der vorherigen Zeile löschen +// display a row +static void rowshow(unsigned char row, unsigned char plane) { + //reset states of preceding row COLPORT1 = 0; COLPORT2 = 0; - - //kurze Warteschleife, damit die Treiber auch wirklich ausschalten + + // short delay loop, to ensure proper deactivation of the drivers unsigned char i; - for(i=0;i<20;i++){ + for (i = 0; i < 20; i++) { asm volatile("nop"); } - - - if (row == 0){ - //Zeile 0: Das erste Schieberegister initialisieren - ROWPORT&= ~(1<>1) + ((row & 0x01)?8:0 ); - tmp = pixmap[plane][row][0]; + tmp = pixmap[plane][row][0]; tmp1 = pixmap[plane][row][1]; #endif #ifdef REVERSE_COLS @@ -124,44 +112,43 @@ inline void rowshow(unsigned char row, unsigned char plane){ #else #ifdef INTERLACED_COLS static uint8_t interlace_table[16] = { - 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 + 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, + 0x50, 0x51, 0x54, 0x55 }; - COLPORT1 = interlace_table[tmp&0x0f] | (interlace_table[tmp1&0x0f]<<1); + COLPORT1 = interlace_table[tmp&0x0f] | (interlace_table[tmp1&0x0f]<<1); tmp>>=4; tmp1>>=4; - COLPORT2 = interlace_table[tmp] | (interlace_table[tmp1]<<1); + COLPORT2 = interlace_table[tmp] | (interlace_table[tmp1]<<1); #else COLPORT1 = tmp; COLPORT2 = tmp1; #endif #endif - + } - -//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt -SIGNAL(SIG_OUTPUT_COMPARE0) -{ +// depending on the plane this interrupt triggers at 50 kHz, 31.25 kHz or +// 12.5 kHz +SIGNAL(SIG_OUTPUT_COMPARE0) { static unsigned char plane = 0; static unsigned char row = 0; - - //Watchdog zurücksetzen + + // reset watchdog wdt_reset(); - - //Zeile und Ebene inkrementieren - if(++plane==NUMPLANE){ - plane=0; - if(++row == NUM_ROWS){ + + // increment both row and plane + if (++plane == NUMPLANE) { + plane = 0; + if (++row == NUM_ROWS) { row = 0; } nextrow(row); } - - //Die aktuelle Zeile in der aktuellen Ebene ausgeben + + // output current row according to current plane rowshow(row, plane); } - -void timer0_off(){ +void timer0_off() { cli(); COLPORT1 = 0; @@ -169,60 +156,59 @@ void timer0_off(){ ROWPORT = 0; #ifdef __AVR_ATmega644P__ - TCCR0A = 0x00; - TCCR0B = 0x00; + TCCR0A = 0x00; + TCCR0B = 0x00; #else - + TCCR0 = 0x00; #endif sei(); } +// initialize timer which triggers the interrupt +static void timer0_on() { + /* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 + CS02 CS01 CS00 + 0 0 0 stop + 0 0 1 clk + 0 1 0 clk/8 + 0 1 1 clk/64 + 1 0 0 clk/256 + 1 0 1 clk/1024 + */ -// Den Timer, der denn Interrupt auslöst, initialisieren -void timer0_on(){ -/* TCCR0: FOC0 WGM00 COM01 COM00 WGM01 CS02 CS01 CS00 - CS02 CS01 CS00 - 0 0 0 stop - 0 0 1 clk - 0 1 0 clk/8 - 0 1 1 clk/64 - 1 0 0 clk/256 - 1 0 1 clk/1024 - -*/ #ifdef __AVR_ATmega644P__ - TCCR0A = 0x02; // CTC Mode - TCCR0B = 0x04; // clk/256 - TCNT0 = 0; // reset timer - OCR0 = 20; // Compare with this value - TIMSK0 = 0x02; // Compare match Interrupt on + TCCR0A = 0x02; // CTC Mode + TCCR0B = 0x04; // clk/256 + TCNT0 = 0; // reset timer + OCR0 = 20; // compare with this value + TIMSK0 = 0x02; // compare match Interrupt on #else - TCCR0 = 0x0C; // CTC Mode, clk/256 - TCNT0 = 0; // reset timer - OCR0 = 20; // Compare with this value - TIMSK = 0x02; // Compare match Interrupt on + TCCR0 = 0x0C; // CTC Mode, clk/256 + TCNT0 = 0; // reset timer + OCR0 = 20; // compare with this value + TIMSK = 0x02; // compare match Interrupt on #endif } -void borg_hw_init(){ - //Spalten Ports auf Ausgang +void borg_hw_init() { + // switch column ports to output mode COLDDR1 = 0xFF; COLDDR2 = 0xFF; - - //Pins am Zeilenport auf Ausgang - ROWDDR = (1<>=1; - COLPORT &= ~(1<>= 1; + COLPORT &= ~(1 << PIN_CLK); + COLPORT |= (1 << PIN_CLK); } } - - COLPORT &= ~(1<>row; - - // if (row==4) - { - MYPORT &= ~(1 << PIN_ENABLE) ; - //MYPORT |= (1 << PIN_ENABLE) ; //hide - // MYPORT |= (1 << PIN_ENABLE) ; //hide - for (n=7;n<8;n--) - { - outb = pixmap[plane][row][n]; - p=0x80; - for (m=0;m<8;m++) - { - if (outb & p) - // MYPORT |= (1 << PIN_DATA); - MYPORT &= ~(1 << PIN_DATA) ; - else - // MYPORT &= ~(1 << PIN_DATA) ; //off - MYPORT |= (1 << PIN_DATA); - - MYPORT2 &= ~clkmsk ; - MYPORT2 |= clkmsk ; + clkmsk = 0x80 >> row; - p>>=1; + // if (row==4) + { + MYPORT &= ~(1 << PIN_ENABLE); + // MYPORT |= (1 << PIN_ENABLE); //hide + // MYPORT |= (1 << PIN_ENABLE); //hide + for (n = 7; n < 8; n--) { + outb = pixmap[plane][row][n]; + p = 0x80; + for (m = 0; m < 8; m++) { + if (outb & p) + // MYPORT |= (1 << PIN_DATA); + MYPORT &= ~(1 << PIN_DATA); + else + // MYPORT &= ~(1 << PIN_DATA); //off + MYPORT |= (1 << PIN_DATA); - } - } - } - MYPORT |= (1 << PIN_ENABLE) ; // - //MYPORT &= ~(1 << PIN_ENABLE) ; - // for(n=0;n<250;n++) asm ("nop"); - + MYPORT2 &= ~clkmsk; + MYPORT2 |= clkmsk; + p >>= 1; + + } + } + } + MYPORT |= (1 << PIN_ENABLE); + //MYPORT &= ~(1 << PIN_ENABLE) ; + // for(n=0;n<250;n++) asm ("nop"); } -SIGNAL(SIG_OUTPUT_COMPARE0) -{ - static unsigned char plane = 0; - unsigned char row = 0; +SIGNAL( SIG_OUTPUT_COMPARE0) { + static unsigned char plane = 0; + unsigned char row = 0; - switch (plane){ - case 0: - OCR0 = 60; - break; - case 1: - OCR0 = 120; - break; - case 2: - OCR0 = 160; - break; - // case 3: - // OCR0 = 24; - // break; - // case 4: - // OCR0 = 48; - // break; - } - - for(row=0;row #include #include #include "borg_hw.h" -/* Steckerbelegung Flachbandkabel am Panel - * (die Nummerierung ist in wirklichkeit umgekehrt) + +/* pinout of the ribbon cable connected to the panel + * (the numbering is actually upside down) * * 1-3 GND - * 4 +5V für Logic + * 4 +5V for logic * 5-8 +12V * 9-10 GND * 11 CP3 @@ -21,7 +21,7 @@ * 17-18 GND * 19-26 D0-D7 * - * Und nochmal richtigrum: + * and now the right way round: * 1 D7 * 2 D6 * 3 D5 @@ -49,22 +49,20 @@ * 25 GND * 26 GND * - * Es werden 4 40374 Latches benutzt. Nr. 1,2 und 4 treiben vom Datenbus - * in Richtung Panel, Nr. 3 treibt von den Tastenausgängen auf den Datenbus. - * Die EOs von 1,2 und 4 liegen fest auf GND. + * Four 40374 latches are used. No. 1, 2 and 4 drive from the data bus to the + * panel, no. 3 drives from the button outputs to the data bus. The EOs of + * 1, 2 and 4 are hardwired to GND. * - * Die LEDs sind in einer 12*16 Matrix angeordnet - * Die Werte für die LED spalten Werden mit CP1 und CP2 in die - * Latches übernommen (insgesammt 16 Spalten) - * Die Nummer der Zeile wird beim löschen von /show übernommen. + * The LEDs are aligned to a 12*16 matrix. The values for the LED columns are + * passed to the latches via CP1 und CP2 (16 columns total). The index of the + * row is passed during the deletion of "/show". * - * Die Tasten sind in einer 8*8 Matrix angeordnet. - * Über Latch 4 werden die Zeilen einzeln auf high gesetzt, über - * Latch 3 können dann die Spalten gelesen werden. - * + * The buttons are aligned to an 8*8 matrix. The rows get separately set to + * "high" via latch 4. The columns can then be read via latch 3. */ -//Datenport für das Panel + +// data port for the panel #define COLPORT PORTC #define COLDDR DDRC #define COLPIN PINC @@ -72,7 +70,7 @@ #define CTRLPORT PORTD #define CTRLDDR DDRD -// PINs on CTRLPORT +// pins on CTRLPORT #define PIN_EO3 PD7 #define PIN_CP4 PD2 #define PIN_SHOW PD3 @@ -80,84 +78,88 @@ #define PIN_CP2 PD5 #define PIN_CP3 PD6 -//Der Puffer, in dem das aktuelle Bild gespeichert wird + +// buffer which holds the currently shown frame unsigned char pixmap[NUMPLANE][NUM_ROWS][LINEBYTES]; volatile uint8_t keys[8]; + inline void busywait() { //unsigned char i; - //for(i=0;i<20;i++){ + //for(i=0; i < 20; i++){ // asm volatile("nop"); //} } -//Eine Zeile anzeigen +// display a row inline void rowshow(unsigned char row, unsigned char plane){ - CTRLPORT |= (1<>1) + ((row & 0x01)?8:0 ); - tmp = pixmap[plane][row][0]; + tmp = pixmap[plane][row][0]; tmp1 = pixmap[plane][row][1]; #endif #ifdef REVERSE_COLS @@ -123,7 +122,8 @@ inline void rowshow(unsigned char row, unsigned char plane){ #else #ifdef INTERLACED_COLS static uint8_t interlace_table[16] = { - 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 + 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, + 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 }; //COLPORT1 = interlace_table[tmp&0x0f] | (interlace_table[tmp1&0x0f]<<1); tmp>>=4; tmp1>>=4; @@ -133,147 +133,142 @@ inline void rowshow(unsigned char row, unsigned char plane){ //COLPORT2 = tmp1; pd1165_write(row, tmp); - #endif -#endif - +#endif } */ -//Dieser Interrupt wird je nach Ebene mit 50kHz 31,25kHz oder 12,5kHz ausgeführt -SIGNAL(SIG_OUTPUT_COMPARE0) -{ + +// depending on the plane this interrupt gets triggered at 50 kHz, 31.25 kHz or +// 12.5 kHz +SIGNAL(SIG_OUTPUT_COMPARE0) { static unsigned char plane = 0; unsigned char row = 0; - - //Watchdog zurücksetzen + + // reset watchdog wdt_reset(); - - //Tasten für joystick einlesen + + // determine button status of the joystick readButtons(); - for(row=0; row < 8; row++){ + for (row = 0; row < 8; row++) { pd1165_write(row, pixmap[plane][row][0]); - CTRLPORT &= ~((1< (64ul * 256ul * 64ul)){ + +ISR(INT0_vect) { + if (akku > (64ul * 256ul * 64ul)) { akku -= OCR1A - TCNT1; - + mod = akku / 64; akku = 0; row = 0; @@ -72,32 +71,31 @@ ISR(INT0_vect){ } -void timer0_off(){ +void timer0_off() { cli(); - TCCR1B = 0x00; - sei(); } -// Den Timer, der denn Interrupt auslöst, initialisieren -void timer1_on(){ - TCCR1B = 1; //clk/1 - TIMSK |= (1<nLines += nLines; pStdVariant->nLevel = ((pStdVariant->nLines / 10) < TETRIS_INPUT_LEVELS) ? (pStdVariant->nLines / 10) : (TETRIS_INPUT_LEVELS - 1); - switch (nLines) - { - case 1: - pStdVariant->nScore += 50; - break; - case 2: - pStdVariant->nScore += 150; - break; - case 3: - pStdVariant->nScore += 250; - break; - case 4: - pStdVariant->nScore += 400; - break; - } + static uint16_t const nScoreTable[] PROGMEM = {0, 50, 150, 250, 400}; + pStdVariant->nScore += pgm_read_word(&nScoreTable[nLines]); }