Final Project of "AVR: Architecture, Assembly & Reverse Engineering" HackADayU Course
Not a member? You should Sign up.
Already have an account? Log in.
To make the experience fit your profile, pick a username and tell us what interests you.
Wokwi Arduino Simulator
#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); }
View all 2 project logs
Create an account to leave a comment. Already have an account? Log In.
Radek
Aswinth Raj
Big Boy Pete
zvodd
Become a member to follow this project and never miss any updates
By using our website and services, you expressly agree to the placement of our performance, functionality, and advertising cookies. Learn More
Yes, delete it Cancel
You are about to report the project "AVR Pong in Assembly", please tell us the reason.
Your application has been submitted.
Are you sure you want to remove yourself as a member for this project?
Project owner will be notified upon removal.