All pastes #577558 Raw Edit

simon for stk500 (in avrasm)

public text v1 · immutable
·published 2007-06-19 23:29 UTC
rendered paste body
//_
//_ simon for stk500 (in avrasm) 
//_	by renesis/efnet
//_ 2007.06.19
//_ 
//_ based on: 
//_ simon for stk500 (in c)
//_ by ^dx^/efnet
//_

//_ device definitions

.include "m8515def.inc"			// ATMega8515, 8MHz (internal RC) 

//_ register definitions

.def temp		=r16			// general use
.def temp2		=r17
.def temp3		=r18
.def buttons	=r19			// button buffer
.def random		=r20			// random buffer
.def level		=r21			// game level counter

//_ program constants

.equ game_length		=6		// game length, in number of levels

.equ game_gap_time		=20		// time between simon input and simon output modes * 0.01sec
.equ led_flash_time		=15		// simon blink on time * 0.01sec
.equ led_dead_time		=5		// off time between simon blinks * 0.01sec
.equ led_winblink_time	=5		// win blink halfcycle time * 0.01sec		
.equ led_loseblink_time	=33		// lose blink halfcycle time * 0.01sec
.equ led_start_pattern	=$aa	// stk500 LED splash patterns
.equ led_wina_pattern	=$aa	// LED are active low
.equ led_winb_pattern	=$55
.equ led_losea_pattern	=$fc
.equ led_loseb_pattern	=$ff

.equ button_soft_reset	=led_losea_pattern	// soft reset button pattern (active low)

.equ led_port			=portb	// led port definitions
.equ led_ddr			=ddrb

.equ button_port		=portd	// button port definitions
.equ button_ddr			=ddrd
.equ button_pin			=pind


.equ delaytime_10ms		=10000	// compare value @ 8MHz,prescale=/8 (100KHz|10us)

//_ sram allocation

.dseg
	randtab: 		.byte game_length	// random button/LED table
.cseg

//_ vector table

.org $0

	rjmp reset 				// poweron/reset
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti
	reti

//_ delay 100ms (timer1 based)

delay_10ms:
	
	push temp				// store temp register on stack

	clr temp				// clear timer count reg 
	out tcnt1h,temp			// buffered 16bit register, WRITE HIGH BYTE FIRST
	out tcnt1l,temp

	in temp,tifr			// reset ocf1a in timer flag register 
	sbr temp,(1<<ocf1a)		// (logical 1 resets flag)
	out tifr,temp

delay_10ms0:				// loop until ocf1a is set
	in temp,tifr
	sbrs temp,ocf1a
	rjmp delay_10ms0

	pop temp				// get stored temp register value

	ret

//_ delay macros (uses temp register)

.macro delay_x10ms
	ldi temp,@0				// macro input is delay multiplier
delay_x10ms0:
	rcall delay_10ms
	dec temp
	brne delay_x10ms0
.endmacro

//_ stk500 LEDs (uses temp register)

.macro led_setup
	ser temp				// setup LED port output high
	out led_port,temp		// LED are NPN buffered, active low
	out led_ddr,temp
.endmacro

.macro led_on_start
	ldi temp,led_start_pattern
	out led_port,temp
.endmacro

.macro led_on_wina
	ldi temp,led_wina_pattern
	out led_port,temp
.endmacro
	
.macro led_on_winb
	ldi temp,led_winb_pattern
	out led_port,temp
.endmacro

.macro led_on_losea
	ldi temp,led_losea_pattern
	out led_port,temp
.endmacro
	
.macro led_on_loseb
	ldi temp,led_loseb_pattern
	out led_port,temp
.endmacro

.macro led_on_byte
	out led_port,@0
.endmacro

.macro led_on_all
	clr temp
	out led_port,temp
.endmacro

.macro led_off_all
	ser temp
	out led_port,temp
.endmacro

//_ stk500 buttons + random

button_wait:

	push temp					// store temp register on stack

	rcall chk_soft_reset		// check for program reset

button_wait0:					// wait for buttons clear
	in temp,button_pin				
	cpi temp,$ff
	brne button_wait0

	in random,tcnt1l			// import low byte from running timer1
button_wait1:
	inc random					// inc value each button polling
	in buttons,button_pin
	cpi buttons,$ff
	breq button_wait1

	in temp,tcnt1l				// when button press detected, import low byte of running timer1
	eor temp,random				// xor the the modified original and new timer low bytes
	andi temp,$07				// mask off the last 3 bits
	ldi random,$01
button_wait2:					// use the masked bits as a left shift count
	cpi temp,$00
	breq button_wait3
	dec temp
	lsl random
	rjmp button_wait2
button_wait3:
	ldi temp,$ff				// invert the value for active low usability
	eor random,temp

	pop temp					// get stored temp register value

	ret

//_ check for soft reset

chk_soft_reset:

	in buttons,button_pin
	cpi buttons,button_soft_reset
	breq reset

	ret

//_ program init

reset: 
	
	ldi temp,low(ramend) 			// setup stack pointer
	out spl,temp
	ldi temp,high(ramend)
	out sph,temp

	clr temp						// initialize delay timer
	out tccr1a,temp					// mode=CTC,top=OCR1A,prescale=/8
	ldi temp,(1<<WGM12)|(1<<CS11)
	out tccr1b,temp
	ldi temp,high(delaytime_10ms)	// setup compare register
	out ocr1ah,temp					// buffered 16bit register, WRITE HIGH BYTE FIRST
	ldi temp,low(delaytime_10ms)
	out ocr1al,temp
					
	led_setup						// setup stk500 LEDs
	led_on_start					// game start LED splash ($55)

	clr level						// init game level register

	mov temp3,level					// init randtab pointer
	ldi ZH,high(randtab)
	ldi ZL,low(randtab)

	rcall button_wait				// wait for user input to start game
	st Z+,random					// store as next in random table 

//_ program mainloop

deathloop:

	inc level
	cpi level,game_length+1
	breq winloop
	
	delay_x10ms game_gap_time
	rcall simon_out
	delay_x10ms game_gap_time	
	rcall simon_in

	rjmp deathloop

//_ simon output loop

simon_out:

	mov temp3,level				// copy level for counter use
	ldi ZH,high(randtab)		// init randtab pointer
	ldi ZL,low(randtab)

simon_out0:

	led_off_all					// switch of all LED
	delay_x10ms led_dead_time

	ld random,Z+				// pull value from randtab, post inc
	led_on_byte random			// flash LED for randtab byte
	delay_x10ms led_flash_time

	dec temp3					// decrement copied level counter
	brne simon_out0				// continue looping if not zero
	
	led_off_all

	ret

//_ simon input loop

simon_in:

	mov temp3,level				// copy level for counter use
	ldi ZH,high(randtab)		// init randtab pointer
	ldi ZL,low(randtab)

simon_in0:

	rcall button_wait			// wait for button press
	mov temp2,random			// copy random value for possible storage later

	led_on_byte buttons			// flash LED corresponding to pressed button
	delay_x10ms led_flash_time
	led_off_all
	delay_x10ms led_dead_time

	ld random,Z+				// pull value from randtab, post inc
	cp buttons,random			// compare the randtab value and buttons
	brne loseloop				// game lost if not equal

	dec temp3					// decrement copied level counter
	brne simon_in0				// continue looping if not zero

	st Z,temp2					// store copied random value to randtab
	
	ret

//_ game won loop

winloop:
	
	led_on_wina						// do win blink sequence
	delay_x10ms (led_winblink_time)
	led_on_winb
	delay_x10ms (led_winblink_time)

	rcall chk_soft_reset			// check for program reset

	rjmp winloop

//_ game lost loop

loseloop:

	led_on_losea					// do lose blink sequence
	delay_x10ms (led_loseblink_time)
	led_on_loseb
	delay_x10ms (led_loseblink_time)

	rcall chk_soft_reset			// check for program reset
	
	rjmp loseloop

//_ program end