;--------
; 2013/07/22 TEST2
; LED点灯プログラム
; ATtiny2313A 1MHz
;--------
;-------- アセンブラプログラムの決まりごと--------
;(1) ';(セミコロン)'はコメント記号です。行の中に現れると、開発環境はセミコロンより後ろを無視します。
;(2) アセンブラプログラムの中では、名前や命令の大文字小文字の違いは無視されます。
;大文字小文字どちらでプログラムを書いてもかまいません。
;※データ中の大文字小文字は区別されます。
;※コメント以外の場所では、全角文字は使えません(エラーになります)
;(3) '.include'など、頭に'.(ピリオド)'がついているのは開発環境に対する作業指示を意味する擬似命令です。
;(4) 「main:」など、名前の後ろに':(コロン)'があるのはラベルです。
;ジャンプやサブルーチンコール命令の飛び先を指定するのに使います。
;--------
.include "tn2313def.inc"			;ATtiny2313用定義ファイルを取り込みます
			;このファイルの中で、I/Oレジスタの名前などが定義されています。
;--------
; 割り込みベクタ領域(ATtiny2313Aの場合、0x0000番地～0x0012番地)
; 使う割り込みの頭のコメント記号(セミコロン)を外して使います。
;--------
.org 0x00	rjmp	reset	;各種リセット: 「reset:」というラベルのところにジャンプします。
;.org 0x01	rjmp	ext_int0	;外部割り込み要求0
;.org 0x02	rjmp	ext_int1	;外部割り込み要求1
;.org 0x03	rjmp	tim1_capt	;タイマ/カウンタ1捕獲(キャプチャ)発生
;.org 0x04	rjmp	tim1_compa	;タイマ/カウンタ1比較A一致
;.org 0x05	rjmp	tim1_ovf	;タイマ/カウンタ1オーバーフロー
;.org 0x06	rjmp	tim0_ovf	;タイマ/カウンタ0オーバーフロー
;.org 0x07	rjmp	usart_rxt	;usart受信完了
;.org 0x08	rjmp	usart_udre	;usart送信バッファ空
;.org 0x09	rjmp	uasrt_tx	;usart送信完了
;.org 0x0a	rjmp	ana_comp	;アナログ比較器出力遷移
;.org 0x0b	rjmp	pcint	;ピン変化割り込み要求
;.org 0x0c	rjmp	tim1_compb	;タイマ/カウンタ1比較B一致
;.org 0x0d	rjmp	tim0_compa	;タイマ/カウンタ0比較A一致
;.org 0x0e	rjmp	tim0_compb	;タイマ/カウンタ0比較B一致
;.org 0x0f	rjmp	usi_strt	;usi開始条件検出
;.org 0x10	rjmp	usi_ovf	;usiカウンタオーバーフロー
;.org 0x11	rjmp	ee_edy	;eeprom操作可
;.org 0x12	rjmp	wdt_ovf	;ウォッチドッグ時計完了
;--------
; ATtiny2313Aの場合、プログラムは0x13番地以降からはじまるように書きます
;--------
.org 0x13			; 「.org 0x13」は、命令をプログラムメモリの 0x13番地以降に置くよう、
			; 開発環境に対して指示するための擬似命令です。
			; 頭が「0x」ではじまる数値は16進数です。
;--------
	
;--------
; リセット時の処理
; (1)スタックポインタの初期化
; ATtiny2313Aの場合、RAMEND(内部SRAMの最終番地)は0x00df番地です。
; RAMENDの値は、"tn2313adef.inc"中で定義されています
;--------
reset:	ldi	r16,low(RAMEND)	;「low」は16ビットの定数の下位8ビットを取り出すための演算子です。
			;ATtiny2313aの場合、「ldi r16,0xdf」と書いてもかまいません。
	out	SPL,r16
;「RAMEND」は、データSRAM領域の最後のアドレスのことで、開発環境中で定義されています。
;--------
; (2)ポートの初期化
;--------
	ldi	r16,0b11111111	;ポートB(PB0～PB7)を
	out	DDRB,r16	;全ビット出力モードにする
	ldi	r16,0b11111111	;ポートD(PD0～PD6)を
	out	DDRD,r16	;全ビット出力モードにする
	ldi	r16,0b11111111	;ポートA(PA1～PA0)を
	out	DDRA,r16	;全ビット出力モードにする
;頭が「0bではじまる数値は2進数です。
;--------
;mainループ: ここに繰り返し実行させる内容を書きます
; ※このチュートリアルの回路では、点灯させたいLEDのポートを「L」にする
; (PORTレジスタの対応するビットを「0」にする)とLEDが点灯します。
;--------
main:	ldi	r16,0b11111110	; PB0のLEDを点灯させます
	out	 PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	ldi	r16,0b11111101	; PB1のLEDを点灯させます
	out	PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	ldi	r16,0b11111011	; PB2のLEDを点灯させます
	out	PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	ldi	r16,0b11110111	; PB3のLEDを点灯させます
	out	PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	ldi	r16,0b11101111	; PB4のLEDを点灯させます
	out	PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	ldi	r16,0b11011111	; PB5のLEDを点灯させます
	out	PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	ldi	r16,0b10111111	; PB6のLEDを点灯させます
	out	PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	ldi	r16,0b01111111	; PB7のLEDを点灯させます
	out	PORTB,r16	; PORTBレジスタに出力
	rcall	wait	; 時間待ち
;
	rjmp	main	; mainに飛びます(無限ループ)
	
;******** wait : 時間稼ぎ用ルーチン********
wait:	ldi	r19,0x0f	;r19 = 0x0f(10進で15)
wait1:	dec	r19	;r19を1減らし
	cpi	r19,0	;r19が0になったかどうか比較
	breq	waitend	;0だったら、waitendへジャンプ
	ldi	r18,0xff	;r19が0でなければ、r18を0xffにする
wait2:	dec	r18	;r18を1減らし
	cpi	r18,0	;r18が0になったかどうか比較
	breq	wait1	;r18が0だったら、wait1にジャンプ(繰り返す)ldi r17,0xff ;r18が0でなければ、r17を0xffにする
wait3:	dec	r17	;r17を1減らし
	cpi	r17,0	;r17が0になったかどうか比較
	breq	wait2	;r17が0だったら、wait2にジャンプ
	rjmp	 wait3	;r17が0でなければ、wait3にジャンプ
waitend:	ret		;サブルーチンからリターン