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