;スーパーインポーズテレビ電卓 おさやん 作 おさやんの小道具 HP掲載 2007-10-27 ;概要 ;10桁計算 ;保存用レジスタ10桁 RegV(表示用) Reg1 Reg2 Mem(メモリー) ;計算用レジスタ20桁 RegA RegB RegC ;各レジスタは1桁1バイト*桁数+指数1バイト+STATUS1バイト(Z,N,C) ;計算と入力は別々に行う。 ;IntIO:I/O,割込み等初期化→ ;INT_V:垂直同期割込→ ;Calc :垂直同期後入力されていれば計算処理→ ; キー入力割込み許可 → ;Input:キー割込・入力処理→ ;INT_H:水平同期割込→ ; キー割込み禁止、電卓の表示 ; →INT_V ;平方根は時間がかかるので分割して計算 ;PIC LIST P=PIC18F1320 #include ;CONFIG __CONFIG _CONFIG1H, _IESO_OFF_1H & _FSCM_OFF_1H & _HSPLL_OSC_1H __CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_OFF_2L & _BORV_45_2L __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_32K_2H __CONFIG _CONFIG3H, _MCLRE_ON_3H __CONFIG _CONFIG4L, _DEBUG_OFF_4L & _LVP_OFF_4L & _STVR_OFF_4L ;***** All memory protect Off __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L __CONFIG _CONFIG7H, _EBTRB_OFF_7H ;変数 DMax equ 0AH VMax equ DMax+1 VRAM equ 0 V1 equ VRAM ;M - Eなどの表示エリア ;保存用10桁レジスタ RegV equ VRAM+1 VExp equ RegV+DMax ;Exponent指数 VStatus equ VExp+1 ;N(負) C(キャリー(エラー)) Z(ゼロ)フラグ Reg1 equ RegV+DMax+2 Reg2 equ Reg1+DMax+2 Mem equ Reg2+DMax+2 MStatus equ Mem+DMax+1 TV_OutF equ MStatus+1 ;表示関連フラグ&カウンタ ;CG_Line equ 0-3 ;CGの読み出し中ライン DotLine equ 4 ;小数点ライン表示中 Off equ 5 ;表示のOff/Onフラグ Key1 equ TV_OutF+1 ;入力キー KeyF equ Key1+1 ;入力関連フラグ Parity equ 0 ;パリティービット Break equ 1 ;ブレイク信号受信フラグ DotKey equ 2 ;小数点打鍵フラグ ClrFlag equ 3 ;次の数字入力時にクリアーする TestFlag equ 7 ;キー入力テスト用フラグ ;ICSPよりPICをリセットするとキー入力テストができます。 TempK equ KeyF+1 ;キー入力で使用 FX equ TempK+1 ;2項演算子の控え FX2 equ FX+1 ;1つ前の2項演算子の控え FXF equ FX2+1 ;付加計算フラグ EquF equ 0 ;連続演算 =か%を押した(Inputで使用) Percent equ 1 ;%を押した(Input,Calcで使用) MemAdd equ 2 ;M+を押した(Input,Calcで使用) MemSub equ 3 ;M-を押した(Input,Calcで使用) Cnt1 equ FXF+1 ;繰り返し処理用 Cnt2 equ Cnt1+1 CntSqr equ Cnt2+1 ;平方根分割計算用カウンタ ;計算用20桁レジスタ RegA equ CntSqr+1 AExp equ RegA+DMax*2 AStatus equ RegA+DMax*2+1 RegB equ RegA+DMax*2+2 BExp equ RegB+DMax*2 BStatus equ RegB+DMax*2+1 RegC equ RegB+DMax*2+2 CExp equ RegC+DMax*2 CStatus equ RegC+DMax*2+1 TStatus equ CStatus+1 ;作業用STATUS TempB equ TStatus+1 ;作業用 H_Count1 equ 042H ;キー割込み禁止位置 H_Count2 equ 010H ;キー割込み禁止から表示までの期間 DotH equ 05H ;1ドットの高さ ;PS/2テンキー KeyCLKIn equ RB2 ;INT2割込みも使用 KeyDATIn equ RB3 KeyCLKOut equ RB4 KeyDATOut equ RB5 ACK equ 0FAH ;74HC4052 S0 equ RA0 ;白/黒 S1 equ RA1 ;同期信号/(白/黒) 現在未使用 ;NJM2266D ;SW1 equ 0V SW2 equ RA2 ;スーパーインポーズ/ビデオ入力 ;LM1881 C_Sync equ RA4 ;TMR0割込みも使用 V_Sync equ RB0 ;INT0割込み ; RA3 未使用 ; RB1 未使用 ; RB6 ICSPのみに使用 ; RB7 ICSPのみに使用 ;コード org 0 call IntIO bra Start org 8 btfsc INTCON,TMR0IF ;水平同期割込 goto INT_H btfsc INTCON,INT0IF ;垂直同期割込 bra INT_V btfsc INTCON3,INT2IF ;キーボード割込 bra Input retfie Start ;テスト用エリア シュミレーターで動作確認時に使用 ; btfsc PORTB,KeyCLKIn ; bra Main ; movlw RegA ; call ShiftL ; movlw 9 ; movwf RegV+DMax-1 ; movlw SqrCode ; movwf Key1 ; bra Calc Main bra Main ;入出力ピン設定&IO割り込み設定&変数初期化 IntIO ;I/Oの初期化 movlw 07Fh movwf ADCON1 ;ディジタルモード設定 ; 出力データ設定 clrf PORTA clrf PORTB ; 入出力の設定 movlw 1< 3 ; Sqr(49)=6.999999995 => 7 clrf RegA+DMax dcfsnz CntSqr ;計算終了 bra CalcEnd1 ;2回ずつで計算中断 btfsc CntSqr,0 bra Sqr1 bra CalcEnd3 ;比較 RegA - RegB => Z,C CPAB bsf TStatus,Z movlw RegA movwf FSR0L movlw RegB movwf FSR1L movlw DMax*2 movwf Cnt1 CPAB1 movf POSTINC1,W cpfseq INDF0 bcf TStatus,Z bsf TStatus,C cpfslt POSTINC0 bcf TStatus,C btfss TStatus,Z bra CPAB2 decfsz Cnt1 bra CPAB1 CPAB2 movf TStatus,W movwf STATUS return ;ゼロ判定 ゼロのときNもbcf AStatusSet movlw RegA xStatusSet movwf FSR0L movlw DMax*2 movwf Cnt1 incf WREG bcf PLUSW0,Z ;?Status clrf WREG xStatusSet1 TSTFSZ PLUSW0 return incf WREG decfsz Cnt1 bra xStatusSet1 incf WREG bsf PLUSW0,Z bcf PLUSW0,N return ;10桁コピー郡 CopyRegMV movlw Mem movwf FSR0L movlw RegV call CopyReg10 bra V1SET CopyRegV1 movlw RegV movwf FSR0L movlw Reg1 bra CopyReg10 CopyRegV2 movlw RegV movwf FSR0L movlw Reg2 bra CopyReg10 ;20桁コピー郡 CopyRegAB movlw RegA movwf FSR0L movlw RegB bra CopyReg20 CopyRegBC movlw RegB movwf FSR0L movlw RegC bra CopyReg20 CopyRegCA movlw RegC movwf FSR0L movlw RegA bra CopyReg20 CopyReg10 ;10桁コピー movwf FSR1L movlw DMax+2 movwf Cnt1 bra CopyReg CopyReg20 ;20桁コピー movwf FSR1L movlw DMax*2+2 movwf Cnt1 CopyReg movf POSTINC0,W movwf POSTINC1 decfsz Cnt1 bra CopyReg return ;シフト郡 ;小数点が中央に来るようにシフト ShiftC movwf FSR0L ShiftC1 movlw DMax*2 tstfsz PLUSW0 bra ShiftC2 return ShiftC2 btfss PLUSW0,7 bra ShiftC3 call ShiftL1 bra ShiftC1 ShiftC3 call ShiftH1 bra ShiftC1 ;数字が下位10バイトになるようにシフト ;上位シフトしてから下位に移しています。 ShiftL call ShiftH movlw DMax movwf Cnt1 addwf FSR0L,W movwf FSR2L ShiftL2 movf INDF0,W clrf POSTINC0 movwf POSTINC2 decfsz Cnt1 bra ShiftL2 movlw DMax addwf INDF2 bsf STATUS,C subfwb FSR0L return ;数字が最上位になるようにシフト ShiftH movwf FSR0L tstfsz INDF0 bra xStatusSet movwf FSR2L clrf Cnt1 movlw DMax*2 movwf Cnt2 ShiftH2 movf Cnt1,W tstfsz PLUSW0 bra ShiftH3 movlw DMax*2 decf PLUSW0 ;?Exp incf Cnt1 decfsz Cnt2 bra ShiftH2 clrf PLUSW0 ;?Exp incf WREG ;?Status bsf PLUSW0,Z bcf PLUSW0,N return ShiftH3 movf Cnt1,W movf PLUSW0,W movwf POSTINC2 incf Cnt1 decfsz Cnt2 bra ShiftH3 movf FSR0L,W addlw DMax*2 subwf FSR2L,W movwf Cnt1 ShiftH4 clrf POSTINC2 incfsz Cnt1 bra ShiftH4 incf FSR2L bcf INDF2,Z return ;FSR0Lの示すレジスタを1桁上位へシフト ShiftH1 movlw DMax*2-1 movwf Cnt1 ShiftH11 movlw 1 movf PLUSW0,W movwf POSTINC0 decfsz Cnt1 bra ShiftH11 clrf POSTINC0 decf INDF0 movlw -(DMax*2) addwf FSR0L return ;FSR0Lの示すレジスタを1桁下位へシフト ShiftL1 movlw DMax*2 addwf FSR0L incf INDF0 decf FSR0L movlw DMax*2-1 movwf Cnt1 ShiftL11 movlw -1 movf PLUSW0,W movwf INDF0 decf FSR0L decfsz Cnt1 bra ShiftL11 clrf INDF0 return ;10桁レジスタ=>20桁レジスタ郡 SetReg1A movlw Reg1 bra SetRegA SetReg1B movlw Reg1 bra SetRegB SetReg2B movlw Reg2 bra SetRegB SetRegMA movlw Mem bra SetRegA SetRegVA movlw RegV SetRegA movwf FSR0L movlw RegA bra SetReg0 SetRegVB movlw RegV SetRegB movwf FSR0L movlw RegB SetReg0 call ClrReg movlw DMax movwf Cnt1 SetReg01 movf POSTINC0,W andlw 0FH movwf POSTINC1 decfsz Cnt1 bra SetReg01 movlw DMax addwf FSR1L movf POSTINC0,W movwf POSTINC1 movf POSTINC0,W movwf POSTINC1 return ;20桁レジスタクリア ;入力 WREG=Reg? ClrReg movwf FSR1L movlw DMax*2+1 movwf Cnt1 ClrReg1 clrf POSTINC1 decfsz Cnt1 bra ClrReg1 clrf INDF1 bsf INDF1,Z movlw -(DMax*2+1) addwf FSR1L return ;20桁レジスタ(RegA)=>10桁レジスタ(Reg?) ;上位に詰めて、小数点以下の0と上にはみ出した小数点をシフト ;入力:WREG=Reg? ;結果:RegA => Reg? GetRegA movwf FSR1L movlw RegA call ShiftH GetRegA1 movlw DMax*2 movf PLUSW0,W btfss WREG,7 bra GetRegA3 addlw DMax-1 bn GetRegA2 movlw DMax-1 tstfsz PLUSW0 bra GetRegA3 GetRegA2 call ShiftL1 bra GetRegA1 GetRegA3 movlw DMax movwf Cnt1 GetRegA4 movf POSTINC0,W movwf POSTINC1 decfsz Cnt1 bra GetRegA4 movlw DMax addwf FSR0L movf POSTINC0,W ;?Exp movwf POSTINC1 movf POSTINC0,W ;?Status movwf POSTINC1 return ;キー入力処理及びレジスタ設定 ;ここでは計算せず、垂直同期後のCalcで計算する。 ;処理終了時に計算が必要な場合は、Key1に演算子が入る。 ;計算例 (FX,FX2の_は0 Key1の_は0FFH) ;入力 2 + 3 - 4 = ;Reg1 2 5 1 ;Reg2 2 3 4 ;FX + + - - - - ;FX2 + _ - ;Key1 _ _ _ + _ - ; 計算 計算 ;入力 2 + = ;Reg1 2 4 ;Reg2 2 ;FX + + ;FX2 ;Key1 _ _ + ; 計算 ;入力 2 + 3 = = 3 + 4 = ;Reg1 2 5 8 3 5 ;Reg2 2 3 3 4 ;FX + + + + _ + + + ;FX2 + _ _ _ + _ ;Key1 _ _ _ + + _ _ _ + ;EquF 1 0 ; 計算計算 計算 Input call InKey0 bcf INTCON3,INT2IF movlw 0AAH ;テンキーの初期化信号 subwf Key1,W bz InputAA btfsc KeyF,TestFlag bra InputTest infsnz Key1,W ;0FFHなら無効な入力か入力エラー retfie btfsc TV_OutF,Off call CalcON ;表示されていなければオン movlw 0AH subwf Key1,W bnc InputN ;数字入力へ movlw ClrCode ;クリア subwf Key1,W bnz Input2 call ClrVRAM bra InputEnd Input2 movlw AllClrCode ;オールクリア subwf Key1,W bnz Input3 call AllClr bra InputEnd Input3 movlw DotCode ;小数点 subwf Key1,W bnz Input4 btfsc KeyF,ClrFlag call ClrVRAM bcf KeyF,ClrFlag bsf KeyF,DotKey bra InputEnd2 Input4 ;次回数字入力時は、左シフトせずにクリア bsf KeyF,ClrFlag movlw OffCode ;表示オフ subwf Key1,W bnz Input5 call CalcOFF bra InputEnd Input5 movlw BSCode subwf Key1,W bz InputBS movlw EquCode ;= subwf Key1,W btfsc STATUS,Z bra InputEqu movlw PerCode ;% subwf Key1,W btfsc STATUS,Z bra InputPer movlw SqrCode ;平方根 subwf Key1,W btfsc STATUS,Z bra InputEnd3 movlw DivCode+1 ;+ - * / subwf Key1,W bnc InputFX2 movlw MemReadCode ;MR subwf Key1,W btfss STATUS,Z bra Input6 call CopyRegMV bra InputEnd2 Input6 movlw MemAddCode ;M+ subwf Key1,W btfsc STATUS,Z bra InputMemAdd movlw MemSubCode ;M- subwf Key1,W btfsc STATUS,Z bra InputMemSub movlw MemClrCode ;MC subwf Key1,W btfsc STATUS,Z call ClrMem bra InputEnd1 ;不明なキー ;テンキーからの初期化信号受信時の処理 InputAA call ClrMem ;テンキーを差しなおすことでキーテストプログラムが起動する。 btg KeyF,TestFlag btg TV_OutF,Off ;違うスキャンコードのテンキーがあり、 ;スキャンコードの変更を試みた ; movlw 0F0H ;スキャンコード選択 ; call OutKey ; call InKey ; movlw ACK ; cpfseq Key1 ; retfie ; movlw 02H ;スキャンコード2 ; call OutKey ; call InKey ; movlw ACK ; cpfseq Key1 ; retfie call CalcONOFF bra InputEnd ;キーテストプログラム ;キー入力したスキャンコードを ;16進コードで表示 ;ただし、0AAHコードで電卓とキーテストプログラムが切り替わる。 InputTest movlw VRAM movwf FSR0L movlw VRAM+2 movwf FSR1L movlw VMax-2 movwf Cnt1 InputTest1 movf POSTINC1,W movwf POSTINC0 decfsz Cnt1 bra InputTest1 swapf Key1,W andlw 0FH movwf POSTINC0 movf Key1,W andlw 0FH movwf POSTINC0 bra InputEnd ;数字入力 InputN btfsc KeyF,ClrFlag call ClrVRAM bcf KeyF,ClrFlag ;小数点が上端に来ている movlw DMax-1 addwf VExp,W bz InputEnd ;上端に数字が来ている movlw SPCCode ;" " subwf VRAM+1,W bnz InputEnd ;数字を上位へシフト movlw 1 movwf FSR0L movlw 2 movwf FSR1L movlw 9 movwf Cnt1 InputN1 movf POSTINC1,W movwf POSTINC0 decfsz Cnt1 bra InputN1 movf Key1,W movwf VRAM+DMax btfsc KeyF,DotKey decf VExp bra InputEnd2 ;後退キー InputBS bcf KeyF,ClrFlag ;数字を下位へシフト movlw DMax movwf FSR0L movlw DMax-1 movwf FSR1L movlw 9 movwf Cnt1 InputBS1 movf POSTDEC1,W movwf POSTDEC0 decfsz Cnt1 bra InputBS1 clrf VRAM+1 incf VExp bn InputEnd2 ;小数点が端まで来た(越えた)時 clrf VExp bcf KeyF,DotKey bra InputEnd2 ;二項演算入力 InputFX2 TSTFSZ FX2 bra InputFX21 call CopyRegV1 call CopyRegV2 movf Key1,W movwf FX bra InputEnd InputFX21 call CopyRegV2 movf Key1,W movwf FX movf FX2,W movwf Key1 clrf FX2 retfie ;M+の入力 InputMemAdd bsf FXF,MemAdd clrf FX bra InputEqu ;M−の入力 InputMemSub bsf FXF,MemSub clrf FX bra InputEqu ;%の入力 InputPer bsf FXF,Percent ;=の入力 InputEqu bsf FXF,EquF tstfsz FX2 bra InputEqu2 tstfsz FX bra InputEqu1 ;メモリー計算であれば演算子未入力でも、 ;メモリーには加減算を行う。 btfsc FXF,MemAdd bra InputEqu3 btfsc FXF,MemSub bra InputEqu3 bra InputEnd1 InputEqu1 ;単項同士演算 movf FX,W movwf Key1 retfie InputEqu2 ;2項演算 call CopyRegV2 movf FX2,W movwf Key1 clrf FX2 retfie InputEqu3 call CopyRegV1 retfie ;終了 InputEnd ;2項演算子を更新しない bcf FXF,EquF InputEnd1 ;=,%で未計算時 & 不明なキー setf Key1 retfie InputEnd2 ;2項演算子を更新する(数字,.,+-*/,BS,MR) setf Key1 InputEnd3 ; 平方根 movf FX,W tstfsz FX movwf FX2 btfss FXF,EquF bra InputEnd4 bcf FXF,EquF clrf FX clrf FX2 InputEnd4 call Cut0 bcf VStatus,C ;エラー解除 call V1SET retfie ;表示オフ&LEDオフ CalcOFF bsf TV_OutF,Off call CalcONOFF bcf INTCON3,INT2IF return ;表示オン&LEDオン&オールクリア ;表示オンとともに押したキーの処理をするため、 ;Key1は保持(OffCodeを除く) CalcON bcf TV_OutF,Off movf Key1,W movwf FSR0L ;イレギュラーですがKey1保存 call CalcONOFF bcf INTCON3,INT2IF setf Key1 movlw OffCode subwf FSR0L,W bz AllClr movf FSR0L,W ;Key1がOffCodeでなければ復帰 movwf Key1 bra AllClr ;TV_OutF,Offにしたがって ;テンキーのNumLockLEDのオンオフ CalcONOFF movlw 0EDH ;LED設定 call OutKey call InKey movlw ACK cpfseq Key1 return movlw 02H ;NumLockLED On btfsc TV_OutF,Off clrf WREG ;NumLockLED Off call OutKey bra InKey ;オールクリア AllClr clrf FX clrf FX2 ;VRAMの初期化 ClrVRAM movlw DMax movwf FSR0L ClrVRAM1 clrf INDF0 decfsz FSR0L bra ClrVRAM1 clrf VExp bcf KeyF,DotKey bcf KeyF,ClrFlag bsf VStatus,Z bcf VStatus,C bcf VStatus,N call V1SET ;無用な0を消去(ゼロサプレス) Cut0 movlw RegV movwf FSR0L Cut01 movf VExp,W subwf FSR0L,W SUBLW DMax bz Cut03 ;小数点まで来た movlw SPCCode subwf INDF0,W bz Cut02 TSTFSZ INDF0 return ;ゼロでも" "でもない Cut02 bsf INDF0,4 incf FSR0L movlw VMax cpfseq FSR0L bra Cut01 return Cut03 movlw SPCCode cpfseq INDF0,W btg INDF0,4 btg INDF0,4 ;小数点桁が"0"のとき"0" return ;メモリークリア ClrMem movlw Mem movwf FSR0L movlw DMax+1 movwf Cnt1 ClrMem1 ;メモリークリア clrf POSTINC0 decfsz Cnt1 bra ClrMem1 bsf INDF0,Z bcf INDF0,C bcf INDF0,N ;M - E などの表示 V1SET movlw SPCCode btfsc VStatus,N bsf WREG,0 btfss MStatus,Z bsf WREG,1 btfsc VStatus,C movlw 0EH tstfsz VExp bra V1SET1 bra V1SET2 V1SET1 btfss VExp,7 movlw 0EH V1SET2 movwf V1 return ;キー入力 ;テンキーで使うスキャンコード2を ;CodeTBLを参照して処理コードに変換出力する。 ;出力 Key1 ;受信エラー又は0F0H(プリフィックス)の時は0FFHを出力 ;他のコードははそのまま出力 ;KeyF,TestFlagがセットされているときはそのままのコードを出力 ;エラー時に0FFHコードを出力するので、 ;0FFHというスキャンコードがあっても区別不可 ;キー入力(割込みを使わない入力) InKey call InKeyL ;キー入力(割込みより分岐入力) InKey0 setf Key1 ;エラー時の戻り値 btfsc PORTB,KeyDATIn ;スタートビットチェック return clrf TempB bcf KeyF,Parity ;パリティークリア movlw 08H movwf Cnt1 ;8ビットカウント InKey1 call InKeyL btfss PORTB,KeyDATIn ;データビット取得 bra InKey2 bsf TempB,0 ;データビットセット btg KeyF,Parity ;パリティー InKey2 rrncf TempB decfsz Cnt1 bra InKey1 call InKeyL btfsc PORTB,KeyDATIn ;パリティー取得 btg KeyF,Parity btfss KeyF,Parity return ;パリティーが異なる場合中断 call InKeyL btfss PORTB,KeyDATIn ;ストップビット return ;ストップビットが0の場合中断 call InKeyH btfsc KeyF,TestFlag bra InKey3 ;キーテスト時スキャンコードをそのまま返す movlw 0E0H ;無視する subwf TempB,W bz InKey6 movlw 0F0H ;ブレイクコード subwf TempB,W bz InKeyF0 call CodeScan incf TABLAT,W bnz InKey4 InKey3 movf TempB,W ;不明なキースキャンコードは movwf Key1 ;そのままコードを返す。 return InKey4 movlw 0AH cpfslt TABLAT bra InKeyNN ;数字の場合の処理 btfsc KeyF,Break ;ブレイクチェック bra InKey5 movf TABLAT,W movwf Key1 InKey5 bcf KeyF,Break InKey6 return InKeyF0 bsf KeyF,Break return ;数字以外の場合 InKeyNN btfss KeyF,Break ;ブレイクチェック bra InKeyNN1 ;ブレイク時 btfsc TempK,7 call CodeScan1 movf TABLAT,W movwf Key1 bcf KeyF,Break clrf TempK call V1SET return InKeyNN1 ;メイク時 movf TempB,W xorwf TempK,W andlw 07FH bnz InKeyNN3 bsf TempK,7 ;長押しの場合 call CodeScan1 bra InKeyNN4 InKeyNN3 movf TempB,W movwf TempK InKeyNN4 movf TABLAT,W movwf VRAM return InKeyL ;クロック立下り検出 btfss PORTB,KeyCLKIn bra InKeyL InKeyL1 btfsc PORTB,KeyCLKIn bra InKeyL1 return InKeyH ;クロック立上り検出 btfsc PORTB,KeyCLKIn bra InKeyH InKeyH1 btfss PORTB,KeyCLKIn bra InKeyH1 return CodeScan ;キースキャンコード2=>処理コード clrf TBLPTRU ;UPPER CodeTBL movlw HIGH CodeTBL movwf TBLPTRH movlw LOW CodeTBL movwf TBLPTRL bra CodeScan1 CodeScan0 tblrd *+ CodeScan1 tblrd *+ infsnz TABLAT,W bra CodeScan2 movf TABLAT,W cpfseq TempB bra CodeScan0 CodeScan2 tblrd *+ return ;キーボードへ出力 ;LED表示などで使用 OutKey movwf TempB bcf KeyF,Parity ;パリティー用 call InKeyH1 bsf PORTB,KeyCLKOut ;スタートビット bsf PORTB,KeyDATOut movlw 6 call TimeW bcf PORTB,KeyCLKOut movlw 08H movwf Cnt1 ;8ビットカウント OutKey1 call InKeyL btfss TempB,0 ;データビットセット bra OutKey2 bcf PORTB,KeyDATOut ;1を出力 btg KeyF,Parity ;パリティー bra OutKey3 OutKey2 bsf PORTB,KeyDATOut ;0を出力 OutKey3 rrncf TempB decfsz Cnt1 bra OutKey1 call InKeyL ;パリティーを出力 btfss KeyF,Parity bra OutKey4 bsf PORTB,KeyDATOut; ;0を出力 bra OutKey5 OutKey4 bcf PORTB,KeyDATOut ;1を出力 OutKey5 call InKeyL bcf PORTB,KeyDATOut; ;ストップビット出力 call InKeyL btfss PORTB,KeyDATIn clrf TempB return ;水平同期割込 INT_H bcf INTCON,TMR0IF btfsc TV_OutF,Off retfie ;非表示 btfss INTCON3,INT2IE bra TV_Out ;キー割込み禁止中ならTV出力へ clrf TV_OutF ;キーボード割り込みの禁止 ;(表示期間にキー入力処理がかからないように少し前から禁止します。) bsf PORTB,KeyCLKOut bcf INTCON3,INT2IE bcf INTCON3,INT2IF movlw H_Count2 ;キーボード割込み禁止から表示までの期間 INT_H0 cpfseq TMR0L bra INT_H0 bcf INTCON,TMR0IF ;CGROM上位アドレスの設定 clrf TBLPTRU ;UPPER CG movlw HIGH CG movwf TBLPTRH ;1ドットの高さ movlw DotH movwf Cnt1 ;最初は設定のみで処理終了 ;次の割込みから表示 INT_H1 movlw -1 movwf TMR0L retfie ;スーパーインポーズ出力 ;TV_OutFで出力ラインを判定している ;TV_OutFの内容は;変数を参照 TV_Out btfsc TV_OutF,DotLine bra TV_Out4 ;小数点表示へ ;1桁目CG取得 clrf FSR0L movf POSTINC0,W mullw 7 movf PRODL,W addwf TV_OutF,W movwf TBLPTRL tblrd * movf TABLAT,W movwf TempB ;出力データを保存 call TV_HIndent ;時間取り ;黒出力 bsf PORTA,SW2 TV_Out3 ;横5ドットの出力 ;ドット1出力 movlw (1<>1 ;2 rlcf TempB addwfc WREG movwf PORTA nop nop nop ;ドット2出力 movlw (1<>1 ;2 rlcf TempB addwfc WREG movwf PORTA ;次桁のCG取得 ; 次桁のVRAM取得*7 movf POSTINC0,W mullw 7 nop ;ドット3出力 movlw (1<>1 ;2 rlcf TempB addwfc WREG movwf PORTA ; 次桁のCGROMアドレスセット movf PRODL,W addwf TV_OutF,W movwf TBLPTRL ;ドット4出力 movlw (1<>1 ;2 rlcf TempB addwfc WREG movwf PORTA ; 次桁のCGROM取得 tblrd * nop nop ;ドット5出力 movlw (1<>1 ;2 rlcf TempB addwfc WREG movwf PORTA ;次桁のCGROMデータをTempBにセット movf TABLAT,W movwf TempB nop nop nop movlw VMax+1 ;黒出力 最終ドット5の終了 bcf PORTA,S0 cpfseq FSR0L bra TV_Out3 nop nop ;出力終了 clrf PORTA decfsz Cnt1 bra INT_H1 movlw DotH movwf Cnt1 incf TV_OutF movlw 7 cpfseq TV_OutF bra INT_H1 clrf TV_OutF bsf TV_OutF,DotLine bra INT_H1 ;小数点ラインの表示 TV_Out4 nop nop nop nop nop nop nop movlw -(VMax-1) movwf FSR0L call TV_HIndent ;時間取り ;黒出力 bsf PORTA,SW2 movlw (1<(*) OffCode equ 19H ;off(Num,TAB) ClrCode equ 0CH ;C(/) EquCode equ 1AH ;=(Enter) MemAddCode equ 1BH ;M+(+) MemSubCode equ 1CH ;M-(-) MemReadCode equ 1DH ;MR(BS) MemClrCode equ 1EH ;MC(/) SqrCode equ 1FH ;SQR(*) PerCode equ 20H ;%(.) AllClrCode equ 21H ;AC(Num,TAB) ;キースキャンコード2 => 処理コード表 CodeTBL ;KEY Make Break 役割 DB 70H,00H ;0 DB 69H,01H ;1 DB 72H,02H ;2 DB 7AH,03H ;3 DB 6BH,04H ;4 DB 73H,05H ;5 DB 74H,06H ;6 DB 6CH,07H ;7 DB 75H,08H ;8 DB 7DH,09H ;9 DB 1CH,0AH ;A DB 32H,0BH ;B DB 21H,0CH ;C DB 23H,0DH ;D DB 24H,0EH ;E DB 2BH,0FH ;F ; DB 00H,10H ;" " DB 79H,SubCode ;(+)- ; DB 00H,12H ;M ; DB 00H,13H ;M - DB 71H,DotCode ;. DB 5AH,AddCode ;(Enter)+(E0 5A) DB 7BH,MulCode ;(-)* DB 66H,DivCode ;(BS)/ DB 7CH,BSCode ;(*)=> DB 4AH,ClrCode ;(/)C(E0 4A) DB 77H,AllClrCode ;(Num)AC DB 0DH,AllClrCode ;(TAB)C Numと同じ ;長押し DB 71H,PerCode ;(.)% DB 5AH,EquCode ;(Enter)=(E0 5A) DB 79H,MemAddCode ;(+)M+ DB 7BH,MemSubCode ;(-)M- DB 66H,MemReadCode ;(BS)MR DB 7CH,SqrCode ;(*)SQR DB 4AH,MemClrCode ;(/)MC(E0 4A) DB 77H,OffCode ;(Num)off DB 0DH,OffCode ;(TAB)off Numと同じ DB 0FFH,0FFH CodeEnd org (HIGH (CodeEnd+0100H))*0100H ;5×7ドットフォント ;7バイトで1フォント 最大36文字 CG ;??00H番地 ;0 1 DB B'01110000',B'10001000' DB B'10001000',B'10001000' DB B'10001000',B'10001000' DB B'01110000',B'00100000' DB B'01100000',B'00100000' DB B'00100000',B'00100000' DB B'00100000',B'01110000' ;2 3 DB B'01110000',B'10001000' DB B'00001000',B'00010000' DB B'01100000',B'10000000' DB B'11111000',B'01110000' DB B'10001000',B'00001000' DB B'01110000',B'00001000' DB B'10001000',B'01110000' ;4 5 DB B'00010000',B'01010000' DB B'01010000',B'10010000' DB B'11111000',B'00010000' DB B'00010000',B'11111000' DB B'10000000',B'10110000' DB B'11001000',B'00001000' DB B'10001000',B'01110000' ;6 7 DB B'01110000',B'10001000' DB B'10000000',B'11110000' DB B'10001000',B'10001000' DB B'01110000',B'11111000' DB B'00001000',B'00010000' DB B'00010000',B'00100000' DB B'00100000',B'00100000' ;8 9 DB B'01110000',B'10001000' DB B'10001000',B'01110000' DB B'10001000',B'10001000' DB B'01110000',B'01110000' DB B'10001000',B'10001000' DB B'01111000',B'00001000' DB B'00010000',B'00100000' ;A B DB B'00100000',B'01010000' DB B'01010000',B'10001000' DB B'11111000',B'10001000' DB B'10001000',B'11110000' DB B'10001000',B'10001000' DB B'11110000',B'10001000' DB B'10001000',B'11110000' ;C D DB B'00110000',B'01001000' DB B'10000000',B'10000000' DB B'10000000',B'01001000' DB B'00110000',B'11100000' DB B'10010000',B'10001000' DB B'10001000',B'10001000' DB B'10010000',B'11100000' ;E F DB B'11111000',B'10000000' DB B'10000000',B'11111000' DB B'10000000',B'10000000' DB B'11111000',B'11111000' DB B'10000000',B'10000000' DB B'11110000',B'10000000' DB B'10000000',B'10000000' ;SPC - DB B'00000000',B'00000000' DB B'00000000',B'00000000' DB B'00000000',B'00000000' DB B'00000000',B'00000000' DB B'00000000',B'00000000' DB B'00000000',B'11111000' DB B'00000000',B'00000000' ;M M - DB B'10001000',B'11011000' DB B'10101000',B'00000000' DB B'00000000',B'00000000' DB B'00000000',B'10001000' DB B'11011000',B'10101000' DB B'00000000',B'11111000' DB B'00000000',B'00000000' ;. + DB B'00000000',B'00000000' DB B'00000000',B'00000000' DB B'00000000',B'00011000' DB B'00011000',B'00000000' DB B'00000000',B'00100000' DB B'00100000',B'11111000' DB B'00100000',B'00100000' ;* / DB B'00000000',B'00000000' DB B'10001000',B'01010000' DB B'00100000',B'01010000' DB B'10001000',B'00000000' DB B'00000000',B'00100000' DB B'00000000',B'11111000' DB B'00000000',B'00100000' ;-> off DB B'00000000',B'00000000' DB B'00100000',B'00010000' DB B'11111000',B'00010000' DB B'00100000',B'00100000' DB B'00100000',B'00010000' DB B'00010000',B'00001000' DB B'00001000',B'00100000' ;= M+ DB B'00000000',B'00000000' DB B'00000000',B'11111000' DB B'00000000',B'11111000' DB B'00000000',B'10001000' DB B'11011000',B'10101000' DB B'00000000',B'00100000' DB B'01110000',B'00100000' ;M- MR DB B'10001000',B'11011000' DB B'10101000',B'00000000' DB B'00000000',B'01110000' DB B'00000000',B'10001000' DB B'11011000',B'10101000' DB B'01110000',B'01110000' DB B'01100000',B'01010000' ;MC SQR DB B'10001000',B'11011000' DB B'10101000',B'00000000' DB B'01110000',B'10000000' DB B'01110000',B'00111000' DB B'00100000',B'00100000' DB B'01000000',B'01000000' DB B'11000000',B'01000000' ;% AC DB B'11001000',B'11001000' DB B'00010000',B'00100000' DB B'01000000',B'10011000' DB B'10011000',B'00100000' DB B'01010000',B'11111000' DB B'10001000',B'01110000' DB B'10000000',B'01110000' END ;作成履歴 ;2007-04-27 PICライターとOSD-232(スーパーインポーズボード)を購入 ; OSD-232を使うか自作するかテンキーをどうするか模索が続く・・・。 ;2007-07-19 秋月電子通商/2007-08-01共立電子産業で部品購入 ;2007-08-?? 手書き実体配線図を元に苦手な半田ごて ;2007-09-03 縦縞表示可能に(同期信号もPICで作るつもりだったがあきらめる。) ;2007-09-09 文字表示(4*7ドット) ;2007-09-12 文字表示(5*7ドット)へ ;2007-09-18 キー入出力可能に ;2007-10-06 一通り演算が可能に ;2007-10-21 連続演算への対応 ;2007-10-18 実体配線図清書 ;2007-10-20 回路図作成 ;2007-10-27 HP掲載 ;主な部品 ;入力 75Ω 10μ ;同期 LM1881N 680Ω 470p 680k 0.1μ*3 ;SW NJM2266D 0.1μ ;発生 74HC4052 VR2k*3,2k*6 0.1μ ;出力 2SC1815 220Ω 75Ω 220μ ;制御 PIC18F1320 10MHz 0.1μ ;ICSP 10k 1S1588 ;PS/2 2SC1815*2 4.7k*4 2k*2 ;電源 7805 100μ 0.1μ*2 ACアダプター9V1.2A(秋月電子) ;キー PS/2テンキー(サンワサプライ NT-9PPK) ;参考文献 ;PIC18本格活用ガイド 後閑哲也 著 ;トランジスタ技術月刊誌1995年10月 PCインターフェースの研究 ;秋月電子キット取扱説明書・回路図集 ;など