;*********************************************************

;*********************************************************

;**** インクルードファイルの指定 ****

.include "2313DEF.INC"
;**** 初期値 ****




;**** 汎用レジスタの指定 ****

.def	spart	= r17			; spart flag 残り1分未満時1
.def	process	= r18			; 現在のプロセス
;	｛ 1=SHR 2=1 3=rest 4=2 5=rest 6=3 7=rest 8=4 9=noon 10=5 11=rest 12=6 13=rest 14=7 ｝
.def	temp	= r19			; 一時使用用
.def	stack	= r20			; 割り込み時のテータスレジスタ待避場所
.def	n	= r21			; 表示数字一時格納用

.def	d_sec01	= r22			;秒の一の位
.def	d_sec10 = r23			;秒の十の位
.def	d_min01 = r24			;分の一の位
.def	d_min10 = r25			;分の十の位

.def	sleep	= r27			;Sleepフラグ
.def	school	= r28			;授業中フラグ
.def	temp2	= r29			; 一時使用用2
.def	Stock	= r30			;クロック入力監視




;****  リセットベクトルと割り込みベクトルの指定  ****

		rjmp	RESET
		reti
		reti
		reti
		reti
		reti
		reti		;Timer 0 overflow handle
		reti
		reti
		reti
		reti

;*************************************************
;******************  初期化  *********************
;*************************************************
RESET:
	ldi	spart,0		;初期値
	ldi	process,0
	ldi	d_sec01,9
	ldi	d_sec10,5
	ldi	d_min01,4
	ldi	d_min10,0
	ldi	sleep,0
	ldi	school,0
	ldi	temp,0
	ldi	Stock,0

	ldi	temp,low(RAMEND)	; スタックポインタ設定
	out	SPL,temp

;  PORTのイニシャライズ

	ldi	temp,0xFF		; ポートＤを出力に設定
	out	DDRD,temp

	ldi	temp,0b00001111		; ポートＢの入出力を設定
	out	DDRB,temp

	ldi	temp,0b11100000		;ポートBのプルアップ設定
	out	portB,temp



;*************************************************
;************  ＭＡＩＮプログラム  ***************
;*************************************************
main:


	in	temp,pinB		;temp=pinB
	bst	temp,4			;t=temp(4)
	brtS	T_is_1			;t=1　　　　　 のときとぶ
	rjmp	checkEnd		;t=0のときなにもしない
T_is_1:
	sbrC	Stock,0			;t=1 && Stock=0のとき次の命令スキップ
	rjmp	checkEnd		;t=1 && Stock=1のときなにもしない
	rjmp	tim_ovf			;t=1 && Stock=0のとき時計を進める
checkEnd:
	bld	Stock,0			;Stock(0)=t



	cpi	sleep,1
	breq	display_nop

	cpi	spart,0
	breq	display_min
	cpi	spart,1
	breq	display_sec
	rjmp	display_nop

display_sec:				;秒の表示

	mov	n,d_sec01
	rcall	encode
	rcall	Time
	rcall	Time
	rcall	Time
	ldi	temp,0b1111111		;秒の１の位(緑赤右)にnを表示
	out	PORTD,temp
	ldi	temp,0b11101010
	out	PORTB,temp
	out	PORTD,n

	cpi	d_sec10,0		;0の場合十の位を表示しない
	breq	display_nop

	mov	n,d_sec10
	rcall	encode
	rcall	Time
	rcall	Time
	rcall	Time
	ldi	temp,0b1111111		;秒の十の位(緑赤左)にnを表示
	out	PORTD,temp
	ldi	temp,0b11100101
	out	PORTB,temp
	out	PORTD,n
	rjmp	main

display_min:				;分の表示
	mov	n,d_min01
	rcall	encode
	rcall	Time
	rcall	Time
	rcall	Time
	ldi	temp,0b1111111		;分の一の位(赤右)にnを表示
	out	PORTD,temp
	ldi	temp,0b11100010
	out	PORTB,temp
	out	PORTD,n

	cpi	d_min10,0		;0の場合十の位を表示しない
	breq	display_nop

	mov	n,d_min10
	rcall	encode
	rcall	Time
	rcall	Time
	rcall	Time
	ldi	temp,0b1111111		;分の十の位(赤左)にnを表示
	out	PORTD,temp
	ldi	temp,0b11100001
	out	PORTB,temp
	out	PORTD,n
	rjmp	main

display_nop:
	rcall	Time
	rcall	Time
	rcall	Time
	rcall	Time
	ldi	temp,0b1111111		;分の十の位(緑左)にnを表示
	out	PORTD,temp
	rjmp main


					;***** Timer割り込み時 *****
tim_ovf:
	bld	Stock,0			;Stock(0)=t

	IN	stack,sreg		;flagレジスタを退避

	in	temp,pinB		;NEXTボタンpush確認
	sbrS	temp,5			;押されてなければ次の命令スキップ
	rjmp	next

	dec	d_sec01			;d_sec01を減算
	brmi	dec_sec10		;減算結果が負なら「dec_sec10」へジャンプ
	rjmp	exit_int
dec_sec10:
	ldi	d_sec01,9		;d_sec01を９に
	dec	d_sec10			;d_sec10を減算
	brmi	dec_min01		;減算結果が負なら
	rjmp	exit_int

dec_min01:
	ldi	d_sec10,5		;d_sec10を5に
	dec	d_min01			;d_min01を減算
	brmi	dec_min10		;減算結果が負ならdec_min10
	breq	spart_1			;減算結果が0ならspart開始確認への条件分岐
	rjmp	exit_int
spart_1:
	cpi	d_min10,0
	breq	spart
	rjmp	exit_int
spart:					;spart開始
	ldi	spart,1
	rjmp	exit_int

dec_min10:
	ldi	d_min01,9		;d_min01を９に
	dec	d_min10			;d_min10を減算
	brmi	next			;減算結果が負なら
	rjmp	exit_int
next:
	ldi	spart,0			;spart解除
	ldi	d_sec01,9		;秒をリセット
	ldi	d_sec10,5

	ldi	school,0		;授業中フラグOFF

	inc	process
	cpi	process,1
	breq	shr
	cpi	process,2
	breq	school			;1st
	cpi	process,3
	breq	rest
	cpi	process,4
	breq	school			;2nd
	cpi	process,5
	breq	rest
	cpi	process,6
	breq	school			;3rd
	cpi	process,7
	breq	rest
	cpi	process,8
	breq	school			;4th
	cpi	process,9
	breq	noon
	cpi	process,10
	breq	school			;5th
	cpi	process,11
	breq	rest
	cpi	process,12
	breq	school			;6th
	cpi	process,13
	breq	rest
	cpi	process,14
	breq	school			;7th
	cpi	process,15
	breq	count			;test
	cpi	process,16
	breq	sleep			;sleep
	rjmp	RESET



shr:
	;SHR10min
	ldi	d_min10,0
	ldi	d_min01,9
	rjmp	exit_int
school:
	;授業47min
	ldi	d_min10,4
	ldi	d_min01,6
	ldi	school,1		;授業中フラグON
	rjmp	exit_int
rest:
	;休み時間8min
	ldi	d_min10,0
	ldi	d_min01,7
	rjmp	exit_int
noon:
	;昼休み48min
	ldi	d_min10,4
	ldi	d_min01,7
	rjmp	exit_int
count:
	ldi	d_min10,0
	ldi	d_min01,0
	ldi	spart,1
	rjmp	exit_int

sleep:
	ldi	d_min10,100
	ldi	d_min01,6
	ldi	sleep,1
	rjmp	exit_int

exit_int:
	OUT	sreg,stack		;flagレジスタを復元
	rjmp	main			;割り込みルーチンから復帰

;*************************************************
;************* 以下サブルーチン ******************
;*************************************************

;***** 時間稼ぎ *****
Time:					;26/10,000,000秒（含サブルーチン呼び出し復帰）
	nop				;01
	nop				;02
	nop				;03
	nop				;04
	nop				;05
	nop				;06
	nop				;07
	nop				;08
	nop				;09
	nop				;10
	nop				;11
	nop				;12
	nop				;13
	nop				;14
	nop				;15
	nop				;16
	nop				;17
	nop				;18
	nop				;19
	ret				;サブルーチンから復帰

;***** 数字を変換 *****
encode:
					;nを変換してtempに代入
	ldi	temp,0b1000000		;0
	cpi	n,0
	breq	express
	ldi	temp,0b1110011		;1
	dec	n
	breq	express
	ldi	temp,0b0100100		;2
	dec	n
	breq	express
	ldi	temp,0b0100001		;3
	dec	n
	breq	express
	ldi	temp,0b0010011		;4
	dec	n
	breq	express
	ldi	temp,0b0001001		;5
	dec	n
	breq	express
	ldi	temp,0b0001000		;6
	dec	n
	breq	express
	ldi	temp,0b1000011		;7
	dec	n
	breq	express
	ldi	temp,0b0000000		;8
	dec	n
	breq	express
	ldi	temp,0b0000001		;9
	dec	n
	breq	express
express:
	mov	n,temp			;tempをnに代入
	ret				;サブルーチンから復帰


