; Tab width = 4

;----------------------------------------------------------------------------
; ** ベースタイマ割り込み利用サンプル1 **
;
; ・ベースタイマ割り込み(0.5秒ごと)をカウントする
; ・カウンタの値を2桁10進数でLCDに表示する
;----------------------------------------------------------------------------
; 1.01 990208 SEGA Enterprises,LTD.
;----------------------------------------------------------------------------

chip	LC868700			; チップの種類をアセンブラに指定
world	external			; 外部メモリ用プログラム

public	main				; ghead.asm から参照されるシンボル
public	int_BaseTimer		; ghead.asm から参照されるシンボル

extern	_game_end			; ghead.asm への参照シンボル


; **** システム定数の定義 ***************************************************

							; OCR(発振制御レジスタ)設定値
osc_rc		equ 04dh		;	システムクロックに内蔵RC発振を指定
osc_xt		equ 0efh		;	システムクロックに水晶発振を指定


; *** データセグメント ******************************************************

		dseg				; データセグメント開始

r0:		ds		1			; 間接アドレッシングレジスタ r0
r1:		ds		1			; 間接アドレッシングレジスタ r1
r2:		ds		1			; 間接アドレッシングレジスタ r2
r3:		ds		1			; 間接アドレッシングレジスタ r3
		ds		12			; その他のシステム予約レジスタ
		
counter: ds		1			; ベースタイマ割り込みカウンタ
work1:	ds		1			; 作業用 (put2digit)


; *** コードセグメント ******************************************************

		cseg				; コードセグメント開始
		
; *-------------------------------------------------------------------------*
; * ユーザープログラム														*
; *-------------------------------------------------------------------------*
main:
		mov		#0,counter	; カウンタの値をリセット
		
		call	cls			; LCD表示イメージを消去する
		
loop0:
		mov		#2,c		; 表示位置(水平)
		mov		#1,b		; 表示位置(垂直)
		ld		counter		; カウンタの値をaccへ
		call	put2digit	; accの値(2桁)を数値表示する
		
		set1	pcon,0		; 次の割り込みまでHALTモードで待つ

							; ** [M](モード)ボタンチェック **
		ld		P3
		bn		acc,6,finish ; [M]ボタンが押されていたらアプリ終了

		br		loop0		; 繰り返し

finish:						; ** アプリケーション終了処理 **
		jmp		_game_end	; アプリケーション終了


; *-------------------------------------------------------------------------*
; * 2桁の数値を表示する														*
; * 入力 acc : 数値															*
; *        c : 文字水平位置												  	*
; *        b : 文字垂直位置												  	*
; *-------------------------------------------------------------------------*
put2digit:
		push	b			; 座標データを退避
		push	c			;
		st		c			; 10の位と1の位の値をそれぞれ計算
		xor		a			; ( acc = acc/10, work1 = acc mod 10 )
		mov		#10,b		;
		div					;
		ld		b			;
		st		work1		; 1の位の計算結果をwork1に保存
		ld		c			;
		pop		c			; 座標値を(c.b)に復帰
		pop		b			; 
		push	b			; また退避
		push	c			;
		call	putch		; 10の位を表示
		ld		work1		; 1の位の値を読み込み
		pop		c			; 座標値を(c,b)に復帰
		pop		b			; 
		inc		c			; 表示座標を右へ
		call	putch		; 1の位を表示

		ret					; put2digit終わり


; *-------------------------------------------------------------------------*
; * LCD表示イメージを消去する												*
; *-------------------------------------------------------------------------*
cls:
		push	OCR			; OCR値を退避
		mov		#osc_rc,OCR ; システムクロックを指定

		mov		#0,XBNK		; 表示用RAMのバンクアドレスを指定(BANK0)
		call	cls_s		; そのバンク内のデータをクリア

		mov		#1,XBNK		; 表示用RAMのバンクアドレスを指定(BANK1)
		call	cls_s		; そのバンク内のデータをクリア
		pop		OCR			; OCR値を復帰
		
		ret					; cls終わり
		
cls_s:						; *** 表示用RAM 1BANK分の消去 ***
		mov		#80h,r2		; 間接アドレッシングレジスタを表示用RAMの先頭に
		mov		#80h,b 		; ループカウンタbにループ数をセット
loop3:
		mov		#0,@r2		; アドレスをインクリメントしながら0を書き込む
		inc		r2			;
		dbnz	b,loop3		; bが0になるまで繰り返す
		
		ret					; cls_s終わり
		

; *-------------------------------------------------------------------------*
; * 指定位置に1キャラクタ表示する											*
; * 入力 acc : キャラクタコード												*
; *        c : 文字水平位置												  	*
; *        b : 文字垂直位置												  	*
; *-------------------------------------------------------------------------*
putch:
		push	XBNK
		push	acc
		call	locate		; 座標から表示RAMのアドレスを計算
		pop		acc
		call	put_chara	; 1キャラクタ表示する
		pop		XBNK
		
		ret					; putch終わり
		

locate:	; **** 表示位置指定から表示用RAMのアドレスを計算 ****
		; ** 入力 c: 水平位置(0〜5) b: 垂直位置(0〜3)
		; ** 出力 r2: RAMアドレス XBNK: 表示用RAMバンク

							; *** 表示用RAMバンクアドレスの判断 ***
		ld		b			; b>=2 のとき next1 へ
		sub		#2			;
		bn		PSW,7,next1	;
		
		mov		#00h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK0)
		br		next2
next1:
		st		b
		mov		#01h,XBNK	; 表示用RAMのバンクアドレスを指定(BANK1)
next2:

							; *** 表示指定位置のRAMアドレス計算 ***
		ld		b			; b * 40h + c + 80h
		rol					;
		rol					;
		rol					;
		rol					;
		rol					;
		rol					;
		add		c			;
		add		#80h		;
		st		r2			; RAMアドレスをr2に格納
				
		ret					; locate終わり


put_chara:
		push	PSW			; PSW値を退避
		set1	PSW,1		; データRAMバンク1を選択

							; *** キャラクタデータアドレスの計算 ***
		rol					; (TRH,TRL) = acc*8 + fontdata
		rol					;
		rol					;	
		add		#low(fontdata)	;
		st		TRL				;
		mov		#0,acc			;
		addc	#high(fontdata)	;
		st		TRH			;

		push	OCR			; OCR値を退避
		mov		#osc_rc,OCR ; システムクロックを指定

		mov		#0,b		; キャラクタデータ読み出し用オフセット値
		mov		#4,c		; ループカウンタ
loop1:
		ld		b			; 1ライン目の表示データを読み出す
		ldc					;
		inc		b			; 読み出しデータのオフセットを +1
		st		@r2			; 表示データを表示用RAMに転送
		ld		r2			; 表示用RAMアドレス +6
		add		#6			;
		st		r2			;

		ld		b			; 2ライン目の表示データを読み出す
		ldc					;
		inc		b			; 読み出しデータのオフセットを +1
		st		@r2			; 表示データを表示用RAMに転送
		ld		r2			; 表示用RAMアドレス +10
		add		#10			;
		st		r2			;
		
		dec		c			; ループカウンタのデクリメント
		ld		c			; 
		bnz		loop1		; 8ライン分(4回)繰り返し

		pop		OCR			; OCR値を復帰
		pop		PSW			; PSW値を復帰

		ret					; put_chara終わり


; *-------------------------------------------------------------------------*
; * キャラクタのビットイメージデータ										*
; *-------------------------------------------------------------------------*
fontdata:
		db 07ch, 0e6h, 0c6h, 0c6h, 0c6h, 0ceh, 07ch, 000h	;'0' 00 
		db 018h, 038h, 018h, 018h, 018h, 018h, 03ch, 000h	;'1' 01
		db 07ch, 0c6h, 0c6h, 00ch, 038h, 060h, 0feh, 000h	;'2' 02
		db 07ch, 0e6h, 006h, 01ch, 006h, 0e6h, 07ch, 000h	;'3' 03
		db 00ch, 01ch, 03ch, 06ch, 0cch, 0feh, 00ch, 000h	;'4' 04
		db 0feh, 0c0h, 0fch, 006h, 006h, 0c6h, 07ch, 000h	;'5' 05
		db 01ch, 030h, 060h, 0fch, 0c6h, 0c6h, 07ch, 000h	;'6' 06
		db 0feh, 0c6h, 004h, 00ch, 018h, 018h, 038h, 000h	;'7' 07
		db 07ch, 0c6h, 0c6h, 07ch, 0c6h, 0c6h, 07ch, 000h	;'8' 08
		db 07ch, 0c6h, 0c6h, 07eh, 006h, 00ch, 078h, 000h	;'9' 09		


; *-------------------------------------------------------------------------*
; * ベースタイマ割り込みハンドラ部											*
; *-------------------------------------------------------------------------*
int_BaseTimer:
		push	acc			; 使用レジスタを退避
		inc		counter		; カウンタをインクリメント
		ld		counter		; カウンタが100になったら..
		bne		#100,next3	;
		mov		#0,counter	; カウンタのリセット
next3:						;
		pop		acc			; 退避レジスタを復帰
		
		ret					; (ユーザー側)割り込み処理終了


