.include "riscmcu.inc"
|
.include "riscmcu.inc"
|
|
|
.def temp = r16
|
.def temp = r16
|
.def times = r17
|
.def times = r17
|
.def num = r18
|
.def num = r18
|
.def stack = r19
|
.def stack = r19
|
.def counter = r20
|
.def counter = r20
|
.def life = r22
|
.def life = r22
|
.def level = r23
|
.def level = r23
|
.def temp2 = r24
|
.def temp2 = r24
|
|
|
.cseg
|
.cseg
|
rjmp reset
|
rjmp reset
|
reti
|
reti
|
reti
|
reti
|
|
|
reset:
|
reset:
|
ldi counter,5
|
ldi counter,5
|
|
|
ser temp
|
ser temp
|
out ddrb,temp ; Port B direction as OUTPUT
|
out ddrb,temp ; Port B direction as OUTPUT
|
out ddrd,temp ; Port D direction as OUTPUT
|
out ddrd,temp ; Port D direction as OUTPUT
|
out portc,temp
|
out portc,temp
|
out portd,temp
|
out portd,temp
|
|
|
ldi temp,1
|
ldi temp,1
|
out tccr0,temp ; set clock as timer clock source
|
out tccr0,temp ; set clock as timer clock source
|
ldi temp,$0F
|
ldi temp,$0F
|
out ddrc,temp ; PinC[3..0] output, [7..4] input
|
out ddrc,temp ; PinC[3..0] output, [7..4] input
|
|
|
start:
|
start:
|
ldi life,3
|
ldi life,3
|
ldi level,1
|
ldi level,1
|
clt ; T = 0, start with correct
|
clt ; T = 0, start with correct
|
|
|
rcall getinput ; hit any key to start the game
|
rcall getinput ; hit any key to start the game
|
rcall showlife
|
rcall showlife
|
out portB,level ; output level to display
|
out portB,level ; output level to display
|
rcall holding ; release?
|
rcall holding ; release?
|
|
|
nextlevel:
|
nextlevel:
|
rcall delay ; wait a while before the game is started
|
rcall delay ; wait a while before the game is started
|
rcall showled ; show the LEDs and save it in buffer
|
rcall showled ; show the LEDs and save it in buffer
|
nlife: rcall check ; get input and check
|
nlife: rcall check ; get input and check
|
brts wrong
|
brts wrong
|
rcall greenled
|
rcall greenled
|
inc level ; when win, level <- level + 1
|
inc level ; when win, level <- level + 1
|
out portB,level ; output level to display
|
out portB,level ; output level to display
|
rjmp nextlevel
|
rjmp nextlevel
|
wrong: rcall redled
|
wrong: rcall redled
|
rcall delay
|
rcall delay
|
dec life
|
dec life
|
rcall showlife
|
rcall showlife
|
out portb,level
|
out portb,level
|
rcall delay
|
rcall delay
|
cpi life,0
|
cpi life,0
|
breq start
|
breq start
|
rcall playback
|
rcall playback
|
clt
|
clt
|
rjmp nlife
|
rjmp nlife
|
|
|
|
|
;*******************************************
|
;*******************************************
|
; show life
|
; show life
|
showlife:
|
showlife:
|
mov temp,life
|
mov temp,life
|
sbr temp,$f0
|
sbr temp,$f0
|
out portb,temp
|
out portb,temp
|
rcall delay
|
rcall delay
|
rcall delay
|
rcall delay
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
; on red leds
|
; on red leds
|
|
|
redled:
|
redled:
|
clr temp
|
clr temp
|
out portc,temp
|
out portc,temp
|
rcall delay
|
rcall delay
|
ser temp
|
ser temp
|
out portc,temp
|
out portc,temp
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
; on green led
|
; on green led
|
|
|
greenled:
|
greenled:
|
cbi portd,7
|
cbi portd,7
|
rcall delay
|
rcall delay
|
sbi portd,7
|
sbi portd,7
|
ret
|
ret
|
|
|
|
|
;*******************************************
|
;*******************************************
|
; play back the last sequence when wrong
|
; play back the last sequence when wrong
|
|
|
playback:
|
playback:
|
rcall init
|
rcall init
|
w10: ld temp,Z+
|
w10: ld temp,Z+
|
out portC,temp
|
out portC,temp
|
rcall delay
|
rcall delay
|
ser temp ; OFF
|
ser temp ; OFF
|
out portC,temp
|
out portC,temp
|
ldi counter,1
|
ldi counter,1
|
rcall delay
|
rcall delay
|
dec times
|
dec times
|
brne w10
|
brne w10
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
; Show sequence of LEDs (base on times), save in buffer
|
; Show sequence of LEDs (base on times), save in buffer
|
|
|
showled:
|
showled:
|
rcall init
|
rcall init
|
snext: rcall random ; return in NUM
|
snext: rcall random ; return in NUM
|
st Z+,num
|
st Z+,num
|
out portC,num ; display the LED
|
out portC,num ; display the LED
|
rcall delay
|
rcall delay
|
ser temp ; OFF
|
ser temp ; OFF
|
out portC,temp
|
out portC,temp
|
ldi counter,1
|
ldi counter,1
|
rcall delay
|
rcall delay
|
dec times
|
dec times
|
brne snext
|
brne snext
|
ret
|
ret
|
|
|
|
|
;*******************************************
|
;*******************************************
|
; wait for input and check
|
; wait for input and check
|
; return T = 0 when corrert, T = 1 when wrong
|
; return T = 0 when corrert, T = 1 when wrong
|
|
|
check:
|
check:
|
rcall init
|
rcall init
|
nextkey:
|
nextkey:
|
rcall holding
|
rcall holding
|
sei
|
sei
|
rcall getinput ; return in NUM
|
rcall getinput ; return in NUM
|
cli
|
cli
|
ld temp,Z+
|
ld temp,Z+
|
cpse num,temp
|
cpse num,temp
|
set ; Set T flag if one key is wrong
|
set ; Set T flag if one key is wrong
|
rcall holding
|
rcall holding
|
rcall sdelay
|
rcall sdelay
|
dec times
|
dec times
|
brne nextkey
|
brne nextkey
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
; still holding the key ?
|
; still holding the key ?
|
|
|
holding:
|
holding:
|
in temp,pinc
|
in temp,pinc
|
cbr temp,$0F
|
cbr temp,$0F
|
cpi temp,$F0
|
cpi temp,$F0
|
brne holding
|
brne holding
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
; getinput
|
; getinput
|
|
|
getinput:
|
getinput:
|
g15: in num,pinc
|
g15: in num,pinc
|
cbr num,$0F ; clear lower nibble
|
cbr num,$0F ; clear lower nibble
|
cpi num,$F0
|
cpi num,$F0
|
breq g15
|
breq g15
|
rcall sdelay
|
rcall sdelay
|
in temp,pinc
|
in temp,pinc
|
cbr temp,$0F
|
cbr temp,$0F
|
cp temp,num
|
cp temp,num
|
brne g15
|
brne g15
|
swap num
|
swap num
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
; 1. Load level to times
|
; 1. Load level to times
|
; 2. ZP point to start of buffer
|
; 2. ZP point to start of buffer
|
|
|
init: mov times,level ; times <- level
|
init: mov times,level ; times <- level
|
ldi ZP,buffer ; ZP <- buffer
|
ldi ZP,buffer ; ZP <- buffer
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
; Generate Random Num, return in NUM
|
; Generate Random Num, return in NUM
|
|
|
random:
|
random:
|
in num,tcnt0
|
in num,tcnt0
|
ran: cpi num,4
|
ran: cpi num,4
|
brlo rnext
|
brlo rnext
|
subi num,4
|
subi num,4
|
rjmp ran
|
rjmp ran
|
rnext: cpi num,0
|
rnext: cpi num,0
|
brne r10
|
brne r10
|
ldi num,0b1110
|
ldi num,0b1110
|
rjmp rend
|
rjmp rend
|
r10: cpi num,1
|
r10: cpi num,1
|
brne r20
|
brne r20
|
ldi num,0b1101
|
ldi num,0b1101
|
rjmp rend
|
rjmp rend
|
r20: cpi num,2
|
r20: cpi num,2
|
brne r30
|
brne r30
|
ldi num,0b1011
|
ldi num,0b1011
|
rjmp rend
|
rjmp rend
|
r30: ldi num,0b0111
|
r30: ldi num,0b0111
|
rend: in temp,tcnt0
|
rend: in temp,tcnt0
|
ror temp
|
ror temp
|
ror temp
|
ror temp
|
out tcnt0,temp
|
out tcnt0,temp
|
ret
|
ret
|
|
|
;*******************************************
|
;*******************************************
|
delay:
|
delay:
|
mov stack,ZP
|
mov stack,ZP
|
del: ldi ZP,count
|
del: ldi ZP,count
|
ld temp,Z
|
ld temp,Z
|
dec temp
|
dec temp
|
st Z,temp
|
st Z,temp
|
brne del
|
brne del
|
ldi ZP,count+1
|
ldi ZP,count+1
|
ld temp,Z
|
ld temp,Z
|
dec temp
|
dec temp
|
st Z,temp
|
st Z,temp
|
brne del
|
brne del
|
dec counter
|
dec counter
|
brne del
|
brne del
|
ldi counter,5
|
ldi counter,5
|
mov ZP,stack
|
mov ZP,stack
|
ret
|
ret
|
|
|
sdelay:
|
sdelay:
|
clr temp
|
clr temp
|
sd5: dec temp
|
sd5: dec temp
|
brne sd5
|
brne sd5
|
ret
|
ret
|
;*******************************************
|
;*******************************************
|
.dseg
|
.dseg
|
count: .byte 2
|
count: .byte 2
|
|
|