; Tab width = 4

;----------------------------------------------------------------------------
; ** LCD表示処理サンプル2 **
;
; ・表示用RAMを0でフィルして表示イメージを消去する
; ・キャラクタパターンを指定位置に表示する
;----------------------------------------------------------------------------
; 1.00 981208 SEGA Enterprises,LTD.
;----------------------------------------------------------------------------

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

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

extern	_game_end			; アプリケーション終了


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

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


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

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

r0:		ds		1			; 間接アドレッシングレジスタ r0
r1:		ds		1			; 間接アドレッシングレジスタ r1
r2:		ds		1			; 間接アドレッシングレジスタ r2
r3:		ds		1			; 間接アドレッシングレジスタ r3
		ds		12			; その他のシステム予約レジスタ


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

		cseg				; コードセグメント開始

; *-------------------------------------------------------------------------*
; * ユーザープログラム														*
; *-------------------------------------------------------------------------*
main:
		call	cls			; LCD表示イメージを消去する

		mov		#1,c		; 水平座標
		mov		#1,b		; 垂直座標
		mov		#0ah,acc	; キャラクタコード 'S'
		call	putch		; 一文字表示

		mov		#2,c
		mov		#1,b
		mov		#0bh,acc	; 'E'
		call	putch
		
		mov		#3,c
		mov		#1,b
		mov		#0ch,acc	; 'G'
		call	putch

		mov		#4,c
		mov		#1,b
		mov		#0dh,acc	; 'A'
		call	putch

		mov		#1,c
		mov		#2,b
		mov		#1,acc		; '1'
		call	putch

		mov		#2,c
		mov		#2,b
		mov		#9,acc		; '9'
		call	putch
		
		mov		#3,c
		mov		#2,b
		mov		#9,acc		; '9'
		call	putch

		mov		#4,c
		mov		#2,b
		mov		#8,acc		; '8'
		call	putch

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

		jmp		loop0		; ループして待つ

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


; *-------------------------------------------------------------------------*
; * 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

		db 07ch, 0e6h, 076h, 038h, 0dch, 0ceh, 07ch, 000h	;'S' 0a
		db 0feh, 0c0h, 0c0h, 0f8h, 0c0h, 0c0h, 0feh, 000h	;'E' 0b
		db 07ch, 0e6h, 0c0h, 0dch, 0c6h, 0e6h, 07ch, 000h	;'G' 0c
		db 01eh, 036h, 066h, 0c6h, 0c6h, 0feh, 0c6h, 000h	;'A' 0d
		
