/* */ /* アプリケーション初期化プログラムサンプル */ /* V1.10 '94.11.11 S.U and T.S */ /* */ /* 動作タイミングと機能について: */ /* ライセンス画面表示中に、不定になっている各種デバイス */ /* 状態や、そのメモリのクリアなどを行ないます。 */ /* 処理の所要時間は、0.1 秒程度かかります。 */ /* 終了後、先読みしておいたプログラムの実行に移ります。 */ /* その実行開始アドレスは APP_ENTRY に定義してください。 */ /* */ /* リンケージについて: */ /* IPの sys_init.obj の直後にリンクしてください。 */ /* プログラムをこのまま使用した場合、約360Hバイトに */ /* なり、IPサイズは1000Hを越えますので注意して */ /* ください。 */ /* */ /* プログラム変更時の注意: */ /* main() の前に実行文を含む関数を追加しないでください。 */ /* */ #include "sega_sys.h" /* 先読みしたプログラムの実行開始アドレス(メイン処理完了後にジャンプ)*/ #define APP_ENTRY (0x06003000) /* デバイスを初期化するルーチン */ static void vd1Comfil(void); /* VDP1 クリッピング初期化 */ static void vd2Ramfil(void); /* VDP2 VRAMクリア */ static void colRamfil(void); /* カラーRAMクリア */ static void sndRamfil(Sint32); /* サウンドRAMクリア */ static void scuDspInit(void); /* SCU DSP 初期化 */ static void msh2PeriInit(void); /* マスタSH周辺モジュール初期化 */ static void sndDspInit(void); /* サウンドDSPクリア */ /* その他サブルーチン */ static void vbIrtn(void); /* VB-In 割込み処理 */ static void vbOrtn(void); /* VB-Out 割込み処理 */ static void syncVbI(void); /* VB-In 同期処理用 */ #ifndef __GNUC__ static void memset_w(Sint16 *, Sint16, Sint32); /* ワード memset */ static void memcpy_w(Sint16 *, Sint16 *, Sint32); /* ワード memcpy */ static Sint16 *blkmfil_w(Sint16 *, Sint16, Sint32); /* ワード・ブロックfill */ static Sint32 *blkmfil_l(Sint32 *, Sint32, Sint32); /* ロングワード・ブロックfill */ #else static void memset_w(volatile Sint16 *, Sint16, Sint32); static void memcpy_w(volatile Sint16 *, Sint16 *, Sint32); static void blkmfil_w(volatile Sint16 *, Sint16, Sint32); /* ワード・ブロックfill */ static void blkmfil_l(volatile Sint32 *, Sint32, Sint32); /* ロングワード・ブロックfill */ #endif /* 現時点の(ライセンス画面表示中)画面サイズに関する情報 */ #define XRES (320) /* ライセンス画面の水平サイズ */ #define SCLIP_UX (XRES-1) /* 〃 */ #define SCLIP_UY_N (224-1) /* 〃 (NTSCの場合) */ #define SCLIP_UY_P (256-1) /* 〃 (PALの場合) */ /* 処理対象デバイスのベースアドレス */ #define SND_RAM ((volatile Sint32 *)0x25a00000) #define VD1_VRAM ((volatile Sint16 *)0x25c00000) #define VD1_REG ((volatile Sint16 *)0x25d00000) /* VD2_VRAM は、ライセンス表示で使用中のVRAM領域を除く */ #define VD2_VRAM ((volatile Sint32 *)0x25e08004) /* COL_RAM は、ライセンス表示で使用中のカラーRAM領域を除く */ #define COL_RAM ((volatile Sint16 *)0x25f00020) #define VD2_REG ((volatile Sint16 *)0x25f80000) #define SCSP_DSP_RAM ((volatile Sint16 *)0x25b00800) /* SMPCレジスタ */ #define SMPC_REG(ofs) (*(volatile Uint8 *)(0x20100000+ofs)) /* SCUレジスタ */ #define DSP_PGM_CTRL_PORT (*(volatile Sint32 *)0x25fe0080) #define DSP_PGM_RAM_PORT (*(volatile Sint32 *)0x25fe0084) #define DSP_DATA_RAM_ADRS_PORT (*(volatile Sint32 *)0x25fe0088) #define DSP_DATA_RAM_DATA_PORT (*(volatile Sint32 *)0x25fe008c) /* SCSP サウンドRAMサイズレジスタ */ #define SCSP_SNDRAMSZ (*(volatile Sint8 *)0x25b00400) /* SH2周辺モジュールレジスタ */ #define MSH2_DMAC_SAR(ofs) (*(volatile Sint32 *)(0xffffff80 + ofs)) #define MSH2_DMAC_DAR(ofs) (*(volatile Sint32 *)(0xffffff84 + ofs)) #define MSH2_DMAC_TCR(ofs) (*(volatile Sint32 *)(0xffffff88 + ofs)) #define MSH2_DMAC_CHCR(ofs) (*(volatile Sint32 *)(0xffffff8c + ofs)) #define MSH2_DMAC_DRCR(sel) (*(volatile Sint8 *)(0xfffffe71 + sel)) #define MSH2_DMAC_DMAOR (*(volatile Sint32 *)(0xffffffb0)) #define MSH2_DIVU_CONT (*(volatile Sint32 *)(0xffffffb8)) /* メインの処理に関する情報 */ /* 現在ライセンス表示中、16ビット1024色モードを使用 */ /* VDP2のVRAMとカラーRAMは4回に分けてクリア */ /* VRAMは1回に 20000H バイト(表示中部分を除く) */ /* カラーRAMは1回に 200H バイト(表示中部分を除く) */ #define MSETDIV (4) #define BLKMSK_VD2_VRAM (0x1fffc) #define BLKMSK_COL_RAM (0x001fe) /* サウンドRAMは3手順でクリア */ #define M68000_VECTBLSZ (0x00400/sizeof(Sint32)) #define BLKMSK_SND_RAM (0x003fc) /* サウンドDSP RAMサイズ */ #define SCSP_DSP_RAMSZ (0x00400) /* 割込み処理に関する情報 */ #define VBI_NUM (0x40) /* VBイン割込み番号 */ #define VBO_NUM (0x41) /* VBアウト割込み番号 */ #define VB_MASK (0x0003) /* SCU割込みマスク2つ分 */ /* スタティック変数 */ static Sint16 yBottom, ewBotRight; static Sint16 vdp1cmds[48]; #ifndef __GNUC__ /* static Sint16 vbIcnt = 0, sequence = 0; */ static Sint16 vbIcnt = 0, sequence = 0; static Sint32 *vramptr = VD2_VRAM; static Sint16 *cramptr = COL_RAM; #else static volatile Sint16 vbIcnt = 0, sequence = 0; static volatile Sint32 *vramptr = VD2_VRAM; static volatile Sint16 *cramptr = COL_RAM; #endif /* メイン処理 */ void main(void) { /* 注意:AUTO 変数をとると、APP_ENTRY のプログラムに */ /* 制御が移るとき、スタックが若干無駄になる */ yBottom = (VD2_REG[2]&1)? SCLIP_UY_P: SCLIP_UY_N; ewBotRight = ((XRES/8)<<9)+(yBottom); /* 画面縦上限= 223(NTSC) or 255(PAL) */ SYS_SETUINT(VBI_NUM, vbIrtn); /* VBイン処理登録 */ SYS_SETUINT(VBO_NUM, vbOrtn); /* VBアウト 〃 */ SYS_CHGSCUIM( ~VB_MASK, 0); /* VB割込み2つ許可 */ vd1Comfil(); /* VDP1初期化 */ for (sequence = 0; sequence < MSETDIV; sequence++) { syncVbI(); /* カラーRAMクリアのため同期 */ colRamfil(); /* カラーRAMクリア */ vd2Ramfil(); /* VDP2RAMクリア */ sndRamfil(sequence); /* サウンドRAMクリア */ } scuDspInit(); /* SCUのDSP初期化 */ msh2PeriInit(); /* SH周辺モジュール〃 */ sndDspInit(); /* サウンドDSP 〃 */ SYS_CHGSCUIM( -1, VB_MASK); /* VB割込み2つ禁止 */ SYS_SETUINT(VBI_NUM, (void(*)())0 ); /* フック */ SYS_SETUINT(VBO_NUM, (void(*)())0 ); /* 再初期化 */ ((void(*)())APP_ENTRY)(); /* 次の実行開始アドレス */ } #ifndef __GNUC__ static void memset_w(Sint16 *buf, Sint16 pattern, Sint32 size) #else static void memset_w(volatile Sint16 *buf, Sint16 pattern, Sint32 size) #endif { register Sint32 i; for (i = 0; i < size; i+= sizeof(Sint16)) { *buf++ = pattern; } } #ifndef __GNUC__ static void memcpy_w(Sint16 *dst, Sint16 *src, Sint32 size) #else static void memcpy_w(volatile Sint16 *dst, Sint16 *src, Sint32 size) #endif { register Sint32 i; for (i = 0; i < size; i+= sizeof(Sint16)) { *dst++ = *src++; } } /* blkmfilは、区切りのいいアドレス範囲をmemsetするもの */ #ifndef __GNUC__ static Sint16 *blkmfil_w(Sint16 *buf, Sint16 pattern, Sint32 brkmsk) #else static void blkmfil_w(volatile Sint16 *buf, Sint16 pattern, Sint32 brkmsk) #endif { register Sint32 i; #ifndef __GNUC__ i = (Sint32)buf & brkmsk; #else i = (volatile Sint32)buf & brkmsk; #endif for (; i <= brkmsk; i+= sizeof(Sint16)) { *buf++ = pattern; } #ifndef __GNUC__ return (buf); #endif } #ifndef __GNUC__ static Sint32 *blkmfil_l(Sint32 *buf, Sint32 pattern, Sint32 brkmsk) #else static void blkmfil_l(volatile Sint32 *buf, Sint32 pattern, Sint32 brkmsk) #endif { register Sint32 i; #ifndef __GNUC__ i = (Sint32)buf & brkmsk; #else i = (volatile Sint32)buf & brkmsk; #endif for (; i <= brkmsk; i+= sizeof(Sint32)) { *buf++ = pattern; } #ifndef __GNUC__ return (buf); #endif } /* VBインは、割込みでスタティック変数をインクリメントするのみ */ static void vbIrtn(void) { vbIcnt++; } /* VBアウトは、割込みでVDP1レジスタをコントロールするのみ */ static void vbOrtn(void) { #ifndef __GNUC__ register Sint16 *vdp1r; #else register volatile Sint16 *vdp1r; #endif /* イレースライトでフレームバッファをクリア */ vdp1r = VD1_REG; *vdp1r++ = 0x0; /* 1/60秒自動描画モード */ *vdp1r++ = 0x0; *vdp1r++ = 0x2; *vdp1r++ = 0x0; /* イレースライトは透明色 */ *vdp1r++ = 0x0; /* 〃 左上座標 */ *vdp1r = ewBotRight; /* 〃 右下座標 */ } /* VBI同期は、呼ばれると待ち、VBI直後に抜けて戻る */ static void syncVbI(void) { register Sint32 cur_cnt_value; /* 待つのはカラーRAMクリアのため */ cur_cnt_value = vbIcnt; while (cur_cnt_value == vbIcnt); } /* VDP1に、システムクリッピングとローカル座標を読ませる */ static void vd1Comfil(void) { register Sint16 *cmdbuf; memset_w((cmdbuf=vdp1cmds), 0, sizeof(vdp1cmds)); cmdbuf[0] = 0x0009; cmdbuf[10] = SCLIP_UX; cmdbuf[11] = yBottom; cmdbuf[16] = 0x000a; cmdbuf[32] = 0x8000; memcpy_w(VD1_VRAM, vdp1cmds, sizeof(vdp1cmds)); } /* VDP2のRAMを、1/4ずつクリア */ static void vd2Ramfil(void) { #ifndef __GNUC__ vramptr = blkmfil_l(vramptr, 0, BLKMSK_VD2_VRAM); #else blkmfil_l(vramptr, 0, BLKMSK_VD2_VRAM); #endif } /* カラーRAMを、1/4ずつクリア */ static void colRamfil(void) { #ifndef __GNUC__ cramptr = blkmfil_w(cramptr, 0, BLKMSK_COL_RAM); #else blkmfil_w(cramptr, 0, BLKMSK_COL_RAM); #endif } /* サウンドRAMを、3手順でクリア */ static void sndRamfil(Sint32 initstep) { #ifndef __GNUC__ register Sint32 *memptr; #else register volatile Sint32 *memptr; #endif switch (initstep) { case 0: SMPC_REG(31) = 7; /* M68000を停止 */ break; case 1: SCSP_SNDRAMSZ = 2; /* サウンドRAMサイズ設定 */ /* サウンドRAM先頭400H */ memptr = SND_RAM; /* (ベクタ)に400Hをフィル */ blkmfil_l(memptr, 0x400, BLKMSK_SND_RAM); *memptr = 0x0007fffc; /* SP初期値をセット */ memptr += M68000_VECTBLSZ; *memptr = 0x4e7160fc; /* アドレス400Hに NOPと */ /* BRA @−2 命令を書込み */ break; case 2: SMPC_REG(31) = 6; /* M68000起動(無限待ち) */ break; /* 備考: 1イントの間がある */ } /* ため、SMPCステータスの */ } /* セット/チェックを省略 */ static void msh2PeriInit(void) { register Sint32 i, ofs, dummy; ofs = 0; for(i = 0;i < 2; i++) { /* DMAC各レジスタを初期化 */ MSH2_DMAC_SAR(ofs) = 0x00000000; MSH2_DMAC_DAR(ofs) = 0x00000000; MSH2_DMAC_TCR(ofs) = 0x00000001; dummy = MSH2_DMAC_CHCR(ofs); MSH2_DMAC_CHCR(ofs) = 0x00000000; MSH2_DMAC_DRCR(i) = 0x00; ofs = 0x10; } dummy = MSH2_DMAC_DMAOR; MSH2_DMAC_DMAOR = 0x00000000; /* DIVU割込みを不許可 */ MSH2_DIVU_CONT = 0x00000000; } static void scuDspInit(void) { register Sint32 i; DSP_PGM_CTRL_PORT = 0x0; /* DSP停止 */ for(i = 0; i < 256; i++) DSP_PGM_RAM_PORT = 0xf0000000; /* END命令フィル */ for(i = 0; i < 256; i++){ /* DSP RAMクリア */ DSP_DATA_RAM_ADRS_PORT = i; DSP_DATA_RAM_DATA_PORT = 0x0; } } static void sndDspInit(void) { memset_w(SCSP_DSP_RAM, 0, SCSP_DSP_RAMSZ); /* サウンドDSP */ } /* プログラム領域クリア */