ソフトCRTC ソース

(ソフトCRTC内蔵超ミニBASIC for SH7046より関連部分の抜粋)

戻る


・初期化部分

INIT:

(システムレジスタの設定…省略)

	MOV.L	IPRE1,R13	; IPRE7..4:MTU CH3 TGI
	MOV.W	IPRED,R0	MTUチャネル3の割り込み優先度設定
	MOV.W	R0,@R13

; INIT PORT

	MOV.L	IOBASE1,R13
	LDC	R13,GBR

(ポートAの設定…省略)

	MOV.W	PECRL1D,R0			ビット10をTIOC3Cに設定
	MOV.W	R0,@(PECRL1-IOBASE,GBR)		他は普通のポート
	MOV.W	PEIORLD,R0
	MOV.W	R0,@(PEIORL-IOBASE,GBR)		ビット8〜10を出力に設定

; INIT MTU_CH3 FOR SOFT-CRTC

	MOV.L	MTU34B1,R13
	LDC	R13,GBR
	MOV	#0,R0			; NO SYNCRO
	MOV.B	R0,@(TSYR-MTU34B,GBR)

	MOV	#H'C0,R0		; CLEAR BY TGRD,UP EDGE,PCLK
	MOV.B	R0,@(TCR_3-MTU34B,GBR)	 コンペアマッチDでタイマクリヤ
	MOV	#H'C2,R0		; NO BUFFER,PWM MODE 1
	MOV.B	R0,@(TMDR_3-MTU34B,GBR)	 PWMモード1にする

	MOV	#H'C0,R0		; DON'T OUT TIOC4D,4C,3D,4B,4A,3B
	MOV.B	R0,@(TOER-MTU34B,GBR)
	MOV	#H'00,R0		; DON'T TOGGLE
	MOV.B	R0,@(TOCR-MTU34B,GBR)

	MOV	#0,R0			; TGRA,TGRB NOT FOR PWM
	MOV.B	R0,@(TIORH_3-MTU34B,GBR)
	MOV	#H'21,R0		; TIOC3C MATCH-D -> 1 , MTACH-C -> 0
	MOV.B	R0,@(TIORL_3-MTU34B,GBR) コンペアマッチDで1、コンペアマッチCで0を出力

	MOV	#H'48,R0		; INTERRUPT ON MATCH TGRD
	MOV.B	R0,@(TIER_3-MTU34B,GBR)	 コンペアマッチDで割り込み発生

	MOV	#0,R0			; INITIAL VALUE
	MOV.W	R0,@(TCNT_3-MTU34B,GBR)	 タイマの初期値0
	MOV.W	HCYCLE,R0		 63.5μ秒周期になるようTGRDを設定
	MOV.W	R0,@(TGRD_3-MTU34B,GBR)
	MOV.W	R0,@(TGRB_3-MTU34B,GBR)	; NOT USE TGRB
	MOV.W	HSYWID,R0
	MOV.W	R0,@(TGRC_3-MTU34B,GBR)	 最初は同期パルス幅が4.7μ秒になるよう設定
	MOV.W	HDSPOS,R0
	MOV.W	R0,@(TGRA_3-MTU34B,GBR)	 表示開始位置(コンペアマッチA)の設定

	MOV.B	@(TSR_3-MTU34B,GBR),R0	; DUMMY READ
	MOV.B	#0,R0
	MOV.B	R0,@(TSR_3-MTU34B,GBR)	; CLEAR INTERRUPT FLAGS 割り込みフラグクリヤ

; INIT SCI

(SCIの初期化…省略)

	BRA	INIT_2
	MOV.B	R0,@(SSR_3-SCIBASE,GBR)

	ALIGN	2

MSTCR1D:DC.W	H'F033		; USE SCI2,SCI3
MSTCR2D:DC.W	H'D0F0		; USE MTU
BCR1D:	DC.W	H'2000		; USE MTU
IPRED:	DC.W	H'00E0		; MTU CH3 TGI LEVEL 14
PACRL1D:DC.W	H'0005		; USE TXD3,RXD2,TXD2,RXD2
PACRL2D:DC.W	H'5000
PACRL3D:DC.W	H'03C0
PECRL1D:DC.W	H'0010		; USE TIOC3C
PEIORLD:DC.W	H'0700		; BIT 10,9,8 OUT

HCYCLE:	DC.W	1559		; 24576000/15750-1	 水平周期
HSYWID:	DC.W	114		; 4.7 MICRO SEC.	 同期パルス幅
HDSPOS:	DC.W	354		; DISPLAY START POSITION 表示開始位置(この値を変えると
							 表示位置を調整できます)

	ALIGN	4

MSTCR1_1:	DC.L	MSTCR1
IPRE1:		DC.L	IPRE
IOBASE1:	DC.L	IOBASE
MTU34B1:	DC.L	MTU34B
DLYCNT:		DC.L	25000
SCIBASE1:	DC.L	SCIBASE


; INIT SOFT-CRTC WORK AREA & START SOFT-CRTC

INIT_2:	MOV.L	CRTWRK2,R13
	LDC	R13,GBR
	MOV	#0,R0				垂直位置の初期値0
	MOV	R0,@(CURRVP-CRTWRK,GBR)
	MOV.W	VSYPOS1,R0			垂直同期パルスの位置設定
	MOV.W	R0,@(VSYPOS-CRTWRK,GBR)

	MOV.L	A_GCLR,R13			画面クリヤ
	JSR	@R13
	MOV	#0,R2		; COLOR

	MOV.L	TSTR1,R3
	MOV.B	#H'40,R0	; START MTU CH3 タイマスタート
	MOV.B	R0,@R3

; START BASIC INTERPRETER

(BASICインタプリタの起動…省略)

	ALIGN	2

VSYPOS1:DC.W	222		; INITIAL V-SYNC POSITION 垂直同期パルスの位置(この値を
							  変えると表示位置を調整できます)

	ALIGN	4

CRTWRK2:DC.L	CRTWRK
TSTR1:	DC.L	TSTR
WRKTOP1:DC.L	WRKTOP
A_GCLR:	DC.L	GCLEAR
A_MAIN1:DC.L	MAIN


・同期処理(コンペアマッチD割り込み)

SYNINT:	MOV.L	R0,@-R15
	MOV.L	R1,@-R15
	MOV.L	R2,@-R15
	MOV.L	R3,@-R15

	MOV.L	PEDRL1,R2
	MOV	#0,R0		 輝度出力を0にする
	MOV.W	R0,@R2		; VIDEO OUT OFF

	MOV.L	CRTWRK1,R2
	MOV.W	VCYCLE,R0	 垂直周期(走査線263本)
	MOV.W	@R2,R1		; CURRVP 現在の垂直位置
	MOV.L	TIER3_1,R3
	CMP/HS	R0,R1		 垂直位置≧263なら垂直位置を0にする
	BF/S	SYNI1
	MOV	#H'C0,R0

	MOV	#0,R1		; IF CURRVP>VCYCLE,0 -> CURRVP

SYNI1:	EXTU.B	R0,R0
	CMP/HS	R0,R1		; CURRVP>=192 ?
	BT/S	SYNI2		 垂直位置≧192(垂直ブランク)か?
	MOV	#H'48,R0	; ENABLE MATCH-D,DISABLE MATCH-A
				 垂直ブランク期間ならコンペアマッチA割り込み禁止
	OR	#H'01,R0	; IF CURRVP<192,ENABLE MATCH-A
				 垂直表示期間ならコンペアマッチA割り込みを許可

SYNI2:	MOV.B	R0,@R3		; SET TIER_3

	MOV.W	@(2,R2),R0	; VSYPOS 垂直同期パルス位置
	MOV	#114,R3		; 4.7 MICRO SEC 垂直同期期間でなければ
	CMP/HS	R0,R1				パルス幅を4.7μ秒に設定
	BF	SYNI3

	ADD	#3,R0		; VSYNC PULSE:3H
	CMP/HS	R0,R1
	BT	SYNI3

	MOV.W	VSYWID,R3	 垂直同期期間ならパルス幅を63.5-4.7μ秒に設定

SYNI3:	MOV.L	TGRC3_1,R0
	ADD	#1,R1		 現在の垂直位置を+1する
	MOV.W	R1,@R2		; UPDATE CURRVP
	MOV.L	TSR3_1,R1
	MOV.W	R3,@R0		; SET PULSE WIDTH(TGRC_3)

	MOV.B	@R1,R0		; READ TSR_3
	MOV.L	@R15+,R3
	MOV.L	@R15+,R2
	AND	#H'F6,R0	; CLEAR MATCH-D,MATCH-A FLAG 割り込みフラグクリヤ
	MOV.B	R0,@R1		 フラグDをクリヤするのは当然ですが、ここでフラグAもクリヤ
				 するのがポイントです。理由は皆さんで考えてみてください。
				 (私は最初ここでフラグAをクリヤせず、ハマりました)
	MOV.L	@R15+,R1
	MOV.L	@R15+,R0
	RTE
	NOP

VCYCLE:	DC.W	263
VSYWID:	DC.W	1559-114


・表示処理(コンペアマッチA割り込み)

DSPINT:	MOV.L	R0,@-R15
	MOV.L	R1,@-R15
	MOV.L	R2,@-R15
	MOV.L	R3,@-R15
	MOV.L	R4,@-R15

	MOV.L	CRTWRK1,R2
	MOV.L	VRAM1,R3
	MOV.L	PEDRL1,R4	 高速化のためポートELのアドレスをR4に入れておく

	MOV.W	@R2,R0		; CURRVP
	MOV	#32,R1		; 32 BYTES/LINE
	ADD	#-1,R0		; ALREADY INCREMENTED BY SYNINT
	AND	#H'FE,R0	; VERTICAL 2 LINES/DOT
	SHLL2	R0		; CALC VRAM ADDRESS
	SHLL2	R0		 垂直位置からVRAMのアドレスを計算
	ADD	R0,R3

DSPIL1:	MOV.B	@R3+,R0		; 1	; 17	 1バイト読み込み
	MOV	#4,R2		; 2	; 18	; 4 DOTS/BYTE
	NOP			; 3	; 19

DSPIL2:	SHLL2	R0		; 4	; 20
	MOV.W	R0,@R4		; 6	; 22	; VIDEO DATA OUT
	NOP			; 7		 どのループ経路を通っても MOV,W R0,@R4 を
	NOP			; 8		 実行する周期が16クロックになるようにします
	DT	R2		; 9
	BT/S	DSPI2		; 10/12		4ドット出力したか?
	NOP			; 11

	NOP			; 12
	NOP			; 13
	NOP			; 14
	NOP			; 15
	NOP			; 16
	BRA	DSPIL2		; 17		バイト内4ドット出力ループ
	NOP			; 19

DSPI2:	DT	R1		; 13		32バイト(128ドット)出力したか?
	BF/S	DSPIL1		; 14/16
	NOP			; 15

	MOV.L	TSR3_1,R2	; 16
	NOP			; 17
	MOV	#0,R1		; 18
	MOV.B	@R2,R0		; 20	; READ TSR_3
	MOV.W	R1,@R4		; 22	; VIDEO OUT OFF	 輝度出力を0にする

	MOV.L	@R15+,R4
	MOV.L	@R15+,R3
	AND	#H'FE,R0	; CLEAR MATCH-A FLAG	 割り込みフラグクリヤ
	MOV.B	R0,@R2

	MOV.L	@R15+,R2
	MOV.L	@R15+,R1
	MOV.L	@R15+,R0
	RTE
	NOP

	ALIGN	4

CRTWRK1:	DC.L	CRTWRK
PEDRL1:		DC.L	PEDRL
TIER3_1:	DC.L	TIER_3
TGRC3_1:	DC.L	TGRC_3
TSR3_1:		DC.L	TSR_3
VRAM1:		DC.L	RAMTOP