
	PAGE

;********************************************************
;*							*
;*		RSTルーチン				*
;*							*
;********************************************************

		ORG	$00
RST_0						; リセット
		JP	RESET


		ORG	$08
RST_1						; ROMバンク切り替えてジャンプ
		LD	(ROM_BANK),A
		LD	(MBCBANKREG),A
		JP	(HL)


		ORG	$10
RST_2						; ROMバンク切り替えてコール
		LD	A,(ROM_BANK)
		PUSH	AF
		LD	A,B
		RST	1
		POP	AF
		LD	(ROM_BANK),A
		LD	(MBCBANKREG),A
		RET


		ORG	$20
RST_4						; メインルーチン分岐
		LD	A,(MAIN_B)
		LD	HL,ROM_BANK
		CP	(HL)
		JP	Z,MAIN
		LD	HL,MAIN
		JR	RST_1


		ORG	$30
RST_6						; IDジャンプ
		ADD	A,A
		POP	HL
		LD	E,A
		LD	D,$00
		ADD	HL,DE
		LD	E,(HL)
		INC	HL
		LD	D,(HL)
		PUSH	DE
		POP	HL
		JP	(HL)

;********************************************************
;*							*
;*		割り込みベクタ				*
;*							*
;********************************************************

		ORG	$40			; V-BLANK割り込み
		JP	VBLK

		ORG	$48			; H-BLANK割り込み
		JP	HBLK

		ORG	$50			; TIMER割り込み
		JP	TIMER

		ORG	$58			; SIO割り込み
		JP	SIO

		ORG	$60			; KEY入力割り込み
		JP	KEY_TEST_PORT_INT
		RETI

;********************************************************
;*							*
;*		LCDC作動と停止				*
;*							*
;********************************************************

LCDC_ON
		LD	A,(LCDC_BUF)
		SET	LCDC_START_BIT,A
		LD	(LCDC_BUF),A
		LD	(LCDC),A
		RET


LCDC_OFF
		LD	HL,IE			; V-BLANK割り込み禁止
		RES	IE_VBLK_BIT,(HL)

_10		LD	A,(LY)			; V-BLANK待ち
		CP	144
		JR	C,_10

		LD	A,(LCDC_BUF)		; LCDCストップ
		RES	LCDC_START_BIT,A
		LD	(LCDC_BUF),A
		LD	(LCDC),A

		SET	IE_VBLK_BIT,(HL)	; V-BLANK割り込み許可
		RET


;********************************************************
;*							*
;*		DMA転送ルーチン				*
;*							*
;********************************************************

DMA_DATA
		LD	A,>OBJRAM		; A <- $C0
		LD	(DMA),A			; DMA転送
		LD	A,40			; 160サイクルウェイト
_10		DEC	A
		JR	NZ,_10
		RET


;********************************************************
;*							*
;*		キー入力				*
;*							*
;*		CNT1 =   べた入力			*
;*		TRG1 = トリガ入力			*
;*							*
;*		|    6			   |		*
;*		| 5     4    2  3    1   0 |		*
;*		|    7			   |		*
;*							*
;********************************************************

CONT
		LD	A,$20			; D,U,L,Rキー読み込み
		LD	(P1),A
		LD	A,(P1)
		LD	A,(P1)
		CPL
		AND	$0F
		SWAP	A
		LD	B,A
		LD	A,$10			; ST,SE,B,Aキー読み込み
		LD	(P1),A
		PUSH	AF			; 読み込みが安定するまでの時間調整
		POP	AF
		PUSH	AF
		POP	AF
		LD	A,(P1)
		CPL
		AND	$0F
		OR	B
		LD	C,A
		LD	A,(CNT1)
		XOR	C
		AND	C
		LD	(TRG1),A
		LD	A,C
		LD	(CNT1),A

		LD	A,$30			; ポートリセット
		LD	(P1),A
		RET


;********************************************************
;*							*
;*		メモリ転送 (A Reg.-> メモリ)		*
;*							*
;*	HL:先頭アドレス, BC:個数, D:転送データ		*
;*							*
;********************************************************

MOV_A
		LD	A,D
		LD	(HLI),A
		LOOP_BC	MOV_A
		RET


;********************************************************
;*							*
;*		メモリ転送 (A Reg.-> メモリ)		*
;*							*
;*	HL:先頭アドレス, B:個数, A:転送データ		*
;*							*
;********************************************************

MOVB_A
		LD	(HLI),A
		DEC	B
		JR	NZ, MOVB_A
		RET


;********************************************************
;*							*
;*		メモリ転送 (メモリ -> メモリ)		*
;*							*
;*	DE:転送元アドレス, HL:転送先アドレス, BC:個数	*
;*							*
;********************************************************

MOV_M
		LD	A,(DE)
		LD	(HLI),A
		INC	DE
		LOOP_BC	MOV_M
		RET


;********************************************************
;*							*
;*		メモリ転送 (メモリ -> メモリ)		*
;*							*
;*	DE:転送元アドレス, HL:転送先アドレス, B:個数	*
;*							*
;********************************************************

MOVB_M
		LD	A,(DE)
		LD	(HLI),A
		INC	DE
		DEC	B
		JR	NZ,MOVB_M
		RET


;********************************************************
;*							*
;*		プログラムスタート			*
;*							*
;********************************************************

		ORG	$150

RESET
		LD	A,(LY)			; V-BLANK待ち
		CP	144
		JR	C,RESET
SOFT_RESET
		DI
		XOR	A
		LD	(LCDC),A		; LCDCストップ
		LD	(IF),A
		LD	(IE),A

		LD	SP,$FFFE		; スタックポインタ設定

		LD	A,VBK_1			; RAMチェック
		LD	(VBK),A
		VERIFY	VRAM,$2000		; $8000〜$9FFF
		LD	A,VBK_0
		LD	(VBK),A
		VERIFY	VRAM,$2000

		VERIFY	WRAML,$1000		; $C000〜$CFFF
		LD	B,7
		LD	C,0
_00		LD	HL,SVBK
		LD	(HL),C
		PUSH	BC
		VERIFY	WRAMH,$1000		; $D000〜$DFFF
		POP	BC
		INC	C
		DEC	B
		JR	NZ,_00

		VERIFY	OAM,160			; $FE00〜$FE9F

		VERIFY	$FF80,$FFFC-$FF80	; $FF80〜$FFFB
		XOR	A
		LD	HL,$FFFC
		LD	(HLI),A
		LD	(HLI),A
		LD	(HLI),A

		LD	SP,STACK		; スタックポインタ再設定

		MOVB	DMA_DATA,DMAEXE,10	; DMA転送ルーチンセット

		XOR	A
		LD	(SCY),A
		LD	(SCX),A
		LD	(LYC),A

		LD	A,WY_MIN		; ウィンドウ初期値セット
		LD	(WY_BUF),A
		LD	(WY),A
		LD	A,WX_MIN
		LD	(WX_BUF),A
		LD	(WX),A

		PLTSET	MAIN_PLT,BCPS		; カラーパレットセット
		PLTSET	MAIN_PLT,OCPS

		LD	A,%11100100		; モノクロパレットセット
		LD	(BGP),A
		LD	(OBP0),A
		LD	A,%00011011
		LD	(OBP1),A

		LD	A,IE_VBLK | IE_LCDC	; V-BLANK,LCDC割り込み許可
		LD	(IE_BUF),A

		LD	A,STAT_INT_HBLK		; モード00選択
		LD	(STAT),A

		LD	A,LCDC_START | LCDC_OBJ_ON | LCDC_BG_ON
		LD	(LCDC_BUF),A
		CALL	LCDC_ON

;--------------------------------------------------------

		LD	A,$80
		LD	(NR52),A		; SOUND ON
		LD	A,$77			; VOLUME MAX & EXT IN OFF
		LD	(NR50),A		; TOTAL LEVEL
		LD	A,$FF
		LD	(NR51),A		; SOUND RIGHT/LEFT

		LD	A,1			; バンク設定
		SET_ROMBANK

		VECTOR	VBLK,VBLK_INT		; V-BLANK割り込みベクタセット
		VECTOR	HBLK,HBLK_INT		; H-BLANK割り込みベクタセット
		VECTOR	TIMER,TIMER_INT		; TIMER割り込みベクタセット
		VECTOR	SIO,SIO_INT		; SIO割り込みベクタセット

		CALL	INIT_DEBUG_ADDR		; メモリダンプ時の初期アドレスセット

		NEXT_MAIN	SET_BG_TITLE	; タイトル画面セット

		CALL	IE_SET			; IEレジスタセット
		EI				; 割り込み許可

LOOP
		RST	4			; メイン処理分岐

_30		LD	A,(LY)			; V-BLANK待ち
		CP	144
		JR	C,_30

		CALL	VBLK_EXEC		; V-BLANK期間中の処理

		XOR	A
		LD	(HBLK_FLG),A

		LD	A,(CNT1)
		CP	ST_KEY | SE_KEY | B_KEY | A_KEY
		JR	NZ,LOOP
		JP	SOFT_RESET


;********************************************************
;*							*
;*		CPUクロック速度切替			*
;*							*
;********************************************************

CHG_CPU_SPEED
		LD	HL,KEY1
		SET	0,(HL)
		XOR	A
		LD	(IF),A
		LD	(IE),A			; 割り込み許可フラグリセット
		LD	A,$30
		LD	(P1),A			; キーポートリセット
		STOP

		CALL	IE_SET
		NEXT_MAIN	SET_BG_TITLE
		RET


;********************************************************
;*							*
;*		V-BLANK処理終了待ち			*
;*							*
;********************************************************

VBWAIT
		HALT
		LD	A,(VBLK_FLG)
		AND	A
		JR	Z,VBWAIT
VBFLG_RESET
		XOR	A
		LD	(VBLK_FLG),A
		RET


;********************************************************
;*							*
;*		IEレジスタセット			*
;*							*
;********************************************************

IE_SET
		XOR	A
		LD	(IF),A
		LD	A,(IE_BUF)
		LD	(IE),A
		RET


;********************************************************
;*							*
;*		サブルーチンのベクタをセット		*
;*			HL:VECTOR, DE:FUNC 		*
;*							*
;********************************************************

SET_FUNC_VECTOR
		DI
		LD	A, $C3			; C3 == JP OPCODE
		LD	(HLI),A
		LD	A,E
		LD	(HLI),A
		LD	A,D
		LD	(HL),A
		EI
		RET


;********************************************************
;*							*
;*		メイン処理の分岐アドレスをセット	*
;*			A::FUNC, DE:FUNC 		*
;*							*
;********************************************************

SET_MAIN_FUNC
		LD	HL,MAIN_B
		LD	(HLD),A			; MAIN_B
		LD	A,D
		LD	(HLD),A			; MAIN_H
		LD	A,E
		LD	(HLD),A			; MAIN_L
		LD	A,$C3
		LD	(HL),A			; MAIN = JP OPCODE
		RET


;********************************************************
;*							*
;*		カラーパレットデータセット		*
;*		DE;先頭アドレス, HL;パレット		*
;*							*
;********************************************************

SET_PLT
		LD	B,64			; 2バイト * 4色 * 8パレット
		LD	A,PLT_AUTO_INC
		LD	(HLI),A
_10		LD	A,(DE)
		LD	(HL),A
		INC	DE
		DEC	B
		JR	NZ,_10
		RET


;********************************************************
;*							*
;*		BGデータセット				*
;*		  DE:先頭アドレス			*
;*							*
;*		  コントロールコード			*
;*			VRAM-H ADDR			*
;*			VRAM-L ADDR			*
;*			DATA-SIZE			*
;*			D7 = 0: 横			*
;*			     1: 縦			*
;*			D6 = 0: ランダムデータ		*
;*			     1: 共通データ		*
;*			D5-D0 = データ個数		*
;*				DATA1			*
;*				DATA2			*
;*				  ･			*
;*				  ･			*
;*		  (エンドコード) $00			*
;*							*
;********************************************************

SET_BG
		LD	A,(DE)			; コントロールコードリード
		CP	$00
		RET	Z
		LD	H,A			; WRITE ADDR.HIGH
		INC	DE
		LD	A,(DE)
		LD	L,A			; WRITE ADDR.LOW
		INC	DE
		LD	A,(DE)			; CNT.CODE
		INC	DE

		PUSH	AF			; コントロールコード展開
		AND	%00111111
		LD	B,A			; 個数
		POP	AF
		RLCA
		RLCA
		AND	%00000011
		JR	Z,_00
		DEC	A
		JR	Z,_01
		DEC	A
		JR	Z,_10
		JR	_11

_00		LD	A,(DE)			; 横,ランダムデータ
		LD	(HLI),A
		INC	DE
		DEC	B
		JR	NZ,_00
		JR	SET_BG

_01		LD	A,(DE)			; 横,共通データ
		INC	DE
_02		LD	(HLI),A
		DEC	B
		JR	NZ,_02
		JR	SET_BG

_10		LD	A,(DE)			; 縦,ランダムデータ
		LD	(HL),A
		INC	DE
		LD	A,B
		LD	BC,$0020
		ADD	HL,BC
		LD	B,A
		DEC	B
		JR	NZ,_10
		JR	SET_BG

_11		LD	A,(DE)			; 縦,共通データ
		LD	(HL),A
		LD	A,B
		LD	BC,$0020
		ADD	HL,BC
		LD	B,A
		DEC	B
		JR	NZ,_11
		INC	DE
		JR	SET_BG


;********************************************************
;*							*
;*		スクリーンライン表示			*
;*							*
;********************************************************

CHR_LINE
		LD	A,VBK_0
		LD	(VBK),A
		LD	HL,CHRRAM
		LD	BC,384			; 384 CHR

_10		LD	A,$FF
		LD	(HLI),A
		INC	HL
		LD	D,7
_20		LD	A,(HL)
		OR	$80
		LD	(HLI),A
		INC	HL
		DEC	D
		JR	NZ,_20

		LOOP_BC	_10
		RET


;********************************************************
;*							*
;*		RAMチェック				*
;*							*
;********************************************************

RAM_ERROR_DSP_ADDR	=	$9901
RAM_DATA_DSP_ADDR	=	$9909
RAM_VBK_DSP_ADDR	=	$9963
RAM_SVBK_DSP_ADDR	=	$996B

RAM_ERROR_DSP_DATA
		DB	FONT_R,FONT_A,FONT_M,FONT_R_E,FONT_R_RA,FONT_R_B
RAM_VBK_DSP_DATA
		DB	FONT_V,FONT_B,FONT_K,FONT_CLN
RAM_SVBK_DSP_DATA
		DB	FONT_S,FONT_V,FONT_B,FONT_K,FONT_CLN

RAM_ERROR
		PUSH	AF
		PUSH	DE
		PUSH	HL

		LD	A,(VBK)				; RAMバンクレジスタ退避
		LD	(R0),A
		LD	A,(SVBK)
		LD	(R1),A

		LD	A,(LCDC)
		BIT	LCDC_START_BIT,A
		CALL	NZ,LCDC_OFF

		PLTSET	MAIN_PLT,BCPS

		CHRSET	CHR_DATA,VBK_0

		BGCLR	$00,VBK_1
		BGCLR	SPACE,VBK_0

		MOVB	RAM_ERROR_DSP_DATA,RAM_ERROR_DSP_ADDR,6
		MOVB	RAM_VBK_DSP_DATA,RAM_VBK_DSP_ADDR,4
		MOVB	RAM_SVBK_DSP_DATA,RAM_SVBK_DSP_ADDR,5

		POP	HL				; エラーアドレス
		LD	A,H
		LD	BC,RAM_DATA_DSP_ADDR
		CALL	GET_NUM
		LD	A,L
		LD	BC,RAM_DATA_DSP_ADDR +2
		CALL	GET_NUM

		POP	DE				; ライトデータ
		LD	A,D
		LD	BC,RAM_DATA_DSP_ADDR +5
		CALL	GET_NUM

		POP	AF				; リードデータ
		LD	BC,RAM_DATA_DSP_ADDR +8
		CALL	GET_NUM

		LD	A,(R0)				; VBKバンクNo.
		LD	BC,RAM_VBK_DSP_ADDR +4
		CALL	GET_NUM

		LD	A,(R1)				; SVBKバンクNo.
		LD	BC,RAM_SVBK_DSP_ADDR +5
		CALL	GET_NUM

		LD	A,LCDC_BG_ON
		LD	(LCDC_BUF),A
		CALL	LCDC_ON

_BP0		JR	_BP0				; エラーストップ


CHECK_DATA	MACRO	DATA
		LD	(HL),DATA
		LD	D,DATA
		LD	A,(HL)
		CP	DATA
		JP	NZ,RAM_ERROR
		ENDM


RAM_CHECK
		CHECK_DATA	$55
		CHECK_DATA	$AA
		CHECK_DATA	$FF
		CHECK_DATA	$00
		INC	HL
		LOOP_BC	RAM_CHECK
		RET


;********************************************************

	END
