Final Project of "AVR: Architecture, Assembly & Reverse Engineering" HackADayU Course
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
#define __SFR_OFFSET 0 #include "avr/io.h" .global main .data frame_segment_1: .space 8 frame_segment_2: .space 8 .text spi_transfer: out SPDR, r24 1: in r0, SPSR sbrs r0, SPIF rjmp 1b ret delay_ms: ldi r26, 4000 & 0xFF ldi r27, 4000 >> 8 1: sbiw r26, 1 brne 1b sbiw 24, 1 brne delay_ms ret clear_frame: ldi ZL, lo8(frame_segment_1) ldi ZH, hi8(frame_segment_1) ldi YL, lo8(frame_segment_2) ldi YH, hi8(frame_segment_2) ldi r18, 8 ldi r19, 0x00 1: st Z+, r19 st Y+, r19 dec r18 brne 1b ret draw_frame: ldi r18, 1 ldi ZL, lo8(frame_segment_1) ldi ZH, hi8(frame_segment_1) ldi YL, lo8(frame_segment_2) ldi YH, hi8(frame_segment_2) 1: ; Enable SPI CS ldi r19, 0x00 out PORTB, r19 mov r24, r18 rcall spi_transfer ld r24, Z+ rcall spi_transfer mov r24, r18 rcall spi_transfer ld r24, Y+ rcall spi_transfer ; Disable SPI CS ldi r19, 0x04 out PORTB, r19 inc r18 cp r18, 8 brne 1b ret update_player_paddle: sbis PIND, 7 dec r4 ; Move up sbis PIND, 6 inc r4 ; Move down ; if py < 1, py = 1 mov r18, r4 cpi r18, 1 brsh 2f ldi r18, 1 mov r4, r18 brsh 1f 2: ; if py >= 7, py = 6 mov r18, r4 cpi r18, 6 brlo 1f ldi r18, 6 mov r4, r18 1: ret main: ; Initialize SPI ldi r18, 0x50 out SPCR, r18 ; Configure SPI CS pin (PB2) ldi r18, 0x04 out DDRB, r18 ldi r18, 0x04 out PORTB, r18 ; Configure pins PD6 and PD7 ldi r18, 0x00 out DDRD, r18 ldi r18, 0xFF out PORTD, r18 ; Initialize variable ldi r18, 1 mov r2, r18 ; Ball x ldi r18, 3 mov r3, r18 ; Ball y ldi r18, 3 mov r4, r18 ; Player paddle (py) ldi r18, 3 mov r5, r18 ; Computer paddle (cy) ldi r18, -1 mov r6, r18 ; Ball velocity (dx) ldi r18, 1 mov r7, r18 ; Ball velocity (dy) loop: ; if y == 1, dy = 1 mov r18, r3 cpi r18, 1 brne 1f ldi r19, 1 mov r7, r19 1: ; if y == 8, dy = -1 cpi r18, 8 brne 2f ldi r19, -1 mov r7, r19 2: ; if x == 1, dx = 1 mov r18, r2 cpi r18, 1 brne 1f ldi r19, 1 mov r6, r19 1: ; if x == 14, dx = -1 cpi r18, 14 brne 2f ldi r19, -1 mov r6, r19 2: ; y += dy add r3, r7 ; x += dx add r2, r6 ; Computer Paddle AI ; if x >= 8, cy = y mov r18, r2 cpi r18, 8 brlo 1f mov r5, r3 ; if cy < 1, cy = 1 mov r18, r5 cpi r18, 1 brsh 2f ldi r18, 1 mov r5, r18 brsh 1f 2: ; if cy >= 7, cy = 6 mov r18, r5 cpi r18, 6 brlo 1f ldi r18, 6 mov r5, r18 1: call clear_frame ;; Ball mov r18, r2 cpi r18, 8 brsh 1f ; frame_segment_1 ldi ZL, lo8(frame_segment_1) ldi ZH, hi8(frame_segment_1) mov r19, r2 inc r19 ldi r20, 0x00 bset 0 3: rol r20 bclr 0 dec r19 brne 3b jmp 2f 1: ; frame_segment_2 ldi ZL, lo8(frame_segment_2) ldi ZH, hi8(frame_segment_2) mov r19, r2 subi r19, 7 ldi r20, 0x00 bset 0 3: rol r20 bclr 0 dec r19 brne 3b 2: add ZL, r3 adc ZH, r1 st -Z, r20 ;; Player Paddle ldi ZL, lo8(frame_segment_1) ldi ZH, hi8(frame_segment_1) add ZL, r4 adc ZH, r1 ld r20, -Z ori r20, 0x01 st Z+, r20 ld r20, Z ori r20, 0x01 st Z+, r20 ld r20, Z ori r20, 0x01 st Z, r20 ;; Computer Paddle ldi ZL, lo8(frame_segment_2) ldi ZH, hi8(frame_segment_2) add ZL, r5 adc ZH, r1 ld r20, -Z ori r20, 0x80 st Z+, r20 ld r20, Z ori r20, 0x80 st Z+, r20 ld r20, Z ori r20, 0x80 st Z, r20 call draw_frame call update_player_paddle ; Delay ldi r24, 100 call delay_ms call update_player_paddle ; Delay ldi r24, 100 call delay_ms ;; if (x == 1) and ((y < py) or (y >= py+3)), GAME OVER! mov r18, r2 cpi r18, 1 brne 1f cp r3, r4 brsh 2f jmp 3f 2: mov r18, r4 inc r18 inc r18 inc r18 cp r3, r18 brlo 1f 3: jmp 3b 1: ;; jmp loop jmp main
uint8_t frame[8][2]; /* x : +ve right ; columns ; (0,15) * y : +ve down ; rows ; (1,8)*/ int8_t x=1, y=3, py=3, cy=3, dx=-1, dy=1; void spi_transfer(uint8_t data) { SPDR = data; while(!bitRead(SPSR, SPIF)); } void draw_frame() { for (int row=1; row<=8; row++) { /* Enable CS */ bitClear(PORTB, 2); spi_transfer(row); spi_transfer(frame[row-1][0]); spi_transfer(row); spi_transfer(frame[row-1][1]); /* Disable CS */ bitSet(PORTB, 2); } } void clear_frame() { for (int row=1; row<=8; row++) { frame[row-1][0] = frame[row-1][1] = 0x00; } draw_frame(); } void setup() { /* Initialize SPI */ bitSet(SPCR, SPE); /* SPI Enable */ bitSet(SPCR, MSTR); /* Master */ /* Configure SPI CS pin (PB2) */ bitSet(DDRB, 2); bitSet(PORTB, 2); /* Configure pin change interrupt on pins PD6 (PCINT22) and PD7 (PCINT23) */ DDRD = 0x00; /* Configure pins as input */ PORTD = 0xFF; /* Enable pull up resistors */ bitSet(PCICR, PCIE2); /* Enable PCINT[23:16] */ bitSet(PCMSK2, PCINT22); /* Unmask pin change interrupt on PD6*/ bitSet(PCMSK2, PCINT23); /* Unmask pin change interrupt on PD7 */ /* Timer 1 Configuration */ TCCR1A = 0x00; /* Normal operation */ TCCR1B = 0x00; /* f1 = f_clk/64 = 16M/64 */ /* T1 = 64/16 us = 4 us */ bitSet(TCCR1B, CS10); /* 64 prescaler */ bitSet(TCCR1B, CS11); } void update_player_paddle() { if (!bitRead(PIND, 7)) /* Paddle up */ py -= 1; if (!bitRead(PIND, 6)) /* Paddle down */ py += 1; if (py < 1) py = 1; if (py > 6) py = 6; } ISR(PCINT2_vect) { /* Push button debouncing */ /* 50 ms = 50,000 us, Count = 50,000/4 = 12,500 */ TCNT1 = 53035; /* 65535 - 12,500 */ bitSet(TIMSK1, TOIE1); /* Enable overflow interrupt */ } ISR(TIMER1_OVF_vect) { update_player_paddle(); bitClear(TIMSK1, TOIE1); /* Disable overflow interrupt */ } uint8_t count = 0; void loop() { if (x==1) { if ((y < py) || (y > py+2)) { /* "GAME OVER!" */ while(1); } } clear_frame(); if (y==1) dy=1; else if (y==8) dy=-1; if (x==1) dx=1; else if (x==14) dx=-1; y = y + dy; x = x + dx; /* Computer Paddle AI */ if (x > 7) cy = y; if (cy < 1) cy = 1; if (cy > 6) cy = 6; /* Ball */ bitSet(frame[y-1][x/8], x%8); /* Player Paddle */ bitSet(frame[py-1][0], 0); bitSet(frame[py][0], 0); bitSet(frame[py+1][0], 0); /* Computer Paddle*/ bitSet(frame[cy-1][1], 7); bitSet(frame[cy][1], 7); bitSet(frame[cy+1][1], 7); draw_frame(); // update_player_paddle(); delay(100); // update_player_paddle(); delay(100); }
Create an account to leave a comment. Already have an account? Log In.
Become a member to follow this project and never miss any updates