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