Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; *****************************************************************************
- ;
- ; 16F877A RK-100用プログラム 20MHz
- ; ver 2.60
- ;
- ; ハードSPI版
- ; FAT12版
- ; FIFO版
- ;
- ; (c) 2011 G group, futr
- ;
- ; *****************************************************************************
- ;
- ; デバッグキーワード : DEBUG
- ;
- ; *****************************************************************************
- ;
- ; デルタゼロで97バイト以上データが重なるファイルでは若干処理が止まるかもしれません
- ; 常識的なデータなら多分大丈夫です
- ; FAT12形式に擬似対応していますが、もしファイルが断片化するとデータが再生できなくなります。
- ; フォーマットし直してデータを入れなおしてください
- ;
- ; FIFOの名前がPLAY〜になっているのはMIDIプレーヤー専用の名残で
- ; 実際には通常のキーボード制御でも使っています
- ;
- ; 1234567890123456
- ; +----------------+
- ; |VO000 B000 C00 M| : ボリューム ピッチ チャンネル オクターブ
- ; |VE000 P000 STOP| : ベロシティ プログラム 再生
- ; +----------------+
- ;
- ; *****************************************************************************
- ;
- ; MIDI : 反転なしの31250bps
- ;
- ; 送信しか使わなくてもRCSTAの7bit目が必要
- ; TRISEの3bitからは特別な意味があるので注意
- ;
- ; SMP = 1, CKE = 0, CKP = 1
- ; 本当はこの組み合わせでは動かないはずだけど、時間がないので保留
- ;
- ; BENDは0,64が中心 127,127が最大 0,0が最小らしい
- ;
- ; PORTB : 液晶用
- ; PORTD : セレクタ用
- ; PORTC : 通信用
- ;
- ; A0Hから : キーONテーブル
- ; 110Hから : MIDI用FIFOバッファ
- ;
- ; 同時演奏でおかしくなるので送信のランニングステータス廃止
- ; 音源自作用にノートオフに変更
- ;
- ; *****************************************************************************
- ; コンフィグ
- __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
- LIST p=16F877A, b=4
- INCLUDE "P16F877A.INC"
- ERRORLEVEL -302
- ; * IO - MAP ******************************************************************
- #DEFINE AN_JOY0 PORTA, 0 ; アナログ入力、ジョイスティック
- #DEFINE AN_JOY1 PORTA, 1 ; アナログ入力、ジョイスティック
- #DEFINE AN_VOL PORTA, 3 ; アナログ入力、ボリューム
- #DEFINE SW_PG_UP PORTE, 0 ; PC UP
- #DEFINE SW_PG_DOWN PORTE, 1 ; PC DOWN
- #DEFINE SW_HOLD PORTC, 0 ; ホールドキー
- #DEFINE SW_MODE PORTC, 1 ; MODE切り替えスイッチ
- #DEFINE SW_OCT_L PORTA, 4 ; オクターブL
- #DEFINE SW_OCT_H PORTA, 5 ; オクターブH
- #DEFINE LCD_E PORTB, 3 ; 液晶用コントロール端子
- #DEFINE LCD_RS PORTB, 2 ; 液晶用
- #DEFINE LCD_RW PORTB, 1 ; 液晶用
- #DEFINE MMC_CS PORTC, 2 ; チップセレクト
- #DEFINE SPI_DI PORTC, 4 ; 入力ピン
- #DEFINE SPI_CLK PORTC, 3 ; クロック
- #DEFINE SPI_DO PORTC, 5 ; 出力ピン
- #DEFINE MIDI_OUT PORTC, 6 ; MIDI出力
- #DEFINE KEY_IN PORTD, 6 ; キー状態入力端子
- ; *****************************************************************************
- #DEFINE LCD_CMD_CLR 01H ; 液晶コマンドクリア
- #DEFINE LCD_CMD_CUR B'10000000' ; カーソル指定コマンド
- #DEFINE LCD_CUR_1L 00H ; 1行目
- #DEFINE LCD_CUR_2L 040H ; 2行目
- #DEFINE MIDI_BEND_TH D'15' ; BENDのしきい値
- #DEFINE MIDI_RATE D'39' ; MIDI用SPBRG ( BRGH = 1 )
- #DEFINE MIDI_INI_VOL D'100' ; VOL初期値
- #DEFINE MIDI_INI_NOTE D'36' ; NOTE最小値
- #DEFINE MIDI_C_BEND_C D'64' ; BENDの中心値 ( MIDIメッセージにおける )
- #DEFINE MIDI_C_LMH D'12' ; LMH初期値 ( 内部用、加算値 )
- #DEFINE MIDI_STA_ON B'10010000' ; ノートオン OR合成用
- #DEFINE MIDI_STA_OFF B'10000000' ; ノートオフ
- #DEFINE MIDI_STA_BEND 0xE0 ; ピッチベンド
- #DEFINE MIDI_STA_CTRL 0xB0 ; コントロールチェンジ ( 音量とかホールドとか )
- #DEFINE MIDI_STA_PROG 0xC0 ; プログラムチェンジ
- #DEFINE MIDI_CTRL_VOL_M 0x07 ; 音量MSB
- #DEFINE MIDI_CTRL_VOL_L 0x27 ; 音量LSB
- #DEFINE MIDI_CTRL_HOLD 0x40 ; ホールド用
- #DEFINE MODE_CANCEL 0x00 ; キャンセル画面
- #DEFINE MODE_PLAY 0x01 ; 再生
- #DEFINE MODE_STOP 0x02 ; 停止
- #DEFINE MODE_FORMAT 0x03 ; フォーマット
- #DEFINE MODE_CH 0x04 ; チャンネル変更
- #DEFINE MODE_MAX 0x04 ; モード最大値
- #DEFINE SPI_MODE0 D'0' ; MODE0 ( 定数だけど、なんとなくDEFINE )
- #DEFINE SPI_MODE1 D'1' ; MODE1
- #DEFINE SPI_MODE2 D'2' ; MODE2
- #DEFINE SPI_MODE3 D'3' ; MODE3
- #DEFINE SPI_SPEED_200K D'5' ; 200Kbps用定数
- #DEFINE SPI_SPEED_MAX D'1' ; 最大速度
- #DEFINE MMC_CRC_CMD0 B'10010101' ; CMD0用CRC固定値
- #DEFINE MMC_CMD_0 D'0' ; ソフトウェアリセット
- #DEFINE MMC_CMD_1 D'1' ; 初期化開始
- #DEFINE MMC_CMD_12 D'12' ; 読み込み強制停止
- #DEFINE MMC_CMD_16 D'16' ; ブロック長指定
- #DEFINE MMC_CMD_17 D'17' ; シングルブロックリード
- #DEFINE MMC_CMD_24 D'24' ; シングルブロックライト
- #DEFINE MMC_CMD_41 D'41' ; SD専用初期化
- #DEFINE MMC_CMD_55 D'55' ; アプリケーション特化コマンド
- #DEFINE PLAY_FSR_START 0x10 ; バッファ起点
- #DEFINE PLAY_FSR_END 0x70 ; バッファ終点 + 1
- #DEFINE PLAY_FIFO_SIZE D'96' ; FIFOの大きさ
- #DEFINE FIFO_SD_START 0x90 ; バッファ起点
- #DEFINE FIFO_SD_END 0xF0 ; バッファ終点 + 1
- #DEFINE FIFO_SD_SIZE D'96' ; FIFOの大きさ
- #DEFINE FILE_FIRST_SECT 0x42 ; ファイル開始セクタ
- #DEFINE F_FILE_START FILE_FLAG, 0 ; ファイル読み込み中フラグ
- #DEFINE F_FIFO_SD_START FIFO_SD_FLG, 0 ; 開始している?
- #DEFINE F_FIFO_SD_EN FIFO_SD_FLG, 1 ; イネーブル?
- #DEFINE F_KEY_PC KEY_FLAGS, 0 ; PC変更フラグ 1 = 変更
- #DEFINE F_KEY_LCD KEY_FLAGS, 1 ; 液晶書き換え要求
- #DEFINE F_KEY_C_VOL KEY_FLAGS, 2 ; 変更ありか
- #DEFINE F_KEY_C_BEND KEY_FLAGS, 3
- #DEFINE F_KEY_C_VELO KEY_FLAGS, 4
- #DEFINE F_KEY_C_HOLD KEY_FLAGS, 5
- #DEFINE F_KEY_C_LMH KEY_FLAGS, 6
- #DEFINE F_KEY_C_PROG KEY_FLAGS, 7
- #DEFINE F_PLAY_PLAY PLAY_FLAGS, 0 ; 再生中フラグ
- #DEFINE F_PLAY_DELTA PLAY_FLAGS, 1 ; DELTA処理中
- #DEFINE F_PLAY_SEND PLAY_FLAGS, 2 ; バッファ送信
- #DEFINE F_MODE_PUSH MODE_FLAGS, 0 ; ボタン押されてた?
- ; * MEM-MAP *******************************************************************
- ;
- MEM EQU 0x20 ; メモリ開始番地
- CNT1 EQU MEM + D'0' ; ディレイ用
- CNT2 EQU MEM + D'1'
- CNT3 EQU MEM + D'2'
- CNT4 EQU MEM + D'3'
- MEM_LCD EQU MEM + D'4' ; 液晶
- LCD_BUF EQU MEM_LCD + D'0' ; LCDデータバッファ
- LCD_BUF4 EQU MEM_LCD + D'1' ; 4bit転送用バッファ
- MEM_TEMP EQU MEM_LCD + D'2' ; 割り込みテンポラリ用
- TMP_W EQU 0x70 ; Wregに関しては共通アクセスできる0x70に
- TMP_STATUS EQU MEM_TEMP + D'0'
- TMP_PCLATH EQU MEM_TEMP + D'1'
- TMP_FSR EQU MEM_TEMP + D'2'
- MEM_MODE EQU MEM_TEMP + D'3'
- MODE_POS EQU MEM_MODE + D'0' ; 現在のモード画面
- MODE_FLAGS EQU MEM_MODE + D'1' ; フラグ
- MODE_BUF EQU MEM_MODE + D'2' ; バッファ
- MEM_KEY EQU MEM_MODE + D'3' ; キーセレクト用
- KEY_POS EQU MEM_KEY + D'0' ; 現在のサーチ位置
- KEY_FLAGS EQU MEM_KEY + D'1' ; フラグ
- KEY_FLAGS2 EQU MEM_KEY + D'2' ; フラグ2
- KEY_BUF EQU MEM_KEY + D'3' ; キーバッファ
- KEY_TBL_BUF EQU MEM_KEY + D'4' ; テーブル用バッファ
- MEM_MIDI EQU MEM_KEY + D'5' ; MIDI制御用
- MIDI_PROG EQU MEM_MIDI + D'0' ; プログラムナンバー
- MIDI_B_PROG EQU MEM_MIDI + D'1'
- MIDI_CH EQU MEM_MIDI + D'2' ; MIDI-CHANNEL
- MIDI_VOL EQU MEM_MIDI + D'3' ; MIDI-VOLUME
- MIDI_B_VOL EQU MEM_MIDI + D'4' ; 前回のMIDI-VOL
- MIDI_BEND EQU MEM_MIDI + D'5' ; MIDI-BEND
- MIDI_B_BEND EQU MEM_MIDI + D'6' ; 前回のBEND
- MIDI_BEND_C EQU MEM_MIDI + D'7' ; BEND中心値
- MIDI_VELO EQU MEM_MIDI + D'8' ; MIDI-ベロシティ
- MIDI_B_VELO EQU MEM_MIDI + D'9' ; 前回の
- MIDI_LMH EQU MEM_MIDI + D'19' ; MIDI-オクターブ
- MIDI_B_LMH EQU MEM_MIDI + D'11'
- MIDI_TX_BUF EQU MEM_MIDI + D'12' ; MIDI送信バッファ
- MIDI_HOLD EQU MEM_MIDI + D'13' ; ホールド
- MIDI_B_HOLD EQU MEM_MIDI + D'14' ; 前回のホールド
- MEM_TOSTR EQU MEM_MIDI + D'15' ; TOSTR用メモリ
- TOSTR_1 EQU MEM_TOSTR + D'0' ; 結果格納用1の位 ( 最大3ケタ )
- TOSTR_10 EQU MEM_TOSTR + D'1' ; 10
- TOSTR_100 EQU MEM_TOSTR + D'2' ; 100
- TOSTR_BUF EQU MEM_TOSTR + D'3' ; バッファ
- MEM_SPI EQU MEM_TOSTR + D'4' ; SPI通信プログラム用
- SPI_DATA EQU MEM_SPI + D'0' ; 通信データ受け渡し用
- SPI_CNT EQU MEM_SPI + D'1' ; 通信するときに使うカウンタ
- SPI_STATUS EQU MEM_SPI + D'2' ; MODEなどを保存
- SPI_SPEED EQU MEM_SPI + D'3' ; クロックスピード
- SPI_CNT2 EQU MEM_SPI + D'4' ; クロック用カウンタ
- MEM_MMC EQU MEM_SPI + D'5' ; MMC(SD)用
- MMC_ARG EQU MEM_MMC + D'0' ; コマンド用引数(全4バイト)
- MMC_ARG1 EQU MEM_MMC + D'1'
- MMC_ARG2 EQU MEM_MMC + D'2'
- MMC_ARG3 EQU MEM_MMC + D'3'
- MMC_BUF1 EQU MEM_MMC + D'4' ; バッファー1
- MMC_BUF2 EQU MEM_MMC + D'5' ; レスポンス待ちバッファ
- MMC_CNT1 EQU MEM_MMC + D'6' ; MMC用カウンタ1
- MEM_FILE EQU MEM_MMC + D'7' ; ファイルアクセス用
- FILE_BYTES EQU MEM_FILE + D'0' ; 読み込み数カウンタ
- FILE_BYTES1 EQU MEM_FILE + D'1' ; 読み込み数カウンタ
- FILE_FLAG EQU MEM_FILE + D'2' ; ファイルアクセス用フラグ
- FILE_RECV EQU MEM_FILE + D'3' ; 受信データ
- FILE_SECT EQU MEM_FILE + D'4' ; 読み込み希望セクタ
- MEM_PLAYER EQU MEM_FILE + D'5' ; MIDIプレーヤー用メモリ
- PLAY_FLAGS EQU MEM_PLAYER + D'0' ; フラグ用
- PLAY_BUF EQU MEM_PLAYER + D'1' ; バッファ
- PLAY_TEMPO EQU MEM_PLAYER + D'2' ; テンポ保存用
- PLAY_D_0 EQU MEM_PLAYER + D'3' ; デルタ最下位
- PLAY_D_1 EQU MEM_PLAYER + D'4'
- PLAY_D_2 EQU MEM_PLAYER + D'5'
- PLAY_D_3 EQU MEM_PLAYER + D'6' ; デルタ最上位
- PLAY_DELTAS EQU MEM_PLAYER + D'7' ; デルタバイト数
- PLAY_DATAS EQU MEM_PLAYER + D'8' ; データ部の長さ
- PLAY_D_BUF EQU MEM_PLAYER + D'9' ; デルタ用バッファ
- PLAY_FSR EQU MEM_PLAYER + D'10' ; 送信バッファ用ポインタ
- PLAY_COUNT EQU MEM_PLAYER + D'11' ; 送信バッファたまり具合
- PLAY_FSR_S EQU MEM_PLAYER + D'12' ; 送信バッファの現在送信中の位置
- PLAY_FIFO EQU MEM_PLAYER + D'13' ; FIFO用汎用バッファ
- PLAY_CLS_0 EQU MEM_PLAYER + D'14' ; 開始クラスタ
- PLAY_CLS_1 EQU MEM_PLAYER + D'15'
- MEM_PG EQU MEM_PLAYER + D'16' ; 汎用カウンタ用
- PG_CNT1 EQU MEM_PG + D'0' ; 汎用カウンタ
- PG_CNT2 EQU MEM_PG + D'1' ; 汎用カウンタ
- PG_POINT1 EQU MEM_PG + D'2' ; 汎用ポインタ
- PG_BUF1 EQU MEM_PG + D'3'
- MEM_FIFO_SD EQU MEM_PG + D'4' ; SD用FIFO
- FIFO_SD_R EQU MEM_FIFO_SD + D'0' ; 読み込みFSR
- FIFO_SD_W EQU MEM_FIFO_SD + D'1' ; 書き込みFSR
- FIFO_SD_C EQU MEM_FIFO_SD + D'2' ; FIFOたまり具合
- FIFO_SD_BUF EQU MEM_FIFO_SD + D'3' ; FIFO用バッファ
- FIFO_SD_FLG EQU MEM_FIFO_SD + D'4' ; フラグ
- MEM_DEBUG EQU MEM_FIFO_SD + D'5' ; デバッグ用
- DBG_FIFO_OF EQU MEM_DEBUG + D'0' ; FIFOフロー
- ; *****************************************************************************
- ORG 00H ; 開始
- GOTO START
- ORG 004H ; 割り込みベクタ
- GOTO INT
- START ; システム初期化開始
- BSF STATUS, RP0 ; BANK1へ
- MOVLW B'11111111' ; PORTAすべて入力
- MOVWF TRISA
- MOVLW B'00000001' ; PORTBはINTだけ入力 ( 残りは液晶用 )
- MOVWF TRISB
- MOVLW B'10010011' ; PORTCはSDとMIDI用
- MOVWF TRISC
- MOVLW B'11000000' ; PORTDはセレクタ用 ( RD6が入力 )
- MOVWF TRISD
- MOVLW B'00000111' ; PORTEはとりあえず入力に
- MOVWF TRISE
- BCF STATUS, RP0 ; BANK0へ
- ; ADコンバーター設定
- BSF STATUS, RP0 ; BANK1へ
- MOVLW B'01000100' ; ADCON1の値設定 ( 左詰め, Fosc/62, AN0-1-3 )
- MOVWF ADCON1 ; ADCON1設定
- BCF STATUS, RP0 ; BANK0へ
- MOVLW B'10000000' ; ADCON0の値設定 ( Fosc/64 )
- MOVWF ADCON0 ; ADCON0設定
- ; MIDIOUT ( USART ) 設定
- BSF RCSTA, SPEN ; シリアル通信を使用する
- BSF STATUS, RP0 ; BANK1へ
- MOVLW B'00100100' ; TXSTAの値設定 ( 非同期, 高速, ノンパリティ )
- MOVWF TXSTA ; TXSTA設定
- MOVLW MIDI_RATE ; 転送速度設定 ( MIDIベース )
- MOVWF SPBRG ; SPBRG設定 ( 31250bps )
- BCF STATUS, RP0 ; BANK0へ
- ; 割り込み等
- BSF INTCON, PEIE ; 周辺割り込み許可
- BSF INTCON, GIE ; 割り込み許可
- ; 初期値設定
- CLRF KEY_POS ; キーポジション初期化
- CLRF KEY_FLAGS ; フラグクリア
- CLRF PLAY_FLAGS
- CLRF FILE_FLAG
- CLRF FIFO_SD_FLG
- CLRF FIFO_SD_C
- CLRF DBG_FIFO_OF ; DEBUG
- MOVLW PLAY_FSR_START ; バッファ起点設定
- MOVWF PLAY_FSR
- MOVWF PLAY_FSR_S
- CLRF PLAY_COUNT ; バッファカウンタ初期化
- ; ポート初期化
- CLRF PORTD ; PORTD初期化
- BSF MMC_CS ; MMCを開放する
- ; 液晶初期化開始
- CALL LCD_INIT ; LCD初期化
- CALL LCD_CLR ; 画面クリア
- MOVLW 'R' ; ようこそ画面
- CALL LCD_SEND
- MOVLW 'K'
- CALL LCD_SEND
- MOVLW '-'
- CALL LCD_SEND
- MOVLW '1'
- CALL LCD_SEND
- MOVLW '0'
- CALL LCD_SEND
- MOVLW '0'
- CALL LCD_SEND
- MOVLW LCD_CUR_2L ; 2行目へ
- CALL LCD_CUR ; 位置設定
- MOVLW D'16' ; 16回繰り返す
- MOVWF PG_CNT1 ; 汎用カウンタにセット
- L_MAIN_INIT_LCD_L0
- MOVLW 0FFH ; ■
- CALL LCD_SEND
- CALL TIME10M
- CALL TIME10M
- CALL TIME10M
- CALL TIME10M
- CALL TIME10M
- DECFSZ PG_CNT1, F
- GOTO L_MAIN_INIT_LCD_L0
- ; MIDIパラメータ初期化開始
- CLRF MIDI_CH ; 0チャンネル
- CLRF MIDI_PROG ; 0プログラム
- CALL KEY_READ_AD ; AD変換開始
- RRF MIDI_VOL, F ; さらに1ビット捨てる
- BCF MIDI_VOL, 7
- RRF MIDI_BEND, F
- BCF MIDI_BEND, 7
- RRF MIDI_VELO, F
- BCF MIDI_VELO, 7
- MOVF MIDI_BEND, W ; BEND中心値取得
- MOVWF MIDI_BEND_C ; 中心値保存
- CALL MIDI_SEND_STA_PROG ; プログラムチェンジ送信
- MOVLW 0x00 ; 0番
- CALL MIDI_SEND_BYTE ; 0番送信
- GOTO MAIN ; 初期化完了、起動!
- ; * MAIN **********************************************************************
- MAIN ; メインループ
- ; AD変換で値取得 ( CALLは使わない )
- MOVLW B'10000000' ; ADCON0初期値
- IORLW B'00000001' ; AN0変換開始
- MOVWF ADCON0 ; チャンネル0選択、使用開始
- CALL TIME50 ; 50マイクロまつ
- BSF ADCON0, GO ; 変換開始
- BTFSC ADCON0, GO ; 変換終了した?
- GOTO $ - D'1' ; まだ
- MOVF ADRESH, W ; 結果取り出し
- MOVWF MIDI_VELO ; ベロシティへ
- MOVLW B'10000000' ; ADCON0初期値
- IORLW B'00001001' ; AN1変換開始
- MOVWF ADCON0 ; チャンネル1選択、使用開始
- CALL TIME50 ; 50マイクロまつ
- BSF ADCON0, GO ; 変換開始
- BTFSC ADCON0, GO ; 変換終了した?
- GOTO $ - D'1' ; まだ
- MOVF ADRESH, W ; 結果取り出し
- MOVWF MIDI_BEND ; BENDへ
- MOVLW B'10000000' ; ADCON0初期値
- IORLW B'00011001' ; AN3変換開始
- MOVWF ADCON0 ; チャンネル3選択、使用開始
- CALL TIME50 ; 50マイクロまつ
- BSF ADCON0, GO ; 変換開始
- BTFSC ADCON0, GO ; 変換終了した?
- GOTO $ - D'1' ; まだ
- MOVF ADRESH, W ; 結果取り出し
- MOVWF MIDI_VOL ; ボリュームへ
- ; 取得値を変換
- RRF MIDI_VOL, F ; さらに1ビット捨てる
- BCF MIDI_VOL, 7
- RRF MIDI_BEND, F
- BCF MIDI_BEND, 7
- RRF MIDI_VELO, F
- BCF MIDI_VELO, 7
- ; BEND作成
- L_BEND_CHECK_OVER
- MOVLW MIDI_BEND_TH ; BENDしきい値と比較
- ADDWF MIDI_BEND_C, W ; 中心 ( 実測 ) に加算
- SUBWF MIDI_BEND, W ; THより大きいかチェック
- BTFSC STATUS, C ; 正だったら大きい ( C = 1 )
- GOTO L_BEND_MAKE ; THを超えていたのでBEND作成
- L_BEND_CHECK_UNDER
- MOVLW MIDI_BEND_TH ; BENDしきい値と比較
- SUBWF MIDI_BEND_C, W ; 中心 ( 実測 ) から減算
- SUBWF MIDI_BEND, W ; THより小さいかチェック
- BTFSS STATUS, C ; 負だったら小さい ( C = 0 )
- GOTO L_BEND_MAKE ; THを超えていたのでBEND作成
- L_BEND_CHECK_CENTER ; 中心誤差の範囲でした
- MOVLW D'0' ; 中心
- L_BEND_MAKE
- ADDLW MIDI_C_BEND_C ; 中心加算
- MOVWF MIDI_BEND ; BEND完成
- ; LMHチェック
- MOVLW 0x00 ; クリア
- BTFSC SW_OCT_L ; -?
- ADDLW MIDI_C_LMH ; 12加算
- BTFSS SW_OCT_H ; +?
- ADDLW MIDI_C_LMH ; 12加算
- MOVWF MIDI_LMH ; LMH設定
- ; HOLDチェック
- BTFSC SW_HOLD ; ホールドされてる?
- MOVLW 0 ; 離されてればホールドなし
- BTFSS SW_HOLD
- MOVLW D'127' ; 押されてればホールド
- MOVWF MIDI_HOLD ; 保存
- ; ボタンチェック
- L_CHECK_BUTTON
- BTFSS F_KEY_PC ; 前回PCあった?
- GOTO L_CHECK_PC_UP ; なかった
- BCF F_KEY_PC
- BTFSS SW_PG_UP ; フラグ操作
- BSF F_KEY_PC
- BTFSS SW_PG_DOWN
- BSF F_KEY_PC
- GOTO L_CHECK_LCD_CHANGE ; LCDチェックへ
- L_CHECK_PC_UP
- BTFSC SW_PG_UP ; PGUP?
- GOTO L_CHECK_PC_DOWN ; 違った
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BSF F_KEY_PC ; PCフラグON
- INCF MIDI_PROG, F ; PROGインクリメント
- MOVF MIDI_PROG, W ; 128超えた?
- SUBLW D'128'
- BTFSC STATUS, Z
- CLRF MIDI_PROG ; 超えてた
- L_CHECK_PC_DOWN
- BTFSC SW_PG_DOWN ; PGDOWN?
- GOTO L_CHECK_LCD_CHANGE ; 違った
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BSF F_KEY_PC ; PCフラグON
- DECF MIDI_PROG, F ; PROGデクリメント
- MOVF MIDI_PROG, W ; 0すぎたかチェック
- SUBLW 0xFF ; 0すぎた?
- BTFSS STATUS, Z
- GOTO $ + D'3' ; 過ぎてなかった
- MOVLW D'127' ; PROGを127に
- MOVWF MIDI_PROG
- ; 液晶の書き換えが必要かチェック
- L_CHECK_LCD_CHANGE
- BCF F_KEY_LCD ; フラグ解除
- BCF F_KEY_C_VELO
- BCF F_KEY_C_HOLD
- BCF F_KEY_C_BEND
- BCF F_KEY_C_VOL
- BCF F_KEY_C_LMH
- BCF F_KEY_C_PROG
- MOVF MIDI_B_BEND, W ; 前回とのチェック
- SUBWF MIDI_BEND, W
- BTFSC STATUS, Z
- GOTO $ + D'3'
- BSF F_KEY_LCD
- BSF F_KEY_C_BEND
- MOVF MIDI_BEND, W
- MOVWF MIDI_B_BEND
- MOVF MIDI_B_VOL, W ; 前回とのチェック
- SUBWF MIDI_VOL, W
- BTFSC STATUS, Z
- GOTO $ + D'3'
- BSF F_KEY_LCD
- BSF F_KEY_C_VOL
- MOVF MIDI_VOL, W
- MOVWF MIDI_B_VOL
- MOVF MIDI_B_VELO, W ; 前回とのチェック
- SUBWF MIDI_VELO, W
- BTFSC STATUS, Z
- GOTO $ + D'3'
- BSF F_KEY_LCD
- BSF F_KEY_C_VELO
- MOVF MIDI_VELO, W
- MOVWF MIDI_B_VELO
- MOVF MIDI_B_LMH, W ; 前回とのチェック
- SUBWF MIDI_LMH, W
- BTFSC STATUS, Z
- GOTO $ + D'3'
- BSF F_KEY_LCD
- BSF F_KEY_C_LMH
- MOVF MIDI_LMH, W
- MOVWF MIDI_B_LMH
- MOVF MIDI_B_HOLD, W ; 前回とのチェック
- SUBWF MIDI_HOLD, W
- BTFSC STATUS, Z
- GOTO $ + D'3'
- BSF F_KEY_LCD
- BSF F_KEY_C_HOLD
- MOVF MIDI_HOLD, W
- MOVWF MIDI_B_HOLD
- MOVF MIDI_B_PROG, W ; 前回とのチェック
- SUBWF MIDI_PROG, W
- BTFSC STATUS, Z
- GOTO $ + D'3'
- BSF F_KEY_LCD
- BSF F_KEY_C_PROG
- MOVF MIDI_PROG, W
- MOVWF MIDI_B_PROG
- ; MODEに入るかチェック ( 3秒押さなければならない )
- BTFSC SW_MODE ; 押されてる?
- GOTO L_KEY_CHECK ; 押されてなかった
- BCF INTCON, GIE ; 割り込み対策
- CALL TIME05S ; 1.5秒まつ
- CALL TIME05S
- CALL TIME05S
- BSF INTCON, GIE ; 割り込み対策
- BTFSC SW_MODE ; 押されてる?
- GOTO L_KEY_CHECK
- GOTO MODE ; MODE画面へ
- ; キーチェック
- L_KEY_CHECK
- CLRF KEY_POS ; キー位置初期化
- L_KEY_CHECK_LOOP
- MOVF KEY_POS, W ; キー位置読み出し
- MOVWF PORTD ; ポートへ設定
- MOVF KEY_POS, W ; キー位置読み出し
- ADDLW 0xA0 ; アドレス基準値を足す
- MOVWF FSR ; FSRに設定
- BCF STATUS, IRP ; BANK0-1
- MOVF INDF, W ; INDF経由で前回のキー状態を読み出し
- MOVWF KEY_BUF ; バッファへ
- BTFSS KEY_IN ; キーの状態は?
- GOTO L_KEY_ON ; 押されてた
- GOTO L_KEY_OFF ; 押されてなかった
- L_KEY_OFF ; 押されてなかった
- BTFSS KEY_BUF, 0 ; 前は押されてた?
- GOTO L_KEY_NEXT ; 変更がなかったので次へ
- L_KEY_OFF_CHANGE ; 押されてた
- MOVLW 0 ; キーを離す
- MOVWF INDF ; INDF経由で転送
- MOVF KEY_POS, W ; キー位置読み出し
- CALL KEY_TO_MIDI ; キー位置をMIDIに変換
- MOVWF KEY_BUF ; バッファに保存
- BCF INTCON, GIE ; 割り込み禁止
- CALL MIDI_SEND_STA_NOTE_OFF ; ノートオフ
- MOVF KEY_BUF, W ; ノート送信
- CALL MIDI_SEND_BYTE ; 送信
- MOVLW 0x00 ; とりあえず0
- CALL MIDI_SEND_BYTE ; 送信
- BSF INTCON, GIE ; 割り込み再開
- GOTO L_KEY_NEXT ; 次へ
- L_KEY_ON
- BTFSC KEY_BUF, 0 ; 前は押されてなかった?
- GOTO L_KEY_NEXT ; 変更がなければ次へ
- L_KEY_ON_CHANGE ; 変更があった
- MOVLW 1 ; キーを押す
- MOVWF INDF ; INDF経由で転送
- MOVF KEY_POS, W ; キー位置読み出し
- CALL KEY_TO_MIDI ; キー位置をMIDIに変換
- MOVWF KEY_BUF ; バッファに保存
- BCF INTCON, GIE ; 割り込み禁止
- CALL MIDI_SEND_STA_NOTE_ON ; ノートオン
- MOVF KEY_BUF, W ; ノート送信
- CALL MIDI_SEND_BYTE ; 送信
- MOVF MIDI_VELO, W ; キー押す
- CALL MIDI_SEND_BYTE ; 送信
- BSF INTCON, GIE ; 割り込み再開
- GOTO L_KEY_NEXT ; 次へ
- L_KEY_NEXT ; 次のキーへ
- INCF KEY_POS, F ; キー位置加算
- MOVF KEY_POS, W ; キー位置取り出し
- SUBLW D'41' ; オーバーした?
- BTFSS STATUS, Z ; オーバーかチェック
- GOTO L_KEY_CHECK_LOOP ; オーバーしてなかった
- ; キーサーチ終了、その他MIDIメッセージ送信
- L_KEY_SEND_HOLD
- BTFSS F_KEY_C_HOLD ; 変更あり?
- GOTO L_KEY_SEND_PC ; なかった
- BCF INTCON, GIE ; 割り込み禁止
- CALL MIDI_SEND_STA_CTRL ; コントロール送信 ( HOLD用 )
- MOVLW MIDI_CTRL_HOLD ; ホールドコントロール
- CALL MIDI_SEND_BYTE
- MOVF MIDI_HOLD, W ; 押されてればホールド
- CALL MIDI_SEND_BYTE
- BSF INTCON, GIE ; 割り込み再開
- L_KEY_SEND_PC
- BTFSS F_KEY_C_PROG ; PCあった?
- GOTO L_KEY_SEND_VOL ; なかった
- BCF INTCON, GIE ; 割り込み禁止
- CALL MIDI_SEND_STA_PROG ; プログラムチェンジ送信
- MOVF MIDI_PROG, W ; プログラムナンバー取得
- CALL MIDI_SEND_BYTE ; 送信
- BSF INTCON, GIE ; 割り込み再開
- L_KEY_SEND_VOL
- BTFSS F_KEY_C_VOL
- GOTO L_KEY_SEND_BEND
- BCF INTCON, GIE ; 割り込み禁止
- CALL MIDI_SEND_STA_CTRL ; コントロール送信 ( VOL用 )
- MOVLW MIDI_CTRL_VOL_M ; MSB送信
- CALL MIDI_SEND_BYTE ; 送信
- MOVF MIDI_VOL, W ; ボリュームロード
- CALL MIDI_SEND_BYTE ; 送信
- BSF INTCON, GIE ; 割り込み再開
- L_KEY_SEND_BEND
- BTFSS F_KEY_C_BEND
- GOTO L_KEY_CHANGE_LCD
- BCF INTCON, GIE ; 割り込み禁止
- CALL MIDI_SEND_STA_BEND ; ピッチベンド
- MOVLW 0x00 ; LSBは0 ( ! )
- CALL MIDI_SEND_BYTE
- MOVF MIDI_BEND, W ; MSB読み出し
- CALL MIDI_SEND_BYTE
- BSF INTCON, GIE ; 割り込み再開
- L_KEY_CHANGE_LCD ; 液晶更新 ( CALLが増えないようにCALL廃止 )
- ;BTFSS F_KEY_LCD
- ;GOTO L_KEY_END_LOOP
- MOVLW LCD_CUR_1L ; 1行目へ
- CALL LCD_CUR ; 位置設定
- MOVLW 'V' ; VOL
- CALL LCD_SEND
- MOVLW 'O'
- CALL LCD_SEND
- MOVF MIDI_VOL, W ; VOL数値表示
- CALL TOSTR
- MOVF TOSTR_100, W
- CALL LCD_SEND
- MOVF TOSTR_10, W
- CALL LCD_SEND
- MOVF TOSTR_1, W
- CALL LCD_SEND
- MOVLW ' ' ; 空白
- CALL LCD_SEND
- MOVLW 'B' ; BEND
- CALL LCD_SEND
- MOVF MIDI_BEND, W ; P.BEND数値表示
- CALL TOSTR
- MOVF TOSTR_100, W
- CALL LCD_SEND
- MOVF TOSTR_10, W
- CALL LCD_SEND
- MOVF TOSTR_1, W
- CALL LCD_SEND
- MOVLW ' ' ; 空白
- CALL LCD_SEND
- MOVLW 'C' ; CH
- CALL LCD_SEND
- MOVF MIDI_CH, W ; CH数値表示
- CALL TOSTR
- MOVF TOSTR_10, W
- CALL LCD_SEND
- MOVF TOSTR_1, W
- CALL LCD_SEND
- MOVLW ' ' ; 空白
- CALL LCD_SEND
- MOVLW 'M' ; LMH出力
- BTFSS SW_OCT_L ; L
- MOVLW 'L'
- BTFSS SW_OCT_H ; H
- MOVLW 'H'
- CALL LCD_SEND
- MOVLW LCD_CUR_2L ; 2行目へ
- CALL LCD_CUR ; 位置設定
- MOVLW 'V' ; VEL
- CALL LCD_SEND
- MOVLW 'E'
- CALL LCD_SEND
- MOVF MIDI_VELO, W ; VEL数値表示
- CALL TOSTR
- MOVF TOSTR_100, W
- CALL LCD_SEND
- MOVF TOSTR_10, W
- CALL LCD_SEND
- MOVF TOSTR_1, W
- CALL LCD_SEND
- MOVLW ' ' ; 空白
- CALL LCD_SEND
- MOVLW 'P' ; PROGRAM
- CALL LCD_SEND
- MOVF MIDI_PROG, W ; PROG数値表示
- CALL TOSTR
- MOVF TOSTR_100, W
- CALL LCD_SEND
- MOVF TOSTR_10, W
- CALL LCD_SEND
- MOVF TOSTR_1, W
- CALL LCD_SEND
- MOVLW ' ' ; 空白
- CALL LCD_SEND
- MOVLW ' ' ; 空白
- CALL LCD_SEND
- BTFSS F_PLAY_PLAY ; 再生中
- GOTO $ + D'9'
- MOVLW 'P'
- CALL LCD_SEND
- MOVLW 'L'
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'Y'
- CALL LCD_SEND
- BTFSC F_PLAY_PLAY
- GOTO $ + D'9'
- MOVLW 'S'
- CALL LCD_SEND
- MOVLW 'T'
- CALL LCD_SEND
- MOVLW 'O'
- CALL LCD_SEND
- MOVLW 'P'
- CALL LCD_SEND
- L_KEY_END_LOOP
- CALL TIME1M ; 待ってみる DEBUG
- CALL TIME1M
- CALL TIME1M
- CALL TIME1M
- CALL TIME1M
- GOTO MAIN ; メインループ
- ; * MODE **********************************************************************
- MODE ; モード画面
- CLRF MODE_POS ; クリア
- CALL LCD_CLR ; 画面クリア
- ; スイッチチェック
- L_MODE_LOOP
- L_MODE_SW_UP
- BTFSC SW_PG_UP ; 上がおされた?
- GOTO L_MODE_SW_DOWN ; おされてない
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BTFSS SW_PG_UP ; 押されてる限り進まない
- GOTO $ - D'1'
- INCF MODE_POS, F ; モード変更
- MOVLW MODE_MAX ; 最大値超えた?
- ADDLW D'1' ; MAX + 1
- SUBWF MODE_POS, W
- BTFSC STATUS, Z
- CLRF MODE_POS ; 0に
- L_MODE_SW_DOWN
- BTFSC SW_PG_DOWN ; 下が押されてた?
- GOTO L_MODE_PAINT ; 押されてなかった
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BTFSS SW_PG_DOWN ; 押されてる限り進まない
- GOTO $ - D'1'
- DECF MODE_POS, F ; モード変更
- MOVLW 0xFF ; 0超えた?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_PAINT
- MOVLW MODE_MAX ; 過ぎてたのでMAXに
- MOVWF MODE_POS
- ; 画面に現在の状態を表示
- L_MODE_PAINT
- MOVLW LCD_CUR_1L ; 1行目へ
- CALL LCD_CUR ; 位置設定
- MOVLW 'M' ; MODE
- CALL LCD_SEND
- MOVLW 'O'
- CALL LCD_SEND
- MOVLW 'D'
- CALL LCD_SEND
- MOVLW 'E'
- CALL LCD_SEND
- MOVLW LCD_CUR_2L ; 2行目へ
- CALL LCD_CUR ; 位置設定
- L_MODE_PAINT_FORMAT
- MOVLW MODE_FORMAT ; FORMAT?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_PAINT_STOP ; 次へ
- MOVLW 'F'
- CALL LCD_SEND
- MOVLW 'O'
- CALL LCD_SEND
- MOVLW 'R'
- CALL LCD_SEND
- MOVLW 'M'
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'T'
- CALL LCD_SEND
- MOVLW D'10' ; スペースで埋める
- MOVWF MODE_BUF
- MOVLW ' '
- CALL LCD_SEND
- DECFSZ MODE_BUF, F
- GOTO $ - D'3'
- L_MODE_PAINT_STOP
- MOVLW MODE_STOP ; STOP?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_PAINT_PLAY ; 次へ
- MOVLW 'S'
- CALL LCD_SEND
- MOVLW 'T'
- CALL LCD_SEND
- MOVLW 'O'
- CALL LCD_SEND
- MOVLW 'P'
- CALL LCD_SEND
- MOVLW D'12' ; スペースで埋める
- MOVWF MODE_BUF
- MOVLW ' '
- CALL LCD_SEND
- DECFSZ MODE_BUF, F
- GOTO $ - D'3'
- L_MODE_PAINT_PLAY
- MOVLW MODE_PLAY ; PLAY?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_PAINT_CANCEL ; 次へ
- MOVLW 'P'
- CALL LCD_SEND
- MOVLW 'L'
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'Y'
- CALL LCD_SEND
- MOVLW D'12' ; スペースで埋める
- MOVWF MODE_BUF
- MOVLW ' '
- CALL LCD_SEND
- DECFSZ MODE_BUF, F
- GOTO $ - D'3'
- L_MODE_PAINT_CANCEL
- MOVLW MODE_CANCEL ; CANCEL?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_PAINT_CH ; 次へ
- MOVLW 'C'
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'N'
- CALL LCD_SEND
- MOVLW 'C'
- CALL LCD_SEND
- MOVLW 'E'
- CALL LCD_SEND
- MOVLW 'L'
- CALL LCD_SEND
- MOVLW D'10' ; スペースで埋める
- MOVWF MODE_BUF
- MOVLW ' '
- CALL LCD_SEND
- DECFSZ MODE_BUF, F
- GOTO $ - D'3'
- L_MODE_PAINT_CH
- MOVLW MODE_CH
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_CHECK_ENTER ; 次へ
- MOVLW 'C'
- CALL LCD_SEND
- MOVLW 'H'
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'N'
- CALL LCD_SEND
- MOVLW 'N'
- CALL LCD_SEND
- MOVLW 'E'
- CALL LCD_SEND
- MOVLW 'L'
- CALL LCD_SEND
- MOVLW D'9' ; スペースで埋める
- MOVWF MODE_BUF
- MOVLW ' '
- CALL LCD_SEND
- DECFSZ MODE_BUF, F
- GOTO $ - D'3'
- L_MODE_CHECK_ENTER ; 決定されるかチェック
- BTFSC SW_HOLD ; 押されてる? ( HOLDがエンターキー )
- GOTO L_MODE_LOOP
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BTFSS SW_HOLD ; 押されてる限り進まない
- GOTO $ - D'1'
- MOVLW D'40' ; チャタリング防止のためまつ ( 長め )
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- L_MODE_CANCEL
- MOVLW MODE_CANCEL ; キャンセルか?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_FORMAT ; 違った
- GOTO L_MODE_EXIT
- L_MODE_FORMAT ; カードフォーマッタ起動
- MOVLW MODE_FORMAT ; フォーマットか?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_PLAY ; 違った
- BTFSC F_PLAY_PLAY ; 再生中だとなにもしない
- GOTO L_MODE_EXIT
- CALL LCD_CLR ; 画面クリア
- MOVLW LCD_CUR_1L ; 1行目へ
- CALL LCD_CUR ; 位置設定
- MOVLW 'W' ; WAIT
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'I'
- CALL LCD_SEND
- MOVLW 'T'
- CALL LCD_SEND
- MOVLW '.'
- CALL LCD_SEND
- MOVLW '.'
- CALL LCD_SEND
- MOVLW '.'
- CALL LCD_SEND
- CALL MMC_INIT ; MMCを初期化
- CLRF MMC_ARG
- CLRF MMC_ARG1
- CLRF MMC_ARG2
- CLRF MMC_ARG3
- ; MMCへFAT12ファイルシステムと、ひとつのテキストファイル書き込み開始
- CALL MMC_WRITE_HEAD ; MMCへ書き込み開始
- MOVLW D'62' ; 先頭の62バイト送信開始
- MOVWF PG_CNT1 ; 汎用カウンタ1へ
- CLRF PG_POINT1 ; 汎用ポインタをブートセクタ読み出しポインタにする
- CALL T_GET_BOOTSECTOR ; ブートセクター取得用関数
- INCF PG_POINT1, F ; ポインタ加算
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F ; 62バイト送った?
- GOTO $ - D'4' ; 繰り返し
- MOVLW D'18' ; 18バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW D'215' ; 215バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW D'215' ; 215バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW 055H ; ブートフラグ立てる
- CALL SPI_START
- MOVLW 0AAH
- CALL SPI_START
- CALL MMC_WRITE_FOOT ; 送信第一段階完了
- MOVLW D'2' ; 第二セクターへ
- MOVWF MMC_ARG2 ; 引数設定
- CALL MMC_WRITE_HEAD ; 送信第二段階開始
- MOVLW 0F0H ; 第一FAT書き込み開始 ( 512バイト以内のファイルを一個含む )
- CALL SPI_START
- MOVLW 0FFH
- CALL SPI_START
- MOVLW 0FFH
- CALL SPI_START
- MOVLW 0FFH
- CALL SPI_START
- MOVLW 00FH
- CALL SPI_START
- MOVLW D'255' ; 255バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW D'252' ; 252バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- CALL MMC_WRITE_FOOT ; 送信第2段階完了
- MOVLW D'8' ; 8回
- MOVWF PG_CNT2
- L_MODE_FORMAT_FAT_L
- INCF MMC_ARG2, F ; 残りのFATを0で埋めておく
- INCF MMC_ARG2, F
- CALL MMC_WRITE_HEAD ; 書き込み開始
- MOVLW 0x00 ; 0
- CALL SPI_START
- MOVLW 0x00 ; 0
- CALL SPI_START
- MOVLW D'255' ; 255バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW D'255' ; 255バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- CALL MMC_WRITE_FOOT ; 完了
- DECFSZ PG_CNT2, F ; 8回うめた?
- GOTO L_MODE_FORMAT_FAT_L ; 埋めてない
- ; ここまででFAT自体は完了、以下、適当ファイル書き込み開始
- MOVLW 026H ; ファイル情報開始
- MOVWF MMC_ARG2
- CALL MMC_WRITE_HEAD ; ファイル情報書き込み開始
- MOVLW 'T' ; ファイル名8.3形式
- CALL SPI_START
- MOVLW 'E'
- CALL SPI_START
- MOVLW 'S'
- CALL SPI_START
- MOVLW 'T'
- CALL SPI_START
- MOVLW ' '
- CALL SPI_START
- MOVLW ' '
- CALL SPI_START
- MOVLW ' '
- CALL SPI_START
- MOVLW ' '
- CALL SPI_START
- MOVLW 'T'
- CALL SPI_START
- MOVLW 'X'
- CALL SPI_START
- MOVLW 'T'
- CALL SPI_START
- MOVLW 020H ; ファイルタイプ
- CALL SPI_START
- MOVLW D'10' ; 10バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW 00H ; ファイルの時間
- CALL SPI_START
- MOVLW 00H
- CALL SPI_START
- MOVLW 22H ; ファイルの日付
- CALL SPI_START
- MOVLW 22H
- CALL SPI_START
- MOVLW 02H ; ファイルの開始クラスタナンバー
- CALL SPI_START
- MOVLW 00H
- CALL SPI_START
- MOVLW D'10' ; ファイルサイズ
- CALL SPI_START
- MOVLW 00H
- CALL SPI_START
- MOVLW 00H
- CALL SPI_START
- MOVLW 00H
- CALL SPI_START
- MOVLW D'255' ; 255バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW D'225' ; 225バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- CALL MMC_WRITE_FOOT ; ファイル情報書き込み完了
- ; ファイル開始
- MOVLW 042H ; ファイル開始アドレス指定
- MOVWF MMC_ARG2
- CALL MMC_WRITE_HEAD ; ファイル書き込み開始
- MOVLW 'P' ; 適当な文字列
- CALL SPI_START
- MOVLW 'I'
- CALL SPI_START
- MOVLW 'C'
- CALL SPI_START
- MOVLW '*'
- CALL SPI_START
- MOVLW 'F'
- CALL SPI_START
- MOVLW 'A'
- CALL SPI_START
- MOVLW 'T'
- CALL SPI_START
- MOVLW '!'
- CALL SPI_START
- MOVLW 00DH
- CALL SPI_START
- MOVLW 00AH
- CALL SPI_START
- MOVLW D'255' ; 255バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- MOVLW D'247' ; 253バイト0送る
- MOVWF PG_CNT1
- MOVLW 00H ; 0
- CALL SPI_START ; 送信
- DECFSZ PG_CNT1, F
- GOTO $ - D'3'
- CALL MMC_WRITE_FOOT ; ファイル書き込み完了
- CALL LCD_CLR ; 画面クリア
- MOVLW LCD_CUR_1L ; 1行目へ
- CALL LCD_CUR ; 位置設定
- MOVLW 'O' ; 完了
- CALL LCD_SEND
- MOVLW 'K' ; 完了
- CALL LCD_SEND
- MOVLW '!' ; 完了
- CALL LCD_SEND
- CALL TIME05S ; ちょっとまつ
- CALL TIME05S
- CALL TIME05S
- CALL TIME05S
- GOTO L_MODE_EXIT
- L_MODE_PLAY ; 再生する
- MOVLW MODE_PLAY ; 再生か?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_STOP ; 違った
- BTFSC F_PLAY_PLAY ; 再生中?
- GOTO L_MODE_STOP ; だった
- CALL MMC_INIT ; MMC初期化
- L_MODE_PLAY_LOOP ; FAT12ある程度アクセスに挑戦!
- ; ファイル情報までジャンプ
- CALL FILE_READ_STOP ; もどってきた場合、一度読み込みを止めるため
- MOVLW 0x26 ; ファイル情報の先頭
- CALL FILE_READ_SET_START ; ファイルリード関数準備
- CALL FILE_READ_START
- L_MODE_PLAY_LOOP_NEXT ; 次のファイル情報へアクセス
- CALL LCD_CLR ; 画面クリア
- MOVLW LCD_CUR_1L ; 1行目へ
- CALL LCD_CUR ; 位置設定
- ; FILE NAME
- MOVLW 'F' ; FILENAMEと表示
- CALL LCD_SEND
- MOVLW 'I'
- CALL LCD_SEND
- MOVLW 'L'
- CALL LCD_SEND
- MOVLW 'E'
- CALL LCD_SEND
- MOVLW ' '
- CALL LCD_SEND
- MOVLW 'N'
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'M'
- CALL LCD_SEND
- MOVLW 'E'
- CALL LCD_SEND
- MOVLW LCD_CUR_2L ; 2行目へ
- CALL LCD_CUR ; 位置設定
- ; ファイル名取得
- CALL FILE_READ ; 1文字目読み込み
- MOVWF PG_CNT2 ; 保存しておく ( 存在判定用 )
- CALL LCD_SEND ; 出力
- MOVLW D'7' ; ファイル名ロード
- MOVWF PG_CNT1 ; カウンタセット
- CALL FILE_READ ; 読み出し
- MOVWF PG_BUF1 ; バッファへ
- MOVLW ' ' ; スペース?
- SUBWF PG_BUF1, W ; スペース?
- SWAPF PG_BUF1, F ; めんどくさいのでSWAP
- SWAPF PG_BUF1, W ; SWAPで読み出し
- BTFSS STATUS, Z ; スペースなら表示しない
- CALL LCD_SEND ; そのまま書きこみ
- DECFSZ PG_CNT1, F ; 全部読んだ?
- GOTO $ - D'9'
- MOVLW '.' ; .
- CALL LCD_SEND
- MOVLW D'3' ; 拡張子ロード
- MOVWF PG_CNT1 ; カウンタセット
- CALL FILE_READ ; 読み出し
- CALL LCD_SEND ; そのまま書きこみ
- DECFSZ PG_CNT1, F ; 全部読んだ?
- GOTO $ - D'3'
- ; から読み
- MOVLW D'15'
- MOVWF PG_CNT1
- CALL FILE_READ
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- ; 開始場所ロード
- CALL FILE_READ
- MOVWF PLAY_CLS_0
- CALL FILE_READ
- MOVWF PLAY_CLS_1
- ; サイズは読み捨て
- CALL FILE_READ
- CALL FILE_READ
- CALL FILE_READ
- CALL FILE_READ
- ; ファイルが存在するかチェック ( ファイル名の先頭が0xE5か0x00を利用 )
- MOVF PG_CNT2, F
- BTFSC STATUS, Z ; 最初の文字が0なら最後のエントリなので最初に戻る
- GOTO L_MODE_PLAY_LOOP
- MOVLW 0xE5 ; 削除済み?
- SUBWF PG_CNT2, W ; 削除済み?
- BTFSC STATUS, Z
- GOTO L_MODE_PLAY_LOOP_NEXT ; 削除済みなので次のエントリへ
- ; 開始場所をセクターに変換
- L_MODE_PLAY_CONV_SECT
- BCF STATUS, C ; キャリークリア
- RLF PLAY_CLS_0, F ; *2
- RLF PLAY_CLS_1, F ; *2
- MOVLW 0x3E ; 基準加算
- ADDWF PLAY_CLS_0, F
- BTFSC STATUS, C ; キャリーチェック
- INCF PLAY_CLS_1, F ; キャリーが発生してれば加算
- L_MODE_PLAY_SW_UP
- BTFSC SW_PG_UP ; 上がおされた?
- GOTO L_MODE_PLAY_SW_DOWN ; おされてない
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BTFSS SW_PG_UP ; 押されてる限り進まない
- GOTO $ - D'1'
- GOTO L_MODE_PLAY_LOOP_NEXT ; 繰り返し
- L_MODE_PLAY_SW_DOWN
- BTFSC SW_PG_DOWN ; 下が押されてた?
- GOTO L_MODE_PLAY_CHECK_ENTER ; 押されてなかった
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BTFSS SW_PG_DOWN ; 押されてる限り進まない
- GOTO $ - D'1'
- GOTO L_MODE_PLAY_LOOP_NEXT ; 繰り返し
- L_MODE_PLAY_CHECK_ENTER ; 決定された
- BTFSC SW_HOLD ; された?
- GOTO L_MODE_PLAY_SW_UP ; されてないのでスイッチチェックに戻る
- CALL FILE_READ_STOP ; 読み込み停止
- CALL PLAY_PLAY ; されたので再生
- GOTO L_MODE_EXIT
- L_MODE_STOP
- MOVLW MODE_STOP ; 停止?
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_CH ; 違った
- BCF INTCON, GIE
- CALL PLAY_STOP ; 停止
- BSF INTCON, GIE
- GOTO L_MODE_EXIT
- L_MODE_CH ; チャンネル変更?
- MOVLW MODE_CH
- SUBWF MODE_POS, W
- BTFSS STATUS, Z
- GOTO L_MODE_EXIT ; 違った
- CALL LCD_CLR ; クリア
- MOVLW LCD_CUR_1L ; 1行目へ
- CALL LCD_CUR ; 位置設定
- MOVLW 'C'
- CALL LCD_SEND
- MOVLW 'H'
- CALL LCD_SEND
- MOVLW 'A'
- CALL LCD_SEND
- MOVLW 'N'
- CALL LCD_SEND
- MOVLW 'N'
- CALL LCD_SEND
- MOVLW 'E'
- CALL LCD_SEND
- MOVLW 'L'
- CALL LCD_SEND
- L_MODE_CH_LOOP
- L_MODE_CH_SW_UP
- BTFSC SW_PG_UP ; 上がおされた?
- GOTO L_MODE_CH_SW_DOWN ; おされてない
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BTFSS SW_PG_UP ; 押されてる限り進まない
- GOTO $ - D'1'
- INCF MIDI_CH, F ; モード変更
- MOVLW D'16' ; 最大値超えた?
- SUBWF MIDI_CH, W
- BTFSC STATUS, Z
- CLRF MIDI_CH ; 0に
- L_MODE_CH_SW_DOWN
- BTFSC SW_PG_DOWN ; 下が押されてた?
- GOTO L_MODE_CH_PUT ; 押されてなかった
- MOVLW D'20' ; チャタリング防止のためまつ
- MOVWF PG_CNT1 ; 汎用カウンタ
- CALL TIME1M
- DECFSZ PG_CNT1, F
- GOTO $ - D'2'
- BTFSS SW_PG_DOWN ; 押されてる限り進まない
- GOTO $ - D'1'
- DECF MIDI_CH, F ; モード変更
- MOVLW 0xFF ; 0超えた?
- SUBWF MIDI_CH, W
- BTFSS STATUS, Z
- GOTO L_MODE_CH_PUT
- MOVLW D'15' ; 過ぎてたのでMAXに
- MOVWF MIDI_CH
- L_MODE_CH_PUT
- MOVLW LCD_CUR_2L ; 2行目へ
- CALL LCD_CUR ; 位置設定
- MOVF MIDI_CH, W ; 読み出し
- CALL TOSTR ; 文字に変換
- MOVF TOSTR_10, W
- CALL LCD_SEND
- MOVF TOSTR_1, W
- CALL LCD_SEND
- BTFSS SW_HOLD ; 決定された?
- GOTO L_MODE_EXIT ; された
- GOTO L_MODE_CH_LOOP ; されてない
- L_MODE_EXIT ; MODEモード終了
- GOTO MAIN ; MAINに戻る ( 液晶を更新してもらう )
- ; * INT ***********************************************************************
- INT ; 割り込みルーチン開始
- PUSH MOVWF TMP_W ; Wreg退避 ( 共通アクセス可能領域へ )
- SWAPF STATUS, W ; SWAP命令はフラグに影響しないので、これを使ってSTATUS退避
- CLRF STATUS ; BANK0に切り替え ( 割り込みはBANK0で )
- MOVWF TMP_STATUS ; STATUS退避
- MOVF PCLATH, W ; PCLATH退避
- MOVWF TMP_PCLATH
- CLRF PCLATH ; PAGE0へ ( 割り込みはPAGE0で )
- MOVF FSR, W ; FSR退避
- MOVWF TMP_FSR
- INT_CHECK
- BTFSS INTCON, T0IE ; タイマ0割り込み使えるか
- GOTO $ + D'3' ; 使えない
- BTFSC INTCON, T0IF ; タイマ0割り込み
- GOTO INT_T0 ; T0のINTへ
- BSF STATUS, RP0 ; BANK1へ
- BTFSS PIE1, TXIE ; 送信割り込み許可?
- GOTO $ + D'4'
- BCF STATUS, RP0 ; BANK0
- BTFSC PIR1, TXIF ; 送信完了割り込み
- GOTO INT_TX ; TXのINTへ
- BSF STATUS, RP0 ; BANK1へ
- BTFSS PIE1, SSPIE ; SPI割り込み許可
- GOTO $ + D'4'
- BCF STATUS, RP0 ; BANK0
- BTFSC PIR1, SSPIF ; SPI完了割り込み
- GOTO INT_SPI ; SPIのINTへ
- BCF STATUS, RP0 ; BANK0
- GOTO POP ; 脱出
- INT_T0 ; タイマ0割り込み ( MIDIプレーヤー用 )
- BTFSS F_PLAY_DELTA ; デルタ処理中?
- GOTO INT_T0_READ_NEXT ; 違った
- INT_T0_DELTA ; デルタ処理
- MOVF PLAY_TEMPO, W ; テンポ読み出し
- MOVWF TMR0 ; タイマ0再設定 ( プリスケーラクリア、カウント再開 )
- CLRF PLAY_D_BUF
- MOVF PLAY_D_0, F ; 全部0かチェック
- BTFSS STATUS, Z
- INCF PLAY_D_BUF, F
- MOVF PLAY_D_1, F
- BTFSS STATUS, Z
- INCF PLAY_D_BUF, F
- MOVF PLAY_D_2, F
- BTFSS STATUS, Z
- INCF PLAY_D_BUF, F
- MOVF PLAY_D_3, F
- BTFSS STATUS, Z
- INCF PLAY_D_BUF, F
- MOVF PLAY_D_BUF, F
- BTFSC STATUS, Z ; 0だった?
- GOTO INT_T0_DELTA_SEND_MIDI ; MIDI送信へ
- DECF PLAY_D_0, F ; 32bitデクリメント
- MOVF PLAY_D_0, W
- SUBLW 0xFF ; ボローした?
- BTFSS STATUS, Z
- GOTO INT_T0_OUT
- DECF PLAY_D_1, F
- MOVF PLAY_D_1, W
- SUBLW 0xFF
- BTFSS STATUS, Z
- GOTO INT_T0_OUT
- DECF PLAY_D_2, F
- MOVF PLAY_D_2, W
- SUBLW 0xFF
- BTFSS STATUS, Z
- GOTO INT_T0_OUT
- DECF PLAY_D_3, F
- MOVF PLAY_D_3, W
- SUBLW 0xFF
- BTFSS STATUS, Z
- GOTO INT_T0_OUT
- INT_T0_DELTA_SEND_MIDI ; MIDI送信 ( バッファにつめ込み )
- CALL FIFO_SD_GET ; ファイル読み込み
- CALL PLAY_PUT_BUF ; FIFOに詰め込み
- DECFSZ PLAY_DATAS, F ; 読み込み数カウント
- GOTO INT_T0_DELTA_SEND_MIDI
- BCF F_PLAY_DELTA ; デルタ処理終了
- GOTO INT_T0 ; すぐさま次のデータを処理
- INT_T0_READ_NEXT ; 次のデータへ
- CALL FIFO_SD_GET ; 1バイト読み込み
- MOVWF PLAY_BUF ; バッファへ退避
- INT_T0_READ_MIDI ; MIDIデータ
- ANDLW B'10000000' ; MIDIかチェック
- BTFSS STATUS, Z
- GOTO INT_T0_READ_TEMPO ; 違った
- MOVF PLAY_BUF, W ; バッファ取り出し
- ANDLW 0xF0 ; 上位取り出し
- MOVWF PLAY_DELTAS ; デルタ数に保存
- BCF STATUS, C ; フラグクリア
- RRF PLAY_DELTAS, F ; 4bitシフト
- RRF PLAY_DELTAS, F
- RRF PLAY_DELTAS, F
- RRF PLAY_DELTAS, F
- MOVF PLAY_BUF, W ; バッファ取り出し
- ANDLW 0x0F ; 下位取り出し
- MOVWF PLAY_DATAS ; データ数保存
- CLRF PLAY_D_3 ; デルタクリア
- CLRF PLAY_D_2
- CLRF PLAY_D_1
- CLRF PLAY_D_0
- MOVLW PLAY_D_0 ; FSR経由でデルタ保存
- MOVWF PLAY_D_BUF ; D_BUFをFSRに利用
- INT_T0_READ_MIDI_DELTA_L
- CALL FIFO_SD_GET ; 1バイト読み込み
- MOVWF PLAY_BUF ; バッファへ
- BCF STATUS, IRP ; BANK0-1
- MOVF PLAY_D_BUF, W ; FSR読み出し
- MOVWF FSR ; FSR設定
- MOVF PLAY_BUF, W ; バッファ取り出し
- MOVWF INDF ; FSR経由で書きこみ
- INCF PLAY_D_BUF, F ; アドレスインクリメント
- DECFSZ PLAY_DELTAS, F ; DELTA分よんだ?
- GOTO INT_T0_READ_MIDI_DELTA_L; くりかえし
- BSF F_PLAY_DELTA ; デルタ処理開始
- GOTO INT_T0 ; すぐさま割り込みへ戻る
- INT_T0_READ_TEMPO ; テンポ情報だった
- MOVF PLAY_BUF, W ; バッファを取り出し
- SUBLW 0xFE ; テンポ?
- BTFSS STATUS, Z ;
- GOTO INT_T0_READ_END ; 違った
- CALL FIFO_SD_GET ; 次の1バイト取得
- MOVWF PLAY_TEMPO ; テンポ情報保存
- GOTO INT_T0 ; テンポ情報の場合はすぐさま次を読む
- INT_T0_READ_END ; 終了だった
- CALL PLAY_STOP ; 停止
- ;BCF F_PLAY_PLAY ; 再生停止 ( CALL節約でここに書いた )
- ;BCF INTCON, T0IE ; T0I禁止
- ;BCF F_FIFO_SD_EN ; ディセーブル ( この時点でSPIが必ず開始しているので、割り込み側で終了させる )
- GOTO INT_T0_OUT ; 脱出
- INT_T0_OUT ; INTT0終了
- BCF INTCON, T0IF ; 割り込みフラグ解除
- GOTO INT_CHECK ; POP
- INT_TX ; 送信完了割り込み
- BTFSS F_PLAY_SEND ; 送信中フラグがたってなければPOPする
- GOTO INT_TX_OUT ; 脱出
- INT_TX_SEND ; 送信開始
- BSF STATUS, IRP ; BANK2-3
- DECF PLAY_COUNT, F ; 送信した分減らすした分減らす
- MOVF PLAY_FSR_S, W ; 送信位置を読み込み
- MOVF PLAY_FSR_S, W ; 送信位置を読み込み
- MOVWF FSR ; FSR設定
- INCF PLAY_FSR_S, F ; 送信位置インクリメント
- MOVF PLAY_FSR_S, W ; バッファを飛び出していないかチェック
- SUBLW PLAY_FSR_END ; 終点 + 1を引く
- BTFSS STATUS, Z
- GOTO INT_TX_SEND_SEND ; 送信部へ
- MOVLW PLAY_FSR_START ; バッファの最初へ
- MOVWF PLAY_FSR_S ; 送信位置再設定
- INT_TX_SEND_SEND
- MOVF INDF, W ; 1バイト読み込み
- MOVWF TXREG ; 送信 ( TXIF解除 )
- MOVF PLAY_COUNT, F ; 個数0になった?
- BTFSS STATUS, Z ; ゼロ?
- GOTO INT_TX_OUT ; ゼロではないので脱出
- MOVLW PLAY_FSR_START ; FSR初期値再設定
- MOVWF PLAY_FSR ; 初期化
- MOVWF PLAY_FSR_S
- BCF F_PLAY_SEND ; 送信中解除
- BSF STATUS, RP0 ; BANK1へ
- BCF PIE1, TXIE ; TX割り込み停止
- BCF STATUS, RP0 ; BANK0へ
- GOTO INT_TX_OUT ; 送信完了
- INT_TX_OUT ; 割り込み終了
- GOTO POP ; POP
- INT_SPI ; SPI用割り込み
- BTFSS F_FIFO_SD_EN ; イネーブル?
- GOTO L_INT_SPI_DISABLE ; ディセーブルする
- CALL FILE_READ_FIFO ; 受信データ取り出し ( 動くか心配 )
- MOVWF FIFO_SD_BUF ; バッファへ
- BSF STATUS, IRP ; BANK2-3
- MOVF FIFO_SD_W, W ; 書き込みFSRロード
- MOVWF FSR ; FSR設定
- MOVF FIFO_SD_BUF, W
- MOVWF INDF ; バッファへ書き込み
- INCF FIFO_SD_W, F ; FSR加算
- MOVF FIFO_SD_W, W ; FSRが飛び出してないかチェック
- SUBLW FIFO_SD_END ; 終了アドレス + 1
- BTFSS STATUS, Z ; 飛び出してた?
- GOTO $ + D'3' ; 飛び出してなかった
- MOVLW FIFO_SD_START ; 開始地点
- MOVWF FIFO_SD_W ; 設定
- INCF FIFO_SD_C, F ; たまり具合カウント
- MOVF FIFO_SD_C, W ; 溜まりきったかチェック
- SUBLW FIFO_SD_SIZE ; サイズを引く
- BTFSC STATUS, Z ; 溜まりきってた?
- GOTO L_INT_SPI_STOP ; 溜まりきってたので停止させる
- MOVLW 0FFH ; 適当なデータ
- MOVWF SSPBUF ; 通信開始
- GOTO INT_SPI_EXIT ; 脱出
- L_INT_SPI_STOP ; 受信停止
- BCF F_FIFO_SD_START ; 停止
- GOTO INT_SPI_EXIT ; 脱出
- L_INT_SPI_DISABLE ; バッファ貯めこみ中止 ( 今は使っていない = 廃止してもOK )
- CALL FILE_READ_FIFO ; 読み込み
- CALL FILE_READ_STOP ; 読み込み停止
- BCF F_FIFO_SD_START ; 停止
- BSF STATUS, RP0 ; BANK1へ
- BCF PIE1, SSPIE ; SSPI停止
- BCF STATUS, RP0 ; BANK0へ
- GOTO INT_SPI_EXIT ; 脱出
- INT_SPI_EXIT
- BCF PIR1, SSPIF ; 割り込みフラグ解除
- GOTO INT_CHECK ; 脱出
- POP MOVF TMP_FSR, W ; FSR復帰
- MOVWF FSR
- MOVF TMP_PCLATH, W ; PCLATH復帰
- MOVWF PCLATH
- SWAPF TMP_STATUS, W ; STATUS復帰
- MOVWF STATUS
- SWAPF TMP_W, F ; Wreg退避準備 ( STATUSに影響を与えないよう、SWAPをかます )
- SWAPF TMP_W, W ; Wreg復帰
- RETFIE ; 割り込みから復帰
- ; * キーボード制御 ************************************************************
- KEY_TO_MIDI ; KEYからMIDIに
- ADDLW MIDI_INI_NOTE ; 初期値加算
- ADDWF MIDI_LMH, W ; オクターブ情報加算
- RETURN
- KEY_READ_AD ; ADC読み込み
- MOVLW B'10000000' ; ADCON0初期値
- IORLW B'00000001' ; AN0変換開始
- MOVWF ADCON0 ; チャンネル0選択、使用開始
- CALL TIME50 ; 50マイクロまつ
- BSF ADCON0, GO ; 変換開始
- BTFSC ADCON0, GO ; 変換終了した?
- GOTO $ - D'1' ; まだ
- MOVF ADRESH, W ; 結果取り出し
- MOVWF MIDI_VELO ; ベロシティへ
- MOVLW B'10000000' ; ADCON0初期値
- IORLW B'00001001' ; AN1変換開始
- MOVWF ADCON0 ; チャンネル1選択、使用開始
- CALL TIME50 ; 50マイクロまつ
- BSF ADCON0, GO ; 変換開始
- BTFSC ADCON0, GO ; 変換終了した?
- GOTO $ - D'1' ; まだ
- MOVF ADRESH, W ; 結果取り出し
- MOVWF MIDI_BEND ; BENDへ
- MOVLW B'10000000' ; ADCON0初期値
- IORLW B'00011001' ; AN3変換開始
- MOVWF ADCON0 ; チャンネル3選択、使用開始
- CALL TIME50 ; 50マイクロまつ
- BSF ADCON0, GO ; 変換開始
- BTFSC ADCON0, GO ; 変換終了した?
- GOTO $ - D'1' ; まだ
- MOVF ADRESH, W ; 結果取り出し
- MOVWF MIDI_VOL ; ボリュームへ
- RETURN
- ; * MIDI制御 ******************************************************************
- MIDI_SEND_BYTE ; 1Byte送信
- CALL PLAY_PUT_BUF ; バッファへ詰め込み
- RETURN
- MIDI_SEND_STA_NOTE_ON ; NOTE-ON送信
- MOVF MIDI_CH, W ; チャンネル読み出し
- IORLW MIDI_STA_ON ; 命令作成
- CALL MIDI_SEND_BYTE ; 送信
- RETURN
- MIDI_SEND_STA_NOTE_OFF ; NOTE-OFF送信
- MOVF MIDI_CH, W ; チャンネル読み出し
- IORLW MIDI_STA_OFF ; 命令作成
- CALL PLAY_PUT_BUF ; バッファへ詰め込み
- RETURN
- MIDI_SEND_STA_BEND ; BEND送信
- MOVF MIDI_CH, W ; チャンネル読み出し
- IORLW MIDI_STA_BEND ; 命令作成
- CALL PLAY_PUT_BUF ; バッファへ詰め込み
- RETURN
- MIDI_SEND_STA_CTRL ; CTRL送信
- MOVF MIDI_CH, W ; チャンネル読み出し
- IORLW MIDI_STA_CTRL ; 命令作成
- CALL PLAY_PUT_BUF ; バッファへ詰め込み
- RETURN
- MIDI_SEND_STA_PROG ; PC送信
- MOVF MIDI_CH, W ; チャンネル読み出し
- IORLW MIDI_STA_PROG ; 命令作成
- CALL PLAY_PUT_BUF ; バッファへ詰め込み
- RETURN
- ; * TOSTR *********************************************************************
- TOSTR ; printf関数のようなもの
- MOVWF TOSTR_BUF ; バッファへ退避
- MOVLW 0x30 ; ASCIIコード初期値設定
- MOVWF TOSTR_1 ; 初期値セット
- MOVWF TOSTR_10
- MOVWF TOSTR_100
- L_TOSTR_CHECK_100 ; 100の位チェック
- MOVLW D'100' ; 100ひく
- SUBWF TOSTR_BUF, W ; Wに結果を
- BTFSS STATUS, C ; Cが0で負の数
- GOTO L_TOSTR_CHECK_10 ; 10の位へ
- MOVWF TOSTR_BUF ; 結果をコピー繰り返し
- INCF TOSTR_100, F ; 結果加算
- GOTO L_TOSTR_CHECK_100 ; 繰り返し
- L_TOSTR_CHECK_10 ; 10の位チェック
- MOVLW D'10' ; 10ひく
- SUBWF TOSTR_BUF, W ; Wに結果を
- BTFSS STATUS, C ; Cが0で負の数
- GOTO L_TOSTR_CHECK_1 ; 1の位へ
- MOVWF TOSTR_BUF ; 結果をコピー繰り返し
- INCF TOSTR_10, F ; 結果加算
- GOTO L_TOSTR_CHECK_10 ; 繰り返し
- L_TOSTR_CHECK_1 ; 1の位チェック
- MOVLW D'1' ; 1ひく
- SUBWF TOSTR_BUF, W ; Wに結果を
- BTFSS STATUS, C ; Cが0で負の数
- RETURN ; 終了
- MOVWF TOSTR_BUF ; 結果をコピー繰り返し
- INCF TOSTR_1, F ; 結果加算
- GOTO L_TOSTR_CHECK_1 ; 繰り返し
- ; * LCD ***********************************************************************
- LCD_SEND
- MOVWF LCD_BUF ; バッファにコピー
- BSF LCD_RS ; ピンを設定
- BCF LCD_RW
- CALL LCD_SEND_4BIT ; 4bit送信
- SWAPF LCD_BUF, W ; 下位だけ
- CALL LCD_SEND_4BIT ; 4bit送信
- CALL LCD_BUSY ; ビジーチェック
- RETURN
- LCD_SEND_4BIT ; Wの上位4bitを転送する
- ANDLW 0F0H ; 上位だけ
- MOVWF LCD_BUF4 ; バッファへ
- MOVLW 0FH ; マスク
- ANDWF PORTB, F ; 0000xxxx
- MOVF LCD_BUF4, W ; 上位だけ
- IORWF PORTB, F ; PORTBに設定
- BSF LCD_E ; 送信
- NOP
- BCF LCD_E ; 完了
- RETURN
- LCD_INIT ; LCD初期化
- CALL TIME10M
- CALL TIME10M
- CALL TIME10M
- CALL TIME10M ; 40ms待つ ( 初期化に失敗する場合ここを調整 )
- BCF LCD_RS ; ピンを設定
- BCF LCD_RW ;
- MOVLW 030H ; 8bitモードに設定
- CALL LCD_SEND_4BIT ; 4bit送信
- CALL TIME5M ; 5msまつ
- BCF LCD_RS ; ピンを設定
- BCF LCD_RW ;
- MOVLW 030H ; 8bitモードに設定
- CALL LCD_SEND_4BIT ; 4bit送信
- CALL TIME100 ; 100μsまつ
- BCF LCD_RS ; ピンを設定
- BCF LCD_RW ;
- MOVLW 030H ; 8bitモードに設定
- CALL LCD_SEND_4BIT ; 4bit送信
- CALL TIME100 ; 100μsまつ
- BCF LCD_RS ; ピンを設定
- BCF LCD_RW ;
- MOVLW 020H ; 8bitモードに設定
- CALL LCD_SEND_4BIT ; 4bit送信
- CALL TIME100 ; 100μまつ、ここから4bitモード
- MOVLW 02CH ; ファンクション
- CALL LCD_CMD
- MOVLW 08H ; ディスプレイOFF
- CALL LCD_CMD
- MOVLW 0CH ; ディスプレイON
- CALL LCD_CMD
- MOVLW 06H ; エントリ
- CALL LCD_CMD
- RETURN
- LCD_CMD ; LCDにコマンドを送る ( W )
- MOVWF LCD_BUF ; バッファにコピー
- BCF LCD_RS ; ピンを設定 ( コマンドモード )
- BCF LCD_RW ;
- CALL LCD_SEND_4BIT ; 4bit送信
- SWAPF LCD_BUF, W ; 下位転送
- BCF LCD_RS ; ピンを設定 ( コマンドモード )
- BCF LCD_RW ;
- CALL LCD_SEND_4BIT ; 4bit送信
- CALL LCD_BUSY ; 書き終わるまで待つ
- RETURN
- LCD_BUSY ; LCDがBUSYでなくなるまで帰ってこない
- BCF STATUS, RP1 ; BANK1へ
- BSF STATUS, RP0
- MOVLW 0F0H ; PORTB4-7を入力へ
- IORWF TRISB, F ; 入力設定
- BCF STATUS, RP1 ; BANK0へ
- BCF STATUS, RP0
- BCF LCD_RS ; ピンを設定 ( ビジーチェック )
- BSF LCD_RW ; 読み込みモード
- LCD_BUSY_1
- BSF LCD_E ; 上位を受信
- NOP
- MOVF PORTB, W ; WにPORTBを転送
- BCF LCD_E ; 完了
- ANDLW 0F0H ; 上位 ( 4 : 7 ) だけを残す
- MOVWF LCD_BUF ; バッファに退避
- BSF LCD_E ; 下位を受信
- NOP
- SWAPF PORTB, W ; WにPORTBをSWAPして転送
- BCF LCD_E ; 完了
- ANDLW 0FH ; 下位だけ残す
- IORWF LCD_BUF, F ; 結合!
- BTFSC LCD_BUF, 7 ; BUSYフラグある?
- GOTO LCD_BUSY_1 ; あったら繰り返し
- BCF LCD_RW ; 書き込みモード
- BCF STATUS, RP1 ; BANK1へ
- BSF STATUS, RP0
- MOVLW 0FH ; PORTB4-7を出力へ
- ANDWF TRISB, F ; 出力設定
- BCF STATUS, RP1 ; BANK0へ
- BCF STATUS, RP0
- RETURN
- LCD_CLR ; LCDをクリア
- MOVLW LCD_CMD_CLR ; クリアして
- CALL LCD_CMD
- RETURN
- LCD_CUR ; Wregにカーソルをセット
- IORLW LCD_CMD_CUR ; コマンド作成
- CALL LCD_CMD
- RETURN
- ; * MIDIプレーヤ **************************************************************
- PLAY_PLAY ; 再生開始
- BTFSC F_PLAY_PLAY ; 再生中?
- RETURN ; 再生中なら戻る
- BSF F_PLAY_PLAY ; 再生開始
- BCF F_PLAY_DELTA ; デルタ処理中じゃない
- CALL MMC_INIT ; MMC初期化
- MOVF PLAY_CLS_0, W ; 読み出しセクタ設定
- MOVWF MMC_ARG2 ; 設定
- MOVF PLAY_CLS_1, W ; 読み出しセクタ設定
- MOVWF MMC_ARG1 ; 設定
- CLRF MMC_ARG
- CLRF MMC_ARG3
- CALL FILE_READ_START ; ファイル読み込み開始
- CLRF FIFO_SD_C ; バッファクリア
- MOVLW FIFO_SD_START ; 起点設定
- MOVWF FIFO_SD_R
- MOVWF FIFO_SD_W
- BSF F_FIFO_SD_START ; 起動
- BSF F_FIFO_SD_EN ; イネーブル
- BCF PIR1, SSPIF ; SSPの割り込みフラグ解除
- MOVLW 0FFH ; 即通信開始
- MOVWF SSPBUF ; 開始
- BCF INTCON, GIE ; 割り込み停止
- BSF INTCON, T0IE ; T0割り込み許可
- BSF STATUS, RP0 ; BANK1へ
- MOVLW B'10000101' ; 内部クロック、1:64に設定
- MOVWF OPTION_REG ; 設定
- BSF PIE1, SSPIE ; SSP割り込み許可
- BCF STATUS, RP0 ; BANK0へ
- BSF INTCON, T0IF ; すぐ割り込みが発生するように設定
- BSF INTCON, GIE ; 割り込み許可 ( すぐ発生 )
- RETURN
- PLAY_STOP ; 再生停止
- BTFSS F_PLAY_PLAY ; 再生中?
- RETURN ; 再生中じゃない
- BCF F_PLAY_PLAY ; 再生停止
- BCF INTCON, T0IE ; T0I禁止
- BSF STATUS, RP0 ; BANK1へ
- BCF PIE1, SSPIE ; SSP割り込み停止
- BCF STATUS, RP0 ; BANK0へ
- BCF PIR1, SSPIF ; 一応フラグ解除
- BCF F_FIFO_SD_EN ; ディセーブル
- BTFSS F_FIFO_SD_START ; 開始されてた
- GOTO L_PLAY_STOP_END ; されてなかった
- BSF STATUS, RP0 ; BANK1へ
- BTFSS SSPSTAT, BF ; 受信中のデータがあれば待つ
- GOTO $ - D'1'
- BCF STATUS, RP0 ; BANK0へ
- CALL FILE_READ_FIFO ; 一応受信
- BCF F_FIFO_SD_START ; SD用FIFO停止
- L_PLAY_STOP_END
- CALL FILE_READ_STOP ; 読み込み停止
- RETURN
- PLAY_PUT_BUF ; FIFOバッファに詰め込む ( 割り込み禁止で使う前提 )
- MOVWF PLAY_FIFO ; バッファに一時退避
- MOVLW PLAY_FIFO_SIZE ; FIFOのたまり具合チェック
- SUBWF PLAY_COUNT, W ; 現在の個数から引く
- BTFSC STATUS, Z ; 満タン?
- CALL PLAY_SEND_BUF_BYTE ; 満タンだったので1バイト送信してしまう ( うまくいくか不明 )
- L_PLAY_PUT_BUF_PUT
- BSF STATUS, IRP ; BANK2-3
- MOVF PLAY_FSR, W ; 書込み先
- MOVWF FSR ; FSR設定
- MOVF PLAY_FIFO, W ; データ復帰
- MOVWF INDF ; INDF経由で書き込み
- INCF PLAY_COUNT, F ; 個数加算
- INCF PLAY_FSR, F ; 書込み先加算
- MOVF PLAY_FSR, W ; バッファが飛び出してないかチェック
- SUBLW PLAY_FSR_END ; 終点 + 1を引く
- BTFSS STATUS, Z ; ゼロですか?
- GOTO L_PLAY_PUT_BUF_EXIT ; ゼロではなかったので終了
- MOVLW PLAY_FSR_START ; バッファ起点設定
- MOVWF PLAY_FSR ; 設定
- L_PLAY_PUT_BUF_EXIT
- BTFSC F_PLAY_SEND ; バッファ送信中?
- RETURN ; 送信中だったのでそのまま続行
- BSF F_PLAY_SEND ; 送信フラグを立てる
- BSF STATUS, RP0 ; BANK1へ
- BSF PIE1, TXIE ; TX開始
- BCF STATUS, RP0 ; BANK0へ
- RETURN ; 終了
- PLAY_SEND_BUF_BYTE ; PLAY_SEND_BUFのGIE制御がない, 1バイト送信版
- BSF STATUS, IRP ; BANK2-3
- DECF PLAY_COUNT, F ; 送信した分減らす
- MOVF PLAY_FSR_S, W ; 送信位置を読み込み
- MOVWF FSR ; FSR設定
- INCF PLAY_FSR_S, F ; 送信位置インクリメント
- MOVF PLAY_FSR_S, W ; バッファを飛び出していないかチェック
- SUBLW PLAY_FSR_END ; 終点 + 1を引く
- BTFSS STATUS, Z
- GOTO L_PLAY_SEND_BUF_B_SEND ; 送信部へ
- MOVLW PLAY_FSR_START ; バッファの最初へ
- MOVWF PLAY_FSR_S ; 送信位置再設定
- L_PLAY_SEND_BUF_B_SEND
- BSF STATUS, RP0 ; BANK1に ( MIDI関数をCALLせず直接書いた )
- BTFSS TXSTA, TRMT ; ビジー?
- GOTO $ - D'1' ; ビジー解除を待つ
- BCF STATUS, RP0 ; BANK0へ
- MOVF INDF, W ; 1バイト読み込み
- MOVWF TXREG ; 送信
- MOVF PLAY_COUNT, F ; 個数0になった?
- BTFSS STATUS, Z ; ゼロ?
- RETURN ; ゼロではなかったので終了
- MOVLW PLAY_FSR_START ; FSR初期値再設定
- MOVWF PLAY_FSR ; 初期化
- MOVWF PLAY_FSR_S
- BCF F_PLAY_SEND ; 送信中解除
- BSF STATUS, RP0 ; BANK1へ
- BCF PIE1, TXIE ; TX停止
- BCF STATUS, RP0 ; BANK0へ
- RETURN
- ; * SD用FIFO ( PLAYと連動用 ) *************************************************
- FIFO_SD_GET ; FIFOから1バイト取得
- MOVF FIFO_SD_C, W ; バッファに溜まっているかチェック
- BTFSC STATUS, Z ; ゼロ?
- GOTO L_FIFO_SD_GET_ZERO ; たまってなかった
- DECF FIFO_SD_C, F ; 個数減らす
- BSF STATUS, IRP ; BANK2-3
- MOVF FIFO_SD_R, W ; 読み込み先をFSRへ
- MOVWF FSR ; FSR設定
- MOVF INDF, W ; バッファ取り出し
- MOVWF FIFO_SD_BUF ; 保存
- INCF FIFO_SD_R, F ; 読み込み先加算
- MOVF FIFO_SD_R, W ; オーバーしてるかチェック
- SUBLW FIFO_SD_END ; バッファ終点 + 1か
- BTFSS STATUS, Z ; ゼロ?
- GOTO $ + D'3' ; ゼロじゃなかった
- MOVLW FIFO_SD_START ; 起点設定
- MOVWF FIFO_SD_R
- BTFSC F_FIFO_SD_START ; 開始されてる?
- GOTO L_FIFO_SD_GET_RET ; されてたので終了
- BSF F_FIFO_SD_START ; 起動
- BCF PIR1, SSPIF ; フラグ一応解除
- MOVLW 0FFH ; 通信開始
- MOVWF SSPBUF ; 今度は割り込みを使って通信
- L_FIFO_SD_GET_RET
- MOVF FIFO_SD_BUF, W ; 取り出し
- RETURN
- L_FIFO_SD_GET_ZERO ; 開始してるけどたまってない
- MOVLW FIFO_SD_START ; バッファ位置初期化
- MOVWF FIFO_SD_R
- MOVWF FIFO_SD_W
- BSF STATUS, RP0 ; BANK1へ
- BTFSS SSPSTAT, BF
- GOTO $ - D'1'
- BCF STATUS, RP0 ; BANK0へ
- L_FIFO_SD_FILE_READ_FIFO ; FIFO用に使うREAD ( CALL節約用にコピー )
- BTFSS F_FILE_START ; 読み込み中?
- RETURN ; 違ったので終了
- MOVF SSPBUF, W ; 送受信
- MOVWF FILE_RECV ; 受信バッファへコピー
- INCF FILE_BYTES, F ; 受信カウンタ加算
- BTFSS STATUS, Z ; フロー?
- GOTO L_FIFO_SD_FILE_READ_COMP; 読み込み完了
- BTFSC FILE_BYTES1, 0 ; すでに256読んでいた?
- GOTO L_FIFO_SD_FILE_READ_END ; 読み込み終了
- INCF FILE_BYTES1, F ; 上位バイト加算
- GOTO L_FIFO_SD_FILE_READ_COMP; 読み込み完了
- L_FIFO_SD_FILE_READ_END ; 読み込み終了
- CALL MMC_READ_FOOT ; フッター送信
- INCF MMC_ARG2, F ; 次のセクターへ
- BTFSC STATUS, Z ; フローした?
- INCF MMC_ARG1, F
- INCF MMC_ARG2, F
- BTFSC STATUS, Z ; フローした?
- INCF MMC_ARG1, F
- CLRF FILE_BYTES ; 使う変数を初期化 ( 読み込み再開 )
- CLRF FILE_BYTES1
- CALL MMC_READ_HEAD ; 読み込み開始
- L_FIFO_SD_FILE_READ_COMP ; 読み込み完了
- MOVF FILE_RECV, W ; 読み込みデータをWregに
- MOVWF FIFO_SD_BUF ; バッファへ
- BCF PIR1, SSPIF ; 割り込みフラグ解除
- MOVLW 0FFH ; 通信再開
- MOVWF SSPBUF ; 通信
- MOVF FIFO_SD_BUF, W ; 取り出し
- RETURN
- ; * ファイルアクセス ( 連続改変版 ) *******************************************
- FILE_READ_STOP ; ファイル読み込みを初期化 ( 先頭ファイルの先頭バイトへ )
- BTFSS F_FILE_START ; 読み込み中?
- RETURN ; 違ったので終了
- BCF F_FILE_START ; 読み込みフラグ解除
- MOVLW 0FFH ; 読み込み開始 ( 送信は適当に0FFH )
- CALL SPI_START ; 実行
- INCF FILE_BYTES, F ; リードカウンタ加算
- BTFSS STATUS, Z ; フロー?
- GOTO $ - D'4' ; フローしてなかったので繰り返し
- BTFSC FILE_BYTES1, 0 ; すでに256読み込んでいた ( 00000001 )
- GOTO L_FILE_READ_STOP_1 ; 読み込み完了
- INCF FILE_BYTES1, F ; 上位バイト加算
- GOTO $ - D'8'
- L_FILE_READ_STOP_1 ; 読み込み完了
- CALL MMC_READ_FOOT ; フッター送信
- RETURN
- FILE_READ_SET_START ; ( 改変 ) ファイル読み込み開始セクタ指定
- MOVWF MMC_ARG2 ; 引数設定
- CLRF MMC_ARG
- CLRF MMC_ARG1
- CLRF MMC_ARG3
- RETURN
- FILE_READ_START ; ( 改変 )読み込み開始関数
- BTFSC F_FILE_START ; 読み込み中?
- RETURN ; だったので終了
- BSF F_FILE_START ; 読み込みフラグセット
- CLRF FILE_BYTES ; 使う変数を初期化
- CLRF FILE_BYTES1
- CALL MMC_READ_HEAD ; 読み込み開始
- RETURN
- FILE_READ ; ファイルから1バイト読み込んで、Wregに送る
- BTFSS F_FILE_START ; 読み込み中?
- RETURN ; 違ったので終了
- MOVLW 0FFH ; 受信中には適当な値を送る
- CALL SPI_START ; 送受信
- MOVWF FILE_RECV ; 受信バッファへコピー
- INCF FILE_BYTES, F ; 受信カウンタ加算
- BTFSS STATUS, Z ; フロー?
- GOTO L_FILE_READ_COMP ; 読み込み完了
- BTFSC FILE_BYTES1, 0 ; すでに256読んでいた?
- GOTO L_FILE_READ_END ; 読み込み終了
- INCF FILE_BYTES1, F ; 上位バイト加算
- GOTO L_FILE_READ_COMP ; 読み込み完了
- L_FILE_READ_END ; 読み込み終了
- CALL MMC_READ_FOOT ; フッター送信
- INCF MMC_ARG2, F ; 次のセクターへ
- BTFSC STATUS, Z ; フローした?
- INCF MMC_ARG1, F
- INCF MMC_ARG2, F
- BTFSC STATUS, Z ; フローした?
- INCF MMC_ARG1, F
- CLRF FILE_BYTES ; 使う変数を初期化 ( 読み込み再開 )
- CLRF FILE_BYTES1
- CALL MMC_READ_HEAD ; 読み込み開始
- L_FILE_READ_COMP ; 読み込み完了
- MOVF FILE_RECV, W ; 読み込みデータをWregに
- RETURN
- FILE_READ_FIFO ; FIFO用に使うREAD ( 一部分改変して利用 )
- BTFSS F_FILE_START ; 読み込み中?
- RETURN ; 違ったので終了
- MOVF SSPBUF, W ; 送受信
- MOVWF FILE_RECV ; 受信バッファへコピー
- INCF FILE_BYTES, F ; 受信カウンタ加算
- BTFSS STATUS, Z ; フロー?
- GOTO L_FILE_READ_COMP ; 読み込み完了
- BTFSC FILE_BYTES1, 0 ; すでに256読んでいた?
- GOTO L_FILE_READ_END ; 読み込み終了
- INCF FILE_BYTES1, F ; 上位バイト加算
- GOTO L_FILE_READ_COMP ; 読み込み完了
- ; * SPI通信ルーチン ***********************************************************
- SPI_INIT ; CLK初期化
- MOVLW B'00110000' ; CKP = 1でSPI起動)
- MOVWF SSPCON
- BSF STATUS, RP0 ; BANK1へ
- MOVLW B'10000001' ; SMP = 1, CKE = 0
- MOVWF SSPSTAT
- BCF STATUS, RP0 ; BANK0へ
- RETURN ; 完了
- SPI_START ; 通信を開始する。
- MOVWF SSPBUF ; 送受信開始
- BSF STATUS, RP0 ; BANK1へ
- BTFSS SSPSTAT, BF
- GOTO $ - D'1'
- BCF STATUS, RP0 ; BANK0へ
- MOVF SSPBUF, W ; 受信
- RETURN ; 完了
- ; * MMC制御ルーチン ( CALL軽量版 ) ********************************************
- MMC_INIT ; MMCを初期化
- CLRF MMC_ARG ; 引数を初期化
- CLRF MMC_ARG1
- CLRF MMC_ARG2
- CLRF MMC_ARG3
- CALL SPI_INIT ; SPI初期化
- BSF MMC_CS ; CSをHに ( 開放 )
- BSF SSPCON, SSPM1 ; Fosc/64に
- BCF SSPCON, SSPM0
- MOVLW D'20' ; 80クロック以上送る
- MOVWF MMC_CNT1 ; カウンタへ
- MOVLW 0FFH ; とりあえずFを送る
- CALL SPI_START ; 送信
- DECFSZ MMC_CNT1, F ; 80回送った?
- GOTO $ - 3
- BCF MMC_CS ; CSをLに ( 選択 )
- MOVLW MMC_CMD_0 ; コマンド0送信
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP ; R1をまつ ( 失敗しない前提 )
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- MOVLW MMC_CMD_55 ; SDかチェック
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- MOVLW MMC_CMD_41 ; SDかチェック
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP
- MOVWF MMC_BUF1 ; バッファへ退避
- SUBLW 01H ; SDだったか?
- BTFSC STATUS, Z
- GOTO $ - D'11'
- MOVF MMC_BUF1, W ; Wregへ復帰
- SUBLW 00H
- BTFSC STATUS, Z
- GOTO MMCICMPLT ; SDでしかも初期化完了
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- MOVLW MMC_CMD_1 ; コマンド1送信
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP ; R1を待つ
- SUBLW 00H ; 0か調べる
- BTFSS STATUS, Z
- GOTO $ - D'7' ; 0になってないので再送信
- ;BCF SSPCON, SSPM1 ; Fosc/16に ( 今のところこれ以上でない )
- ;BSF SSPCON, SSPM0 ; DEBUG
- MMCICMPLT
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- MOVLW D'2' ; ブロックを512に指定
- MOVWF MMC_ARG2 ; 引数に設定
- MOVLW MMC_CMD_16
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- BSF MMC_CS ; 開放
- RETURN ; 戻る
- MMC_DUMY ; ダミー送信
- MOVLW 0FFH
- CALL SPI_START
- RETURN
- MMC_WAIT_RESP ; レスポンス待ち関数
- MOVLW 0FFH ; 0FFHを送る
- CALL SPI_START ; 送受信
- MOVWF MMC_BUF2 ; 退避
- SUBLW 0FFH ; 0FFHか調べる
- BTFSC STATUS, Z ; ゼロになった?
- GOTO $ - D'5' ; もう一度待つ
- MOVF MMC_BUF2, W ; 受信できたものをWregに
- RETURN
- MMC_WRITE_HEAD ; 書き込み用ヘッダ
- BCF MMC_CS ; 選択
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- MOVLW MMC_CMD_24 ; シングルブロックライト
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP ; レスポンス待ち
- MOVLW 0FFH ; 1バイト空ける
- CALL SPI_START
- MOVLW B'11111110' ; データトークン開始
- CALL SPI_START
- RETURN ; 戻る
- MMC_WRITE_FOOT ; 書き込み用フッタ
- MOVLW 00H ; 適当にCRC送信
- CALL SPI_START
- MOVLW 00H
- CALL SPI_START
- CALL MMC_WAIT_RESP ; レスポンス待ち
- MOVLW 0FFH ; busy解除をまつ
- CALL SPI_START
- SUBLW 0FFH ; FFになった?
- BTFSS STATUS, Z
- GOTO $ - D'4'
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- BSF MMC_CS ; 開放
- RETURN
- MMC_READ_HEAD ; シングルリード時のヘッダ
- BCF MMC_CS ; 選択
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- MOVLW MMC_CMD_17 ; シングルブロックリード
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP ; レスポンス待ち
- CALL MMC_WAIT_RESP ; トークン待ち(なんでもいい無視)
- RETURN
- MMC_READ_FOOT ; シングルリード時のフッタ
- MOVLW 0FFH ; CRC受信 ( 2Bytes )
- CALL SPI_START
- MOVLW 0FFH
- CALL SPI_START
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- BSF MMC_CS ; 開放
- RETURN
- MMC_READ_STOP ; 読み込み強制停止
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- MOVLW MMC_CMD_12 ; 読み込み停止
- CALL MMC_SEND_COMMAND
- CALL MMC_WAIT_RESP ; レスポンス待ち
- MOVLW 0FFH ; busy解除をまつ
- CALL SPI_START
- SUBLW 0FFH ; FFになった?
- BTFSS STATUS, Z
- GOTO $ - D'4'
- MOVLW 0FFH ; 1回ダミーを送る
- CALL SPI_START
- RETURN
- MMC_SEND_COMMAND ; MMCにコマンド送信
- IORLW B'01000000' ; コマンド作成
- CALL SPI_START ; 送信
- MOVF MMC_ARG, W ; 引数コピー
- CALL SPI_START ; 送信
- MOVF MMC_ARG1, W
- CALL SPI_START ; 送信
- MOVF MMC_ARG2, W
- CALL SPI_START ; 送信
- MOVF MMC_ARG3, W
- CALL SPI_START ; 送信
- MOVLW MMC_CRC_CMD0 ; CRC送信
- CALL SPI_START ; 送信
- RETURN ; 戻る
- ; * ディレイ集 ****************************************************************
- TIME1 ; 1μ秒 : 5ステップ
- NOP ; 2 + 1
- RETURN ; 2
- TIME10 ; 10μ秒 : 50ステップ
- MOVLW D'15'
- MOVWF CNT1
- DECFSZ CNT1, F
- GOTO $ - 1
- RETURN
- TIME50 ; 50μ秒 : 250ステップ
- NOP ; +1
- NOP ; +1
- MOVLW D'81'
- MOVWF CNT1
- DECFSZ CNT1, F
- GOTO $ - 1
- RETURN
- TIME100 ; 100μ秒 : 500ステップ
- MOVLW D'165'
- MOVWF CNT1
- DECFSZ CNT1, F
- GOTO $ - 1
- RETURN
- TIME1M ; 1m秒 : 5000ステップ ( 補正項なしで5035 )
- NOP ; 補正項開始
- NOP
- NOP
- MOVLW D'154'
- MOVWF CNT2
- DECFSZ CNT2, F
- GOTO $ - 1
- NOP
- NOP ; 補正項終わり
- MOVLW D'9'
- MOVWF CNT3
- T_LP1 CALL TIME100
- DECFSZ CNT3, F
- GOTO T_LP1
- RETURN
- TIME5M ; 5m秒 ( 約 )
- CALL TIME1M
- CALL TIME1M
- CALL TIME1M
- CALL TIME1M
- CALL TIME1M
- RETURN
- TIME10M ; 10m秒 ( 約 )
- CALL TIME5M
- CALL TIME5M
- RETURN
- TIME05S ; 0.5秒 ( 約 )
- MOVLW D'50'
- MOVWF CNT4
- T_LP2 CALL TIME10M
- DECFSZ CNT4, F
- GOTO T_LP2
- RETURN
- ; * FAT12ルーチン *************************************************************
- ORG 0x700 ; テーブル用に書き込み場所を変更 ( PAGE0の最後の256バイト )
- T_GET_BOOTSECTOR ; ブートセクタの最初の部分 ( BANK0で実行前提 )
- MOVLW 07H ; テーブルは0700H以降にあり
- MOVWF PCLATH ; PCLATH設定
- MOVF PG_POINT1, W ; 今の位置をWregへ
- ADDWF PCL ,F ; PC書き換え
- TABLE1 RETLW 0EBH ; テーブルルックアップ
- RETLW 04EH
- RETLW 090H
- RETLW 'N'
- RETLW 'O'
- RETLW ' '
- RETLW 'N'
- RETLW 'A'
- RETLW 'M'
- RETLW 'E'
- RETLW ' '
- RETLW 00H
- RETLW 02H
- RETLW 01H
- RETLW 01H
- RETLW 00H
- RETLW 02H
- RETLW 0E0H
- RETLW 00H
- RETLW B'01000000'
- RETLW B'00001011'
- RETLW 0F0H
- RETLW 09H
- RETLW 00H
- RETLW D'18'
- RETLW 00H
- RETLW 02H
- RETLW 00H
- RETLW 00H
- RETLW 00H
- RETLW 00H
- RETLW 00H
- RETLW B'01000000'
- RETLW B'00001011'
- RETLW 00H
- RETLW 00H
- RETLW 00H
- RETLW 00H
- RETLW 029H
- RETLW 0FFH
- RETLW 0FFH
- RETLW 0FFH
- RETLW 0FFH
- RETLW 'P'
- RETLW 'I'
- RETLW 'C'
- RETLW '-'
- RETLW 'F'
- RETLW 'A'
- RETLW 'T'
- RETLW ' '
- RETLW ' '
- RETLW ' '
- RETLW ' '
- RETLW 'F'
- RETLW 'A'
- RETLW 'T'
- RETLW '1'
- RETLW '2'
- RETLW ' '
- RETLW ' '
- RETLW ' '
- ; *****************************************************************************
- END ; おわり
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement