Advertisement
Guest User

Untitled

a guest
Jun 26th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 76.92 KB | None | 0 0
  1. ; *****************************************************************************
  2. ;
  3. ; 16F877A RK-100用プログラム 20MHz
  4. ; ver 2.60
  5. ;
  6. ; ハードSPI版
  7. ; FAT12版
  8. ; FIFO版
  9. ;
  10. ; (c) 2011 G group, futr
  11. ;
  12. ; *****************************************************************************
  13. ;
  14. ; デバッグキーワード : DEBUG
  15. ;
  16. ; *****************************************************************************
  17. ;
  18. ; デルタゼロで97バイト以上データが重なるファイルでは若干処理が止まるかもしれません
  19. ; 常識的なデータなら多分大丈夫です
  20. ; FAT12形式に擬似対応していますが、もしファイルが断片化するとデータが再生できなくなります。
  21. ; フォーマットし直してデータを入れなおしてください
  22. ;
  23. ; FIFOの名前がPLAY〜になっているのはMIDIプレーヤー専用の名残で
  24. ; 実際には通常のキーボード制御でも使っています
  25. ;
  26. ; 1234567890123456
  27. ; +----------------+
  28. ; |VO000 B000 C00 M| : ボリューム ピッチ チャンネル オクターブ
  29. ; |VE000 P000 STOP| : ベロシティ プログラム 再生
  30. ; +----------------+
  31. ;
  32. ; *****************************************************************************
  33. ;
  34. ; MIDI : 反転なしの31250bps
  35. ;
  36. ; 送信しか使わなくてもRCSTAの7bit目が必要
  37. ; TRISEの3bitからは特別な意味があるので注意
  38. ;
  39. ; SMP = 1, CKE = 0, CKP = 1
  40. ; 本当はこの組み合わせでは動かないはずだけど、時間がないので保留
  41. ;
  42. ; BENDは0,64が中心 127,127が最大 0,0が最小らしい
  43. ;
  44. ; PORTB : 液晶用
  45. ; PORTD : セレクタ用
  46. ; PORTC : 通信用
  47. ;
  48. ; A0Hから : キーONテーブル
  49. ; 110Hから : MIDI用FIFOバッファ
  50. ;
  51. ; 同時演奏でおかしくなるので送信のランニングステータス廃止
  52. ; 音源自作用にノートオフに変更
  53. ;
  54. ; *****************************************************************************
  55.  
  56. ; コンフィグ
  57. __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC
  58.  
  59. LIST p=16F877A, b=4
  60. INCLUDE "P16F877A.INC"
  61. ERRORLEVEL -302
  62.  
  63. ; * IO - MAP ******************************************************************
  64.  
  65. #DEFINE AN_JOY0 PORTA, 0 ; アナログ入力、ジョイスティック
  66. #DEFINE AN_JOY1 PORTA, 1 ; アナログ入力、ジョイスティック
  67. #DEFINE AN_VOL PORTA, 3 ; アナログ入力、ボリューム
  68.  
  69. #DEFINE SW_PG_UP PORTE, 0 ; PC UP
  70. #DEFINE SW_PG_DOWN PORTE, 1 ; PC DOWN
  71. #DEFINE SW_HOLD PORTC, 0 ; ホールドキー
  72. #DEFINE SW_MODE PORTC, 1 ; MODE切り替えスイッチ
  73. #DEFINE SW_OCT_L PORTA, 4 ; オクターブL
  74. #DEFINE SW_OCT_H PORTA, 5 ; オクターブH
  75.  
  76. #DEFINE LCD_E PORTB, 3 ; 液晶用コントロール端子
  77. #DEFINE LCD_RS PORTB, 2 ; 液晶用
  78. #DEFINE LCD_RW PORTB, 1 ; 液晶用
  79.  
  80. #DEFINE MMC_CS PORTC, 2 ; チップセレクト
  81. #DEFINE SPI_DI PORTC, 4 ; 入力ピン
  82. #DEFINE SPI_CLK PORTC, 3 ; クロック
  83. #DEFINE SPI_DO PORTC, 5 ; 出力ピン
  84.  
  85. #DEFINE MIDI_OUT PORTC, 6 ; MIDI出力
  86.  
  87. #DEFINE KEY_IN PORTD, 6 ; キー状態入力端子
  88.  
  89. ; *****************************************************************************
  90.  
  91. #DEFINE LCD_CMD_CLR 01H ; 液晶コマンドクリア
  92. #DEFINE LCD_CMD_CUR B'10000000' ; カーソル指定コマンド
  93. #DEFINE LCD_CUR_1L 00H ; 1行目
  94. #DEFINE LCD_CUR_2L 040H ; 2行目
  95.  
  96. #DEFINE MIDI_BEND_TH D'15' ; BENDのしきい値
  97. #DEFINE MIDI_RATE D'39' ; MIDI用SPBRG ( BRGH = 1 )
  98. #DEFINE MIDI_INI_VOL D'100' ; VOL初期値
  99. #DEFINE MIDI_INI_NOTE D'36' ; NOTE最小値
  100. #DEFINE MIDI_C_BEND_C D'64' ; BENDの中心値 ( MIDIメッセージにおける )
  101. #DEFINE MIDI_C_LMH D'12' ; LMH初期値 ( 内部用、加算値 )
  102.  
  103. #DEFINE MIDI_STA_ON B'10010000' ; ノートオン OR合成用
  104. #DEFINE MIDI_STA_OFF B'10000000' ; ノートオフ
  105. #DEFINE MIDI_STA_BEND 0xE0 ; ピッチベンド
  106. #DEFINE MIDI_STA_CTRL 0xB0 ; コントロールチェンジ ( 音量とかホールドとか )
  107. #DEFINE MIDI_STA_PROG 0xC0 ; プログラムチェンジ
  108.  
  109. #DEFINE MIDI_CTRL_VOL_M 0x07 ; 音量MSB
  110. #DEFINE MIDI_CTRL_VOL_L 0x27 ; 音量LSB
  111. #DEFINE MIDI_CTRL_HOLD 0x40 ; ホールド用
  112.  
  113. #DEFINE MODE_CANCEL 0x00 ; キャンセル画面
  114. #DEFINE MODE_PLAY 0x01 ; 再生
  115. #DEFINE MODE_STOP 0x02 ; 停止
  116. #DEFINE MODE_FORMAT 0x03 ; フォーマット
  117. #DEFINE MODE_CH 0x04 ; チャンネル変更
  118. #DEFINE MODE_MAX 0x04 ; モード最大値
  119.  
  120. #DEFINE SPI_MODE0 D'0' ; MODE0 ( 定数だけど、なんとなくDEFINE )
  121. #DEFINE SPI_MODE1 D'1' ; MODE1
  122. #DEFINE SPI_MODE2 D'2' ; MODE2
  123. #DEFINE SPI_MODE3 D'3' ; MODE3
  124.  
  125. #DEFINE SPI_SPEED_200K D'5' ; 200Kbps用定数
  126. #DEFINE SPI_SPEED_MAX D'1' ; 最大速度
  127.  
  128. #DEFINE MMC_CRC_CMD0 B'10010101' ; CMD0用CRC固定値
  129.  
  130. #DEFINE MMC_CMD_0 D'0' ; ソフトウェアリセット
  131. #DEFINE MMC_CMD_1 D'1' ; 初期化開始
  132. #DEFINE MMC_CMD_12 D'12' ; 読み込み強制停止
  133. #DEFINE MMC_CMD_16 D'16' ; ブロック長指定
  134. #DEFINE MMC_CMD_17 D'17' ; シングルブロックリード
  135. #DEFINE MMC_CMD_24 D'24' ; シングルブロックライト
  136. #DEFINE MMC_CMD_41 D'41' ; SD専用初期化
  137. #DEFINE MMC_CMD_55 D'55' ; アプリケーション特化コマンド
  138.  
  139. #DEFINE PLAY_FSR_START 0x10 ; バッファ起点
  140. #DEFINE PLAY_FSR_END 0x70 ; バッファ終点 + 1
  141. #DEFINE PLAY_FIFO_SIZE D'96' ; FIFOの大きさ
  142.  
  143. #DEFINE FIFO_SD_START 0x90 ; バッファ起点
  144. #DEFINE FIFO_SD_END 0xF0 ; バッファ終点 + 1
  145. #DEFINE FIFO_SD_SIZE D'96' ; FIFOの大きさ
  146.  
  147. #DEFINE FILE_FIRST_SECT 0x42 ; ファイル開始セクタ
  148.  
  149. #DEFINE F_FILE_START FILE_FLAG, 0 ; ファイル読み込み中フラグ
  150.  
  151. #DEFINE F_FIFO_SD_START FIFO_SD_FLG, 0 ; 開始している?
  152. #DEFINE F_FIFO_SD_EN FIFO_SD_FLG, 1 ; イネーブル?
  153.  
  154. #DEFINE F_KEY_PC KEY_FLAGS, 0 ; PC変更フラグ 1 = 変更
  155. #DEFINE F_KEY_LCD KEY_FLAGS, 1 ; 液晶書き換え要求
  156. #DEFINE F_KEY_C_VOL KEY_FLAGS, 2 ; 変更ありか
  157. #DEFINE F_KEY_C_BEND KEY_FLAGS, 3
  158. #DEFINE F_KEY_C_VELO KEY_FLAGS, 4
  159. #DEFINE F_KEY_C_HOLD KEY_FLAGS, 5
  160. #DEFINE F_KEY_C_LMH KEY_FLAGS, 6
  161. #DEFINE F_KEY_C_PROG KEY_FLAGS, 7
  162.  
  163. #DEFINE F_PLAY_PLAY PLAY_FLAGS, 0 ; 再生中フラグ
  164. #DEFINE F_PLAY_DELTA PLAY_FLAGS, 1 ; DELTA処理中
  165. #DEFINE F_PLAY_SEND PLAY_FLAGS, 2 ; バッファ送信
  166.  
  167. #DEFINE F_MODE_PUSH MODE_FLAGS, 0 ; ボタン押されてた?
  168.  
  169. ; * MEM-MAP *******************************************************************
  170. ;
  171. MEM EQU 0x20 ; メモリ開始番地
  172.  
  173. CNT1 EQU MEM + D'0' ; ディレイ用
  174. CNT2 EQU MEM + D'1'
  175. CNT3 EQU MEM + D'2'
  176. CNT4 EQU MEM + D'3'
  177.  
  178. MEM_LCD EQU MEM + D'4' ; 液晶
  179. LCD_BUF EQU MEM_LCD + D'0' ; LCDデータバッファ
  180. LCD_BUF4 EQU MEM_LCD + D'1' ; 4bit転送用バッファ
  181.  
  182. MEM_TEMP EQU MEM_LCD + D'2' ; 割り込みテンポラリ用
  183. TMP_W EQU 0x70 ; Wregに関しては共通アクセスできる0x70に
  184. TMP_STATUS EQU MEM_TEMP + D'0'
  185. TMP_PCLATH EQU MEM_TEMP + D'1'
  186. TMP_FSR EQU MEM_TEMP + D'2'
  187.  
  188. MEM_MODE EQU MEM_TEMP + D'3'
  189. MODE_POS EQU MEM_MODE + D'0' ; 現在のモード画面
  190. MODE_FLAGS EQU MEM_MODE + D'1' ; フラグ
  191. MODE_BUF EQU MEM_MODE + D'2' ; バッファ
  192.  
  193. MEM_KEY EQU MEM_MODE + D'3' ; キーセレクト用
  194. KEY_POS EQU MEM_KEY + D'0' ; 現在のサーチ位置
  195. KEY_FLAGS EQU MEM_KEY + D'1' ; フラグ
  196. KEY_FLAGS2 EQU MEM_KEY + D'2' ; フラグ2
  197. KEY_BUF EQU MEM_KEY + D'3' ; キーバッファ
  198. KEY_TBL_BUF EQU MEM_KEY + D'4' ; テーブル用バッファ
  199.  
  200. MEM_MIDI EQU MEM_KEY + D'5' ; MIDI制御用
  201. MIDI_PROG EQU MEM_MIDI + D'0' ; プログラムナンバー
  202. MIDI_B_PROG EQU MEM_MIDI + D'1'
  203. MIDI_CH EQU MEM_MIDI + D'2' ; MIDI-CHANNEL
  204. MIDI_VOL EQU MEM_MIDI + D'3' ; MIDI-VOLUME
  205. MIDI_B_VOL EQU MEM_MIDI + D'4' ; 前回のMIDI-VOL
  206. MIDI_BEND EQU MEM_MIDI + D'5' ; MIDI-BEND
  207. MIDI_B_BEND EQU MEM_MIDI + D'6' ; 前回のBEND
  208. MIDI_BEND_C EQU MEM_MIDI + D'7' ; BEND中心値
  209. MIDI_VELO EQU MEM_MIDI + D'8' ; MIDI-ベロシティ
  210. MIDI_B_VELO EQU MEM_MIDI + D'9' ; 前回の
  211. MIDI_LMH EQU MEM_MIDI + D'19' ; MIDI-オクターブ
  212. MIDI_B_LMH EQU MEM_MIDI + D'11'
  213. MIDI_TX_BUF EQU MEM_MIDI + D'12' ; MIDI送信バッファ
  214. MIDI_HOLD EQU MEM_MIDI + D'13' ; ホールド
  215. MIDI_B_HOLD EQU MEM_MIDI + D'14' ; 前回のホールド
  216.  
  217. MEM_TOSTR EQU MEM_MIDI + D'15' ; TOSTR用メモリ
  218. TOSTR_1 EQU MEM_TOSTR + D'0' ; 結果格納用1の位 ( 最大3ケタ )
  219. TOSTR_10 EQU MEM_TOSTR + D'1' ; 10
  220. TOSTR_100 EQU MEM_TOSTR + D'2' ; 100
  221. TOSTR_BUF EQU MEM_TOSTR + D'3' ; バッファ
  222.  
  223. MEM_SPI EQU MEM_TOSTR + D'4' ; SPI通信プログラム用
  224. SPI_DATA EQU MEM_SPI + D'0' ; 通信データ受け渡し用
  225. SPI_CNT EQU MEM_SPI + D'1' ; 通信するときに使うカウンタ
  226. SPI_STATUS EQU MEM_SPI + D'2' ; MODEなどを保存
  227. SPI_SPEED EQU MEM_SPI + D'3' ; クロックスピード
  228. SPI_CNT2 EQU MEM_SPI + D'4' ; クロック用カウンタ
  229.  
  230. MEM_MMC EQU MEM_SPI + D'5' ; MMC(SD)用
  231. MMC_ARG EQU MEM_MMC + D'0' ; コマンド用引数(全4バイト)
  232. MMC_ARG1 EQU MEM_MMC + D'1'
  233. MMC_ARG2 EQU MEM_MMC + D'2'
  234. MMC_ARG3 EQU MEM_MMC + D'3'
  235. MMC_BUF1 EQU MEM_MMC + D'4' ; バッファー1
  236. MMC_BUF2 EQU MEM_MMC + D'5' ; レスポンス待ちバッファ
  237. MMC_CNT1 EQU MEM_MMC + D'6' ; MMC用カウンタ1
  238.  
  239. MEM_FILE EQU MEM_MMC + D'7' ; ファイルアクセス用
  240. FILE_BYTES EQU MEM_FILE + D'0' ; 読み込み数カウンタ
  241. FILE_BYTES1 EQU MEM_FILE + D'1' ; 読み込み数カウンタ
  242. FILE_FLAG EQU MEM_FILE + D'2' ; ファイルアクセス用フラグ
  243. FILE_RECV EQU MEM_FILE + D'3' ; 受信データ
  244. FILE_SECT EQU MEM_FILE + D'4' ; 読み込み希望セクタ
  245.  
  246. MEM_PLAYER EQU MEM_FILE + D'5' ; MIDIプレーヤー用メモリ
  247. PLAY_FLAGS EQU MEM_PLAYER + D'0' ; フラグ用
  248. PLAY_BUF EQU MEM_PLAYER + D'1' ; バッファ
  249. PLAY_TEMPO EQU MEM_PLAYER + D'2' ; テンポ保存用
  250. PLAY_D_0 EQU MEM_PLAYER + D'3' ; デルタ最下位
  251. PLAY_D_1 EQU MEM_PLAYER + D'4'
  252. PLAY_D_2 EQU MEM_PLAYER + D'5'
  253. PLAY_D_3 EQU MEM_PLAYER + D'6' ; デルタ最上位
  254. PLAY_DELTAS EQU MEM_PLAYER + D'7' ; デルタバイト数
  255. PLAY_DATAS EQU MEM_PLAYER + D'8' ; データ部の長さ
  256. PLAY_D_BUF EQU MEM_PLAYER + D'9' ; デルタ用バッファ
  257. PLAY_FSR EQU MEM_PLAYER + D'10' ; 送信バッファ用ポインタ
  258. PLAY_COUNT EQU MEM_PLAYER + D'11' ; 送信バッファたまり具合
  259. PLAY_FSR_S EQU MEM_PLAYER + D'12' ; 送信バッファの現在送信中の位置
  260. PLAY_FIFO EQU MEM_PLAYER + D'13' ; FIFO用汎用バッファ
  261. PLAY_CLS_0 EQU MEM_PLAYER + D'14' ; 開始クラスタ
  262. PLAY_CLS_1 EQU MEM_PLAYER + D'15'
  263.  
  264. MEM_PG EQU MEM_PLAYER + D'16' ; 汎用カウンタ用
  265. PG_CNT1 EQU MEM_PG + D'0' ; 汎用カウンタ
  266. PG_CNT2 EQU MEM_PG + D'1' ; 汎用カウンタ
  267. PG_POINT1 EQU MEM_PG + D'2' ; 汎用ポインタ
  268. PG_BUF1 EQU MEM_PG + D'3'
  269.  
  270. MEM_FIFO_SD EQU MEM_PG + D'4' ; SD用FIFO
  271. FIFO_SD_R EQU MEM_FIFO_SD + D'0' ; 読み込みFSR
  272. FIFO_SD_W EQU MEM_FIFO_SD + D'1' ; 書き込みFSR
  273. FIFO_SD_C EQU MEM_FIFO_SD + D'2' ; FIFOたまり具合
  274. FIFO_SD_BUF EQU MEM_FIFO_SD + D'3' ; FIFO用バッファ
  275. FIFO_SD_FLG EQU MEM_FIFO_SD + D'4' ; フラグ
  276.  
  277. MEM_DEBUG EQU MEM_FIFO_SD + D'5' ; デバッグ用
  278. DBG_FIFO_OF EQU MEM_DEBUG + D'0' ; FIFOフロー
  279.  
  280. ; *****************************************************************************
  281.  
  282. ORG 00H ; 開始
  283. GOTO START
  284. ORG 004H ; 割り込みベクタ
  285. GOTO INT
  286.  
  287. START ; システム初期化開始
  288. BSF STATUS, RP0 ; BANK1へ
  289. MOVLW B'11111111' ; PORTAすべて入力
  290. MOVWF TRISA
  291. MOVLW B'00000001' ; PORTBはINTだけ入力 ( 残りは液晶用 )
  292. MOVWF TRISB
  293. MOVLW B'10010011' ; PORTCはSDとMIDI用
  294. MOVWF TRISC
  295. MOVLW B'11000000' ; PORTDはセレクタ用 ( RD6が入力 )
  296. MOVWF TRISD
  297. MOVLW B'00000111' ; PORTEはとりあえず入力に
  298. MOVWF TRISE
  299. BCF STATUS, RP0 ; BANK0へ
  300.  
  301. ; ADコンバーター設定
  302.  
  303. BSF STATUS, RP0 ; BANK1へ
  304. MOVLW B'01000100' ; ADCON1の値設定 ( 左詰め, Fosc/62, AN0-1-3 )
  305. MOVWF ADCON1 ; ADCON1設定
  306. BCF STATUS, RP0 ; BANK0へ
  307. MOVLW B'10000000' ; ADCON0の値設定 ( Fosc/64 )
  308. MOVWF ADCON0 ; ADCON0設定
  309.  
  310. ; MIDIOUT ( USART ) 設定
  311.  
  312. BSF RCSTA, SPEN ; シリアル通信を使用する
  313. BSF STATUS, RP0 ; BANK1へ
  314. MOVLW B'00100100' ; TXSTAの値設定 ( 非同期, 高速, ノンパリティ )
  315. MOVWF TXSTA ; TXSTA設定
  316. MOVLW MIDI_RATE ; 転送速度設定 ( MIDIベース )
  317. MOVWF SPBRG ; SPBRG設定 ( 31250bps )
  318. BCF STATUS, RP0 ; BANK0へ
  319.  
  320. ; 割り込み等
  321.  
  322. BSF INTCON, PEIE ; 周辺割り込み許可
  323. BSF INTCON, GIE ; 割り込み許可
  324.  
  325. ; 初期値設定
  326.  
  327. CLRF KEY_POS ; キーポジション初期化
  328. CLRF KEY_FLAGS ; フラグクリア
  329. CLRF PLAY_FLAGS
  330. CLRF FILE_FLAG
  331. CLRF FIFO_SD_FLG
  332. CLRF FIFO_SD_C
  333. CLRF DBG_FIFO_OF ; DEBUG
  334.  
  335. MOVLW PLAY_FSR_START ; バッファ起点設定
  336. MOVWF PLAY_FSR
  337. MOVWF PLAY_FSR_S
  338. CLRF PLAY_COUNT ; バッファカウンタ初期化
  339.  
  340. ; ポート初期化
  341.  
  342. CLRF PORTD ; PORTD初期化
  343. BSF MMC_CS ; MMCを開放する
  344.  
  345. ; 液晶初期化開始
  346.  
  347. CALL LCD_INIT ; LCD初期化
  348. CALL LCD_CLR ; 画面クリア
  349.  
  350. MOVLW 'R' ; ようこそ画面
  351. CALL LCD_SEND
  352. MOVLW 'K'
  353. CALL LCD_SEND
  354. MOVLW '-'
  355. CALL LCD_SEND
  356. MOVLW '1'
  357. CALL LCD_SEND
  358. MOVLW '0'
  359. CALL LCD_SEND
  360. MOVLW '0'
  361. CALL LCD_SEND
  362.  
  363. MOVLW LCD_CUR_2L ; 2行目へ
  364. CALL LCD_CUR ; 位置設定
  365.  
  366. MOVLW D'16' ; 16回繰り返す
  367. MOVWF PG_CNT1 ; 汎用カウンタにセット
  368. L_MAIN_INIT_LCD_L0
  369. MOVLW 0FFH ; ■
  370. CALL LCD_SEND
  371. CALL TIME10M
  372. CALL TIME10M
  373. CALL TIME10M
  374. CALL TIME10M
  375. CALL TIME10M
  376. DECFSZ PG_CNT1, F
  377. GOTO L_MAIN_INIT_LCD_L0
  378.  
  379. ; MIDIパラメータ初期化開始
  380.  
  381. CLRF MIDI_CH ; 0チャンネル
  382. CLRF MIDI_PROG ; 0プログラム
  383.  
  384. CALL KEY_READ_AD ; AD変換開始
  385. RRF MIDI_VOL, F ; さらに1ビット捨てる
  386. BCF MIDI_VOL, 7
  387. RRF MIDI_BEND, F
  388. BCF MIDI_BEND, 7
  389. RRF MIDI_VELO, F
  390. BCF MIDI_VELO, 7
  391.  
  392. MOVF MIDI_BEND, W ; BEND中心値取得
  393. MOVWF MIDI_BEND_C ; 中心値保存
  394.  
  395. CALL MIDI_SEND_STA_PROG ; プログラムチェンジ送信
  396. MOVLW 0x00 ; 0番
  397. CALL MIDI_SEND_BYTE ; 0番送信
  398.  
  399. GOTO MAIN ; 初期化完了、起動!
  400.  
  401. ; * MAIN **********************************************************************
  402.  
  403. MAIN ; メインループ
  404.  
  405. ; AD変換で値取得 ( CALLは使わない )
  406.  
  407. MOVLW B'10000000' ; ADCON0初期値
  408. IORLW B'00000001' ; AN0変換開始
  409. MOVWF ADCON0 ; チャンネル0選択、使用開始
  410. CALL TIME50 ; 50マイクロまつ
  411. BSF ADCON0, GO ; 変換開始
  412. BTFSC ADCON0, GO ; 変換終了した?
  413. GOTO $ - D'1' ; まだ
  414. MOVF ADRESH, W ; 結果取り出し
  415. MOVWF MIDI_VELO ; ベロシティへ
  416.  
  417. MOVLW B'10000000' ; ADCON0初期値
  418. IORLW B'00001001' ; AN1変換開始
  419. MOVWF ADCON0 ; チャンネル1選択、使用開始
  420. CALL TIME50 ; 50マイクロまつ
  421. BSF ADCON0, GO ; 変換開始
  422. BTFSC ADCON0, GO ; 変換終了した?
  423. GOTO $ - D'1' ; まだ
  424. MOVF ADRESH, W ; 結果取り出し
  425. MOVWF MIDI_BEND ; BENDへ
  426.  
  427. MOVLW B'10000000' ; ADCON0初期値
  428. IORLW B'00011001' ; AN3変換開始
  429. MOVWF ADCON0 ; チャンネル3選択、使用開始
  430. CALL TIME50 ; 50マイクロまつ
  431. BSF ADCON0, GO ; 変換開始
  432. BTFSC ADCON0, GO ; 変換終了した?
  433. GOTO $ - D'1' ; まだ
  434. MOVF ADRESH, W ; 結果取り出し
  435. MOVWF MIDI_VOL ; ボリュームへ
  436.  
  437. ; 取得値を変換
  438.  
  439. RRF MIDI_VOL, F ; さらに1ビット捨てる
  440. BCF MIDI_VOL, 7
  441. RRF MIDI_BEND, F
  442. BCF MIDI_BEND, 7
  443. RRF MIDI_VELO, F
  444. BCF MIDI_VELO, 7
  445.  
  446. ; BEND作成
  447.  
  448. L_BEND_CHECK_OVER
  449. MOVLW MIDI_BEND_TH ; BENDしきい値と比較
  450. ADDWF MIDI_BEND_C, W ; 中心 ( 実測 ) に加算
  451. SUBWF MIDI_BEND, W ; THより大きいかチェック
  452. BTFSC STATUS, C ; 正だったら大きい ( C = 1 )
  453. GOTO L_BEND_MAKE ; THを超えていたのでBEND作成
  454.  
  455. L_BEND_CHECK_UNDER
  456. MOVLW MIDI_BEND_TH ; BENDしきい値と比較
  457. SUBWF MIDI_BEND_C, W ; 中心 ( 実測 ) から減算
  458. SUBWF MIDI_BEND, W ; THより小さいかチェック
  459. BTFSS STATUS, C ; 負だったら小さい ( C = 0 )
  460. GOTO L_BEND_MAKE ; THを超えていたのでBEND作成
  461.  
  462. L_BEND_CHECK_CENTER ; 中心誤差の範囲でした
  463. MOVLW D'0' ; 中心
  464.  
  465. L_BEND_MAKE
  466. ADDLW MIDI_C_BEND_C ; 中心加算
  467. MOVWF MIDI_BEND ; BEND完成
  468.  
  469. ; LMHチェック
  470.  
  471. MOVLW 0x00 ; クリア
  472. BTFSC SW_OCT_L ; -?
  473. ADDLW MIDI_C_LMH ; 12加算
  474. BTFSS SW_OCT_H ; +?
  475. ADDLW MIDI_C_LMH ; 12加算
  476. MOVWF MIDI_LMH ; LMH設定
  477.  
  478. ; HOLDチェック
  479.  
  480. BTFSC SW_HOLD ; ホールドされてる?
  481. MOVLW 0 ; 離されてればホールドなし
  482. BTFSS SW_HOLD
  483. MOVLW D'127' ; 押されてればホールド
  484. MOVWF MIDI_HOLD ; 保存
  485.  
  486. ; ボタンチェック
  487.  
  488. L_CHECK_BUTTON
  489. BTFSS F_KEY_PC ; 前回PCあった?
  490. GOTO L_CHECK_PC_UP ; なかった
  491. BCF F_KEY_PC
  492. BTFSS SW_PG_UP ; フラグ操作
  493. BSF F_KEY_PC
  494. BTFSS SW_PG_DOWN
  495. BSF F_KEY_PC
  496. GOTO L_CHECK_LCD_CHANGE ; LCDチェックへ
  497.  
  498. L_CHECK_PC_UP
  499. BTFSC SW_PG_UP ; PGUP?
  500. GOTO L_CHECK_PC_DOWN ; 違った
  501.  
  502. MOVLW D'20' ; チャタリング防止のためまつ
  503. MOVWF PG_CNT1 ; 汎用カウンタ
  504. CALL TIME1M
  505. DECFSZ PG_CNT1, F
  506. GOTO $ - D'2'
  507.  
  508. BSF F_KEY_PC ; PCフラグON
  509. INCF MIDI_PROG, F ; PROGインクリメント
  510. MOVF MIDI_PROG, W ; 128超えた?
  511. SUBLW D'128'
  512. BTFSC STATUS, Z
  513. CLRF MIDI_PROG ; 超えてた
  514.  
  515. L_CHECK_PC_DOWN
  516. BTFSC SW_PG_DOWN ; PGDOWN?
  517. GOTO L_CHECK_LCD_CHANGE ; 違った
  518.  
  519. MOVLW D'20' ; チャタリング防止のためまつ
  520. MOVWF PG_CNT1 ; 汎用カウンタ
  521. CALL TIME1M
  522. DECFSZ PG_CNT1, F
  523. GOTO $ - D'2'
  524.  
  525. BSF F_KEY_PC ; PCフラグON
  526. DECF MIDI_PROG, F ; PROGデクリメント
  527. MOVF MIDI_PROG, W ; 0すぎたかチェック
  528. SUBLW 0xFF ; 0すぎた?
  529. BTFSS STATUS, Z
  530. GOTO $ + D'3' ; 過ぎてなかった
  531. MOVLW D'127' ; PROGを127に
  532. MOVWF MIDI_PROG
  533.  
  534. ; 液晶の書き換えが必要かチェック
  535.  
  536. L_CHECK_LCD_CHANGE
  537. BCF F_KEY_LCD ; フラグ解除
  538. BCF F_KEY_C_VELO
  539. BCF F_KEY_C_HOLD
  540. BCF F_KEY_C_BEND
  541. BCF F_KEY_C_VOL
  542. BCF F_KEY_C_LMH
  543. BCF F_KEY_C_PROG
  544.  
  545. MOVF MIDI_B_BEND, W ; 前回とのチェック
  546. SUBWF MIDI_BEND, W
  547. BTFSC STATUS, Z
  548. GOTO $ + D'3'
  549. BSF F_KEY_LCD
  550. BSF F_KEY_C_BEND
  551. MOVF MIDI_BEND, W
  552. MOVWF MIDI_B_BEND
  553.  
  554. MOVF MIDI_B_VOL, W ; 前回とのチェック
  555. SUBWF MIDI_VOL, W
  556. BTFSC STATUS, Z
  557. GOTO $ + D'3'
  558. BSF F_KEY_LCD
  559. BSF F_KEY_C_VOL
  560. MOVF MIDI_VOL, W
  561. MOVWF MIDI_B_VOL
  562.  
  563. MOVF MIDI_B_VELO, W ; 前回とのチェック
  564. SUBWF MIDI_VELO, W
  565. BTFSC STATUS, Z
  566. GOTO $ + D'3'
  567. BSF F_KEY_LCD
  568. BSF F_KEY_C_VELO
  569. MOVF MIDI_VELO, W
  570. MOVWF MIDI_B_VELO
  571.  
  572. MOVF MIDI_B_LMH, W ; 前回とのチェック
  573. SUBWF MIDI_LMH, W
  574. BTFSC STATUS, Z
  575. GOTO $ + D'3'
  576. BSF F_KEY_LCD
  577. BSF F_KEY_C_LMH
  578. MOVF MIDI_LMH, W
  579. MOVWF MIDI_B_LMH
  580.  
  581. MOVF MIDI_B_HOLD, W ; 前回とのチェック
  582. SUBWF MIDI_HOLD, W
  583. BTFSC STATUS, Z
  584. GOTO $ + D'3'
  585. BSF F_KEY_LCD
  586. BSF F_KEY_C_HOLD
  587. MOVF MIDI_HOLD, W
  588. MOVWF MIDI_B_HOLD
  589.  
  590. MOVF MIDI_B_PROG, W ; 前回とのチェック
  591. SUBWF MIDI_PROG, W
  592. BTFSC STATUS, Z
  593. GOTO $ + D'3'
  594. BSF F_KEY_LCD
  595. BSF F_KEY_C_PROG
  596. MOVF MIDI_PROG, W
  597. MOVWF MIDI_B_PROG
  598.  
  599. ; MODEに入るかチェック ( 3秒押さなければならない )
  600.  
  601. BTFSC SW_MODE ; 押されてる?
  602. GOTO L_KEY_CHECK ; 押されてなかった
  603. BCF INTCON, GIE ; 割り込み対策
  604. CALL TIME05S ; 1.5秒まつ
  605. CALL TIME05S
  606. CALL TIME05S
  607. BSF INTCON, GIE ; 割り込み対策
  608. BTFSC SW_MODE ; 押されてる?
  609. GOTO L_KEY_CHECK
  610. GOTO MODE ; MODE画面へ
  611.  
  612. ; キーチェック
  613.  
  614. L_KEY_CHECK
  615. CLRF KEY_POS ; キー位置初期化
  616.  
  617. L_KEY_CHECK_LOOP
  618. MOVF KEY_POS, W ; キー位置読み出し
  619. MOVWF PORTD ; ポートへ設定
  620.  
  621. MOVF KEY_POS, W ; キー位置読み出し
  622. ADDLW 0xA0 ; アドレス基準値を足す
  623. MOVWF FSR ; FSRに設定
  624. BCF STATUS, IRP ; BANK0-1
  625. MOVF INDF, W ; INDF経由で前回のキー状態を読み出し
  626. MOVWF KEY_BUF ; バッファへ
  627.  
  628. BTFSS KEY_IN ; キーの状態は?
  629. GOTO L_KEY_ON ; 押されてた
  630. GOTO L_KEY_OFF ; 押されてなかった
  631.  
  632. L_KEY_OFF ; 押されてなかった
  633. BTFSS KEY_BUF, 0 ; 前は押されてた?
  634. GOTO L_KEY_NEXT ; 変更がなかったので次へ
  635. L_KEY_OFF_CHANGE ; 押されてた
  636. MOVLW 0 ; キーを離す
  637. MOVWF INDF ; INDF経由で転送
  638. MOVF KEY_POS, W ; キー位置読み出し
  639. CALL KEY_TO_MIDI ; キー位置をMIDIに変換
  640. MOVWF KEY_BUF ; バッファに保存
  641.  
  642. BCF INTCON, GIE ; 割り込み禁止
  643. CALL MIDI_SEND_STA_NOTE_OFF ; ノートオフ
  644. MOVF KEY_BUF, W ; ノート送信
  645. CALL MIDI_SEND_BYTE ; 送信
  646. MOVLW 0x00 ; とりあえず0
  647. CALL MIDI_SEND_BYTE ; 送信
  648. BSF INTCON, GIE ; 割り込み再開
  649.  
  650. GOTO L_KEY_NEXT ; 次へ
  651.  
  652. L_KEY_ON
  653. BTFSC KEY_BUF, 0 ; 前は押されてなかった?
  654. GOTO L_KEY_NEXT ; 変更がなければ次へ
  655. L_KEY_ON_CHANGE ; 変更があった
  656. MOVLW 1 ; キーを押す
  657. MOVWF INDF ; INDF経由で転送
  658. MOVF KEY_POS, W ; キー位置読み出し
  659. CALL KEY_TO_MIDI ; キー位置をMIDIに変換
  660. MOVWF KEY_BUF ; バッファに保存
  661.  
  662. BCF INTCON, GIE ; 割り込み禁止
  663. CALL MIDI_SEND_STA_NOTE_ON ; ノートオン
  664. MOVF KEY_BUF, W ; ノート送信
  665. CALL MIDI_SEND_BYTE ; 送信
  666. MOVF MIDI_VELO, W ; キー押す
  667. CALL MIDI_SEND_BYTE ; 送信
  668. BSF INTCON, GIE ; 割り込み再開
  669.  
  670. GOTO L_KEY_NEXT ; 次へ
  671.  
  672. L_KEY_NEXT ; 次のキーへ
  673. INCF KEY_POS, F ; キー位置加算
  674. MOVF KEY_POS, W ; キー位置取り出し
  675. SUBLW D'41' ; オーバーした?
  676. BTFSS STATUS, Z ; オーバーかチェック
  677. GOTO L_KEY_CHECK_LOOP ; オーバーしてなかった
  678.  
  679. ; キーサーチ終了、その他MIDIメッセージ送信
  680.  
  681. L_KEY_SEND_HOLD
  682. BTFSS F_KEY_C_HOLD ; 変更あり?
  683. GOTO L_KEY_SEND_PC ; なかった
  684.  
  685. BCF INTCON, GIE ; 割り込み禁止
  686. CALL MIDI_SEND_STA_CTRL ; コントロール送信 ( HOLD用 )
  687. MOVLW MIDI_CTRL_HOLD ; ホールドコントロール
  688. CALL MIDI_SEND_BYTE
  689. MOVF MIDI_HOLD, W ; 押されてればホールド
  690. CALL MIDI_SEND_BYTE
  691. BSF INTCON, GIE ; 割り込み再開
  692.  
  693. L_KEY_SEND_PC
  694. BTFSS F_KEY_C_PROG ; PCあった?
  695. GOTO L_KEY_SEND_VOL ; なかった
  696.  
  697. BCF INTCON, GIE ; 割り込み禁止
  698. CALL MIDI_SEND_STA_PROG ; プログラムチェンジ送信
  699. MOVF MIDI_PROG, W ; プログラムナンバー取得
  700. CALL MIDI_SEND_BYTE ; 送信
  701. BSF INTCON, GIE ; 割り込み再開
  702.  
  703. L_KEY_SEND_VOL
  704. BTFSS F_KEY_C_VOL
  705. GOTO L_KEY_SEND_BEND
  706.  
  707. BCF INTCON, GIE ; 割り込み禁止
  708. CALL MIDI_SEND_STA_CTRL ; コントロール送信 ( VOL用 )
  709. MOVLW MIDI_CTRL_VOL_M ; MSB送信
  710. CALL MIDI_SEND_BYTE ; 送信
  711. MOVF MIDI_VOL, W ; ボリュームロード
  712. CALL MIDI_SEND_BYTE ; 送信
  713. BSF INTCON, GIE ; 割り込み再開
  714.  
  715. L_KEY_SEND_BEND
  716. BTFSS F_KEY_C_BEND
  717. GOTO L_KEY_CHANGE_LCD
  718.  
  719. BCF INTCON, GIE ; 割り込み禁止
  720. CALL MIDI_SEND_STA_BEND ; ピッチベンド
  721. MOVLW 0x00 ; LSBは0 ( ! )
  722. CALL MIDI_SEND_BYTE
  723. MOVF MIDI_BEND, W ; MSB読み出し
  724. CALL MIDI_SEND_BYTE
  725. BSF INTCON, GIE ; 割り込み再開
  726.  
  727. L_KEY_CHANGE_LCD ; 液晶更新 ( CALLが増えないようにCALL廃止 )
  728. ;BTFSS F_KEY_LCD
  729. ;GOTO L_KEY_END_LOOP
  730.  
  731. MOVLW LCD_CUR_1L ; 1行目へ
  732. CALL LCD_CUR ; 位置設定
  733.  
  734. MOVLW 'V' ; VOL
  735. CALL LCD_SEND
  736. MOVLW 'O'
  737. CALL LCD_SEND
  738.  
  739. MOVF MIDI_VOL, W ; VOL数値表示
  740. CALL TOSTR
  741. MOVF TOSTR_100, W
  742. CALL LCD_SEND
  743. MOVF TOSTR_10, W
  744. CALL LCD_SEND
  745. MOVF TOSTR_1, W
  746. CALL LCD_SEND
  747.  
  748. MOVLW ' ' ; 空白
  749. CALL LCD_SEND
  750.  
  751. MOVLW 'B' ; BEND
  752. CALL LCD_SEND
  753.  
  754. MOVF MIDI_BEND, W ; P.BEND数値表示
  755. CALL TOSTR
  756. MOVF TOSTR_100, W
  757. CALL LCD_SEND
  758. MOVF TOSTR_10, W
  759. CALL LCD_SEND
  760. MOVF TOSTR_1, W
  761. CALL LCD_SEND
  762.  
  763. MOVLW ' ' ; 空白
  764. CALL LCD_SEND
  765.  
  766. MOVLW 'C' ; CH
  767. CALL LCD_SEND
  768.  
  769. MOVF MIDI_CH, W ; CH数値表示
  770. CALL TOSTR
  771. MOVF TOSTR_10, W
  772. CALL LCD_SEND
  773. MOVF TOSTR_1, W
  774. CALL LCD_SEND
  775.  
  776. MOVLW ' ' ; 空白
  777. CALL LCD_SEND
  778.  
  779. MOVLW 'M' ; LMH出力
  780. BTFSS SW_OCT_L ; L
  781. MOVLW 'L'
  782. BTFSS SW_OCT_H ; H
  783. MOVLW 'H'
  784. CALL LCD_SEND
  785.  
  786. MOVLW LCD_CUR_2L ; 2行目へ
  787. CALL LCD_CUR ; 位置設定
  788.  
  789. MOVLW 'V' ; VEL
  790. CALL LCD_SEND
  791. MOVLW 'E'
  792. CALL LCD_SEND
  793.  
  794. MOVF MIDI_VELO, W ; VEL数値表示
  795. CALL TOSTR
  796. MOVF TOSTR_100, W
  797. CALL LCD_SEND
  798. MOVF TOSTR_10, W
  799. CALL LCD_SEND
  800. MOVF TOSTR_1, W
  801. CALL LCD_SEND
  802.  
  803. MOVLW ' ' ; 空白
  804. CALL LCD_SEND
  805.  
  806. MOVLW 'P' ; PROGRAM
  807. CALL LCD_SEND
  808.  
  809. MOVF MIDI_PROG, W ; PROG数値表示
  810. CALL TOSTR
  811. MOVF TOSTR_100, W
  812. CALL LCD_SEND
  813. MOVF TOSTR_10, W
  814. CALL LCD_SEND
  815. MOVF TOSTR_1, W
  816. CALL LCD_SEND
  817.  
  818. MOVLW ' ' ; 空白
  819. CALL LCD_SEND
  820.  
  821. MOVLW ' ' ; 空白
  822. CALL LCD_SEND
  823.  
  824. BTFSS F_PLAY_PLAY ; 再生中
  825. GOTO $ + D'9'
  826. MOVLW 'P'
  827. CALL LCD_SEND
  828. MOVLW 'L'
  829. CALL LCD_SEND
  830. MOVLW 'A'
  831. CALL LCD_SEND
  832. MOVLW 'Y'
  833. CALL LCD_SEND
  834.  
  835. BTFSC F_PLAY_PLAY
  836. GOTO $ + D'9'
  837. MOVLW 'S'
  838. CALL LCD_SEND
  839. MOVLW 'T'
  840. CALL LCD_SEND
  841. MOVLW 'O'
  842. CALL LCD_SEND
  843. MOVLW 'P'
  844. CALL LCD_SEND
  845.  
  846. L_KEY_END_LOOP
  847. CALL TIME1M ; 待ってみる DEBUG
  848. CALL TIME1M
  849.  
  850. CALL TIME1M
  851. CALL TIME1M
  852. CALL TIME1M
  853. GOTO MAIN ; メインループ
  854.  
  855. ; * MODE **********************************************************************
  856.  
  857. MODE ; モード画面
  858. CLRF MODE_POS ; クリア
  859. CALL LCD_CLR ; 画面クリア
  860.  
  861. ; スイッチチェック
  862.  
  863. L_MODE_LOOP
  864. L_MODE_SW_UP
  865. BTFSC SW_PG_UP ; 上がおされた?
  866. GOTO L_MODE_SW_DOWN ; おされてない
  867.  
  868. MOVLW D'20' ; チャタリング防止のためまつ
  869. MOVWF PG_CNT1 ; 汎用カウンタ
  870. CALL TIME1M
  871. DECFSZ PG_CNT1, F
  872. GOTO $ - D'2'
  873.  
  874. BTFSS SW_PG_UP ; 押されてる限り進まない
  875. GOTO $ - D'1'
  876. INCF MODE_POS, F ; モード変更
  877. MOVLW MODE_MAX ; 最大値超えた?
  878. ADDLW D'1' ; MAX + 1
  879. SUBWF MODE_POS, W
  880. BTFSC STATUS, Z
  881. CLRF MODE_POS ; 0に
  882.  
  883. L_MODE_SW_DOWN
  884. BTFSC SW_PG_DOWN ; 下が押されてた?
  885. GOTO L_MODE_PAINT ; 押されてなかった
  886.  
  887. MOVLW D'20' ; チャタリング防止のためまつ
  888. MOVWF PG_CNT1 ; 汎用カウンタ
  889. CALL TIME1M
  890. DECFSZ PG_CNT1, F
  891. GOTO $ - D'2'
  892.  
  893. BTFSS SW_PG_DOWN ; 押されてる限り進まない
  894. GOTO $ - D'1'
  895. DECF MODE_POS, F ; モード変更
  896. MOVLW 0xFF ; 0超えた?
  897. SUBWF MODE_POS, W
  898. BTFSS STATUS, Z
  899. GOTO L_MODE_PAINT
  900. MOVLW MODE_MAX ; 過ぎてたのでMAXに
  901. MOVWF MODE_POS
  902.  
  903. ; 画面に現在の状態を表示
  904.  
  905. L_MODE_PAINT
  906. MOVLW LCD_CUR_1L ; 1行目へ
  907. CALL LCD_CUR ; 位置設定
  908.  
  909. MOVLW 'M' ; MODE
  910. CALL LCD_SEND
  911. MOVLW 'O'
  912. CALL LCD_SEND
  913. MOVLW 'D'
  914. CALL LCD_SEND
  915. MOVLW 'E'
  916. CALL LCD_SEND
  917.  
  918. MOVLW LCD_CUR_2L ; 2行目へ
  919. CALL LCD_CUR ; 位置設定
  920.  
  921. L_MODE_PAINT_FORMAT
  922. MOVLW MODE_FORMAT ; FORMAT?
  923. SUBWF MODE_POS, W
  924. BTFSS STATUS, Z
  925. GOTO L_MODE_PAINT_STOP ; 次へ
  926. MOVLW 'F'
  927. CALL LCD_SEND
  928. MOVLW 'O'
  929. CALL LCD_SEND
  930. MOVLW 'R'
  931. CALL LCD_SEND
  932. MOVLW 'M'
  933. CALL LCD_SEND
  934. MOVLW 'A'
  935. CALL LCD_SEND
  936. MOVLW 'T'
  937. CALL LCD_SEND
  938. MOVLW D'10' ; スペースで埋める
  939. MOVWF MODE_BUF
  940. MOVLW ' '
  941. CALL LCD_SEND
  942. DECFSZ MODE_BUF, F
  943. GOTO $ - D'3'
  944.  
  945. L_MODE_PAINT_STOP
  946. MOVLW MODE_STOP ; STOP?
  947. SUBWF MODE_POS, W
  948. BTFSS STATUS, Z
  949. GOTO L_MODE_PAINT_PLAY ; 次へ
  950. MOVLW 'S'
  951. CALL LCD_SEND
  952. MOVLW 'T'
  953. CALL LCD_SEND
  954. MOVLW 'O'
  955. CALL LCD_SEND
  956. MOVLW 'P'
  957. CALL LCD_SEND
  958. MOVLW D'12' ; スペースで埋める
  959. MOVWF MODE_BUF
  960. MOVLW ' '
  961. CALL LCD_SEND
  962. DECFSZ MODE_BUF, F
  963. GOTO $ - D'3'
  964.  
  965. L_MODE_PAINT_PLAY
  966. MOVLW MODE_PLAY ; PLAY?
  967. SUBWF MODE_POS, W
  968. BTFSS STATUS, Z
  969. GOTO L_MODE_PAINT_CANCEL ; 次へ
  970. MOVLW 'P'
  971. CALL LCD_SEND
  972. MOVLW 'L'
  973. CALL LCD_SEND
  974. MOVLW 'A'
  975. CALL LCD_SEND
  976. MOVLW 'Y'
  977. CALL LCD_SEND
  978. MOVLW D'12' ; スペースで埋める
  979. MOVWF MODE_BUF
  980. MOVLW ' '
  981. CALL LCD_SEND
  982. DECFSZ MODE_BUF, F
  983. GOTO $ - D'3'
  984.  
  985. L_MODE_PAINT_CANCEL
  986. MOVLW MODE_CANCEL ; CANCEL?
  987. SUBWF MODE_POS, W
  988. BTFSS STATUS, Z
  989. GOTO L_MODE_PAINT_CH ; 次へ
  990. MOVLW 'C'
  991. CALL LCD_SEND
  992. MOVLW 'A'
  993. CALL LCD_SEND
  994. MOVLW 'N'
  995. CALL LCD_SEND
  996. MOVLW 'C'
  997. CALL LCD_SEND
  998. MOVLW 'E'
  999. CALL LCD_SEND
  1000. MOVLW 'L'
  1001. CALL LCD_SEND
  1002. MOVLW D'10' ; スペースで埋める
  1003. MOVWF MODE_BUF
  1004. MOVLW ' '
  1005. CALL LCD_SEND
  1006. DECFSZ MODE_BUF, F
  1007. GOTO $ - D'3'
  1008.  
  1009. L_MODE_PAINT_CH
  1010. MOVLW MODE_CH
  1011. SUBWF MODE_POS, W
  1012. BTFSS STATUS, Z
  1013. GOTO L_MODE_CHECK_ENTER ; 次へ
  1014. MOVLW 'C'
  1015. CALL LCD_SEND
  1016. MOVLW 'H'
  1017. CALL LCD_SEND
  1018. MOVLW 'A'
  1019. CALL LCD_SEND
  1020. MOVLW 'N'
  1021. CALL LCD_SEND
  1022. MOVLW 'N'
  1023. CALL LCD_SEND
  1024. MOVLW 'E'
  1025. CALL LCD_SEND
  1026. MOVLW 'L'
  1027. CALL LCD_SEND
  1028. MOVLW D'9' ; スペースで埋める
  1029. MOVWF MODE_BUF
  1030. MOVLW ' '
  1031. CALL LCD_SEND
  1032. DECFSZ MODE_BUF, F
  1033. GOTO $ - D'3'
  1034.  
  1035. L_MODE_CHECK_ENTER ; 決定されるかチェック
  1036. BTFSC SW_HOLD ; 押されてる? ( HOLDがエンターキー )
  1037. GOTO L_MODE_LOOP
  1038.  
  1039. MOVLW D'20' ; チャタリング防止のためまつ
  1040. MOVWF PG_CNT1 ; 汎用カウンタ
  1041. CALL TIME1M
  1042. DECFSZ PG_CNT1, F
  1043. GOTO $ - D'2'
  1044.  
  1045. BTFSS SW_HOLD ; 押されてる限り進まない
  1046. GOTO $ - D'1'
  1047.  
  1048. MOVLW D'40' ; チャタリング防止のためまつ ( 長め )
  1049. MOVWF PG_CNT1 ; 汎用カウンタ
  1050. CALL TIME1M
  1051. DECFSZ PG_CNT1, F
  1052. GOTO $ - D'2'
  1053.  
  1054. L_MODE_CANCEL
  1055. MOVLW MODE_CANCEL ; キャンセルか?
  1056. SUBWF MODE_POS, W
  1057. BTFSS STATUS, Z
  1058. GOTO L_MODE_FORMAT ; 違った
  1059. GOTO L_MODE_EXIT
  1060.  
  1061. L_MODE_FORMAT ; カードフォーマッタ起動
  1062. MOVLW MODE_FORMAT ; フォーマットか?
  1063. SUBWF MODE_POS, W
  1064. BTFSS STATUS, Z
  1065. GOTO L_MODE_PLAY ; 違った
  1066.  
  1067. BTFSC F_PLAY_PLAY ; 再生中だとなにもしない
  1068. GOTO L_MODE_EXIT
  1069.  
  1070. CALL LCD_CLR ; 画面クリア
  1071. MOVLW LCD_CUR_1L ; 1行目へ
  1072. CALL LCD_CUR ; 位置設定
  1073.  
  1074. MOVLW 'W' ; WAIT
  1075. CALL LCD_SEND
  1076. MOVLW 'A'
  1077. CALL LCD_SEND
  1078. MOVLW 'I'
  1079. CALL LCD_SEND
  1080. MOVLW 'T'
  1081. CALL LCD_SEND
  1082. MOVLW '.'
  1083. CALL LCD_SEND
  1084. MOVLW '.'
  1085. CALL LCD_SEND
  1086. MOVLW '.'
  1087. CALL LCD_SEND
  1088.  
  1089. CALL MMC_INIT ; MMCを初期化
  1090. CLRF MMC_ARG
  1091. CLRF MMC_ARG1
  1092. CLRF MMC_ARG2
  1093. CLRF MMC_ARG3
  1094.  
  1095. ; MMCへFAT12ファイルシステムと、ひとつのテキストファイル書き込み開始
  1096.  
  1097. CALL MMC_WRITE_HEAD ; MMCへ書き込み開始
  1098.  
  1099. MOVLW D'62' ; 先頭の62バイト送信開始
  1100. MOVWF PG_CNT1 ; 汎用カウンタ1へ
  1101.  
  1102. CLRF PG_POINT1 ; 汎用ポインタをブートセクタ読み出しポインタにする
  1103. CALL T_GET_BOOTSECTOR ; ブートセクター取得用関数
  1104. INCF PG_POINT1, F ; ポインタ加算
  1105. CALL SPI_START ; 送信
  1106. DECFSZ PG_CNT1, F ; 62バイト送った?
  1107. GOTO $ - D'4' ; 繰り返し
  1108.  
  1109. MOVLW D'18' ; 18バイト0送る
  1110. MOVWF PG_CNT1
  1111. MOVLW 00H ; 0
  1112. CALL SPI_START ; 送信
  1113. DECFSZ PG_CNT1, F
  1114. GOTO $ - D'3'
  1115.  
  1116. MOVLW D'215' ; 215バイト0送る
  1117. MOVWF PG_CNT1
  1118. MOVLW 00H ; 0
  1119. CALL SPI_START ; 送信
  1120. DECFSZ PG_CNT1, F
  1121. GOTO $ - D'3'
  1122.  
  1123. MOVLW D'215' ; 215バイト0送る
  1124. MOVWF PG_CNT1
  1125. MOVLW 00H ; 0
  1126. CALL SPI_START ; 送信
  1127. DECFSZ PG_CNT1, F
  1128. GOTO $ - D'3'
  1129.  
  1130. MOVLW 055H ; ブートフラグ立てる
  1131. CALL SPI_START
  1132. MOVLW 0AAH
  1133. CALL SPI_START
  1134.  
  1135. CALL MMC_WRITE_FOOT ; 送信第一段階完了
  1136.  
  1137. MOVLW D'2' ; 第二セクターへ
  1138. MOVWF MMC_ARG2 ; 引数設定
  1139.  
  1140. CALL MMC_WRITE_HEAD ; 送信第二段階開始
  1141.  
  1142. MOVLW 0F0H ; 第一FAT書き込み開始 ( 512バイト以内のファイルを一個含む )
  1143. CALL SPI_START
  1144. MOVLW 0FFH
  1145. CALL SPI_START
  1146. MOVLW 0FFH
  1147. CALL SPI_START
  1148. MOVLW 0FFH
  1149. CALL SPI_START
  1150. MOVLW 00FH
  1151. CALL SPI_START
  1152.  
  1153. MOVLW D'255' ; 255バイト0送る
  1154. MOVWF PG_CNT1
  1155. MOVLW 00H ; 0
  1156. CALL SPI_START ; 送信
  1157. DECFSZ PG_CNT1, F
  1158. GOTO $ - D'3'
  1159.  
  1160. MOVLW D'252' ; 252バイト0送る
  1161. MOVWF PG_CNT1
  1162. MOVLW 00H ; 0
  1163. CALL SPI_START ; 送信
  1164. DECFSZ PG_CNT1, F
  1165. GOTO $ - D'3'
  1166.  
  1167. CALL MMC_WRITE_FOOT ; 送信第2段階完了
  1168.  
  1169. MOVLW D'8' ; 8回
  1170. MOVWF PG_CNT2
  1171. L_MODE_FORMAT_FAT_L
  1172. INCF MMC_ARG2, F ; 残りのFATを0で埋めておく
  1173. INCF MMC_ARG2, F
  1174.  
  1175. CALL MMC_WRITE_HEAD ; 書き込み開始
  1176.  
  1177. MOVLW 0x00 ; 0
  1178. CALL SPI_START
  1179. MOVLW 0x00 ; 0
  1180. CALL SPI_START
  1181.  
  1182. MOVLW D'255' ; 255バイト0送る
  1183. MOVWF PG_CNT1
  1184. MOVLW 00H ; 0
  1185. CALL SPI_START ; 送信
  1186. DECFSZ PG_CNT1, F
  1187. GOTO $ - D'3'
  1188.  
  1189. MOVLW D'255' ; 255バイト0送る
  1190. MOVWF PG_CNT1
  1191. MOVLW 00H ; 0
  1192. CALL SPI_START ; 送信
  1193. DECFSZ PG_CNT1, F
  1194. GOTO $ - D'3'
  1195.  
  1196. CALL MMC_WRITE_FOOT ; 完了
  1197.  
  1198. DECFSZ PG_CNT2, F ; 8回うめた?
  1199. GOTO L_MODE_FORMAT_FAT_L ; 埋めてない
  1200.  
  1201. ; ここまででFAT自体は完了、以下、適当ファイル書き込み開始
  1202.  
  1203. MOVLW 026H ; ファイル情報開始
  1204. MOVWF MMC_ARG2
  1205.  
  1206. CALL MMC_WRITE_HEAD ; ファイル情報書き込み開始
  1207.  
  1208. MOVLW 'T' ; ファイル名8.3形式
  1209. CALL SPI_START
  1210. MOVLW 'E'
  1211. CALL SPI_START
  1212. MOVLW 'S'
  1213. CALL SPI_START
  1214. MOVLW 'T'
  1215. CALL SPI_START
  1216. MOVLW ' '
  1217. CALL SPI_START
  1218. MOVLW ' '
  1219. CALL SPI_START
  1220. MOVLW ' '
  1221. CALL SPI_START
  1222. MOVLW ' '
  1223. CALL SPI_START
  1224. MOVLW 'T'
  1225. CALL SPI_START
  1226. MOVLW 'X'
  1227. CALL SPI_START
  1228. MOVLW 'T'
  1229. CALL SPI_START
  1230.  
  1231.  
  1232. MOVLW 020H ; ファイルタイプ
  1233. CALL SPI_START
  1234.  
  1235. MOVLW D'10' ; 10バイト0送る
  1236. MOVWF PG_CNT1
  1237. MOVLW 00H ; 0
  1238. CALL SPI_START ; 送信
  1239. DECFSZ PG_CNT1, F
  1240. GOTO $ - D'3'
  1241.  
  1242. MOVLW 00H ; ファイルの時間
  1243. CALL SPI_START
  1244. MOVLW 00H
  1245. CALL SPI_START
  1246.  
  1247. MOVLW 22H ; ファイルの日付
  1248. CALL SPI_START
  1249. MOVLW 22H
  1250. CALL SPI_START
  1251.  
  1252. MOVLW 02H ; ファイルの開始クラスタナンバー
  1253. CALL SPI_START
  1254. MOVLW 00H
  1255. CALL SPI_START
  1256.  
  1257. MOVLW D'10' ; ファイルサイズ
  1258. CALL SPI_START
  1259. MOVLW 00H
  1260. CALL SPI_START
  1261. MOVLW 00H
  1262. CALL SPI_START
  1263. MOVLW 00H
  1264. CALL SPI_START
  1265.  
  1266. MOVLW D'255' ; 255バイト0送る
  1267. MOVWF PG_CNT1
  1268. MOVLW 00H ; 0
  1269. CALL SPI_START ; 送信
  1270. DECFSZ PG_CNT1, F
  1271. GOTO $ - D'3'
  1272.  
  1273. MOVLW D'225' ; 225バイト0送る
  1274. MOVWF PG_CNT1
  1275. MOVLW 00H ; 0
  1276. CALL SPI_START ; 送信
  1277. DECFSZ PG_CNT1, F
  1278. GOTO $ - D'3'
  1279.  
  1280. CALL MMC_WRITE_FOOT ; ファイル情報書き込み完了
  1281.  
  1282. ; ファイル開始
  1283.  
  1284. MOVLW 042H ; ファイル開始アドレス指定
  1285. MOVWF MMC_ARG2
  1286.  
  1287. CALL MMC_WRITE_HEAD ; ファイル書き込み開始
  1288.  
  1289. MOVLW 'P' ; 適当な文字列
  1290. CALL SPI_START
  1291. MOVLW 'I'
  1292. CALL SPI_START
  1293. MOVLW 'C'
  1294. CALL SPI_START
  1295. MOVLW '*'
  1296. CALL SPI_START
  1297. MOVLW 'F'
  1298. CALL SPI_START
  1299. MOVLW 'A'
  1300. CALL SPI_START
  1301. MOVLW 'T'
  1302. CALL SPI_START
  1303. MOVLW '!'
  1304. CALL SPI_START
  1305. MOVLW 00DH
  1306. CALL SPI_START
  1307. MOVLW 00AH
  1308. CALL SPI_START
  1309.  
  1310. MOVLW D'255' ; 255バイト0送る
  1311. MOVWF PG_CNT1
  1312. MOVLW 00H ; 0
  1313. CALL SPI_START ; 送信
  1314. DECFSZ PG_CNT1, F
  1315. GOTO $ - D'3'
  1316.  
  1317. MOVLW D'247' ; 253バイト0送る
  1318. MOVWF PG_CNT1
  1319. MOVLW 00H ; 0
  1320. CALL SPI_START ; 送信
  1321. DECFSZ PG_CNT1, F
  1322. GOTO $ - D'3'
  1323.  
  1324. CALL MMC_WRITE_FOOT ; ファイル書き込み完了
  1325.  
  1326. CALL LCD_CLR ; 画面クリア
  1327. MOVLW LCD_CUR_1L ; 1行目へ
  1328. CALL LCD_CUR ; 位置設定
  1329.  
  1330. MOVLW 'O' ; 完了
  1331. CALL LCD_SEND
  1332. MOVLW 'K' ; 完了
  1333. CALL LCD_SEND
  1334. MOVLW '!' ; 完了
  1335. CALL LCD_SEND
  1336.  
  1337. CALL TIME05S ; ちょっとまつ
  1338. CALL TIME05S
  1339. CALL TIME05S
  1340. CALL TIME05S
  1341.  
  1342. GOTO L_MODE_EXIT
  1343.  
  1344. L_MODE_PLAY ; 再生する
  1345. MOVLW MODE_PLAY ; 再生か?
  1346. SUBWF MODE_POS, W
  1347. BTFSS STATUS, Z
  1348. GOTO L_MODE_STOP ; 違った
  1349. BTFSC F_PLAY_PLAY ; 再生中?
  1350. GOTO L_MODE_STOP ; だった
  1351.  
  1352. CALL MMC_INIT ; MMC初期化
  1353. L_MODE_PLAY_LOOP ; FAT12ある程度アクセスに挑戦!
  1354.  
  1355. ; ファイル情報までジャンプ
  1356.  
  1357. CALL FILE_READ_STOP ; もどってきた場合、一度読み込みを止めるため
  1358. MOVLW 0x26 ; ファイル情報の先頭
  1359. CALL FILE_READ_SET_START ; ファイルリード関数準備
  1360. CALL FILE_READ_START
  1361.  
  1362. L_MODE_PLAY_LOOP_NEXT ; 次のファイル情報へアクセス
  1363. CALL LCD_CLR ; 画面クリア
  1364. MOVLW LCD_CUR_1L ; 1行目へ
  1365. CALL LCD_CUR ; 位置設定
  1366.  
  1367. ; FILE NAME
  1368.  
  1369. MOVLW 'F' ; FILENAMEと表示
  1370. CALL LCD_SEND
  1371. MOVLW 'I'
  1372. CALL LCD_SEND
  1373. MOVLW 'L'
  1374. CALL LCD_SEND
  1375. MOVLW 'E'
  1376. CALL LCD_SEND
  1377. MOVLW ' '
  1378. CALL LCD_SEND
  1379. MOVLW 'N'
  1380. CALL LCD_SEND
  1381. MOVLW 'A'
  1382. CALL LCD_SEND
  1383. MOVLW 'M'
  1384. CALL LCD_SEND
  1385. MOVLW 'E'
  1386. CALL LCD_SEND
  1387.  
  1388. MOVLW LCD_CUR_2L ; 2行目へ
  1389. CALL LCD_CUR ; 位置設定
  1390.  
  1391. ; ファイル名取得
  1392.  
  1393. CALL FILE_READ ; 1文字目読み込み
  1394. MOVWF PG_CNT2 ; 保存しておく ( 存在判定用 )
  1395. CALL LCD_SEND ; 出力
  1396.  
  1397. MOVLW D'7' ; ファイル名ロード
  1398. MOVWF PG_CNT1 ; カウンタセット
  1399. CALL FILE_READ ; 読み出し
  1400. MOVWF PG_BUF1 ; バッファへ
  1401. MOVLW ' ' ; スペース?
  1402. SUBWF PG_BUF1, W ; スペース?
  1403. SWAPF PG_BUF1, F ; めんどくさいのでSWAP
  1404. SWAPF PG_BUF1, W ; SWAPで読み出し
  1405. BTFSS STATUS, Z ; スペースなら表示しない
  1406. CALL LCD_SEND ; そのまま書きこみ
  1407. DECFSZ PG_CNT1, F ; 全部読んだ?
  1408. GOTO $ - D'9'
  1409.  
  1410. MOVLW '.' ; .
  1411. CALL LCD_SEND
  1412.  
  1413. MOVLW D'3' ; 拡張子ロード
  1414. MOVWF PG_CNT1 ; カウンタセット
  1415. CALL FILE_READ ; 読み出し
  1416. CALL LCD_SEND ; そのまま書きこみ
  1417. DECFSZ PG_CNT1, F ; 全部読んだ?
  1418. GOTO $ - D'3'
  1419.  
  1420. ; から読み
  1421.  
  1422. MOVLW D'15'
  1423. MOVWF PG_CNT1
  1424. CALL FILE_READ
  1425. DECFSZ PG_CNT1, F
  1426. GOTO $ - D'2'
  1427.  
  1428. ; 開始場所ロード
  1429.  
  1430. CALL FILE_READ
  1431. MOVWF PLAY_CLS_0
  1432. CALL FILE_READ
  1433. MOVWF PLAY_CLS_1
  1434.  
  1435. ; サイズは読み捨て
  1436.  
  1437. CALL FILE_READ
  1438. CALL FILE_READ
  1439. CALL FILE_READ
  1440. CALL FILE_READ
  1441.  
  1442. ; ファイルが存在するかチェック ( ファイル名の先頭が0xE5か0x00を利用 )
  1443.  
  1444. MOVF PG_CNT2, F
  1445. BTFSC STATUS, Z ; 最初の文字が0なら最後のエントリなので最初に戻る
  1446. GOTO L_MODE_PLAY_LOOP
  1447.  
  1448. MOVLW 0xE5 ; 削除済み?
  1449. SUBWF PG_CNT2, W ; 削除済み?
  1450. BTFSC STATUS, Z
  1451. GOTO L_MODE_PLAY_LOOP_NEXT ; 削除済みなので次のエントリへ
  1452.  
  1453. ; 開始場所をセクターに変換
  1454.  
  1455. L_MODE_PLAY_CONV_SECT
  1456. BCF STATUS, C ; キャリークリア
  1457. RLF PLAY_CLS_0, F ; *2
  1458. RLF PLAY_CLS_1, F ; *2
  1459. MOVLW 0x3E ; 基準加算
  1460. ADDWF PLAY_CLS_0, F
  1461. BTFSC STATUS, C ; キャリーチェック
  1462. INCF PLAY_CLS_1, F ; キャリーが発生してれば加算
  1463.  
  1464. L_MODE_PLAY_SW_UP
  1465. BTFSC SW_PG_UP ; 上がおされた?
  1466. GOTO L_MODE_PLAY_SW_DOWN ; おされてない
  1467.  
  1468. MOVLW D'20' ; チャタリング防止のためまつ
  1469. MOVWF PG_CNT1 ; 汎用カウンタ
  1470. CALL TIME1M
  1471. DECFSZ PG_CNT1, F
  1472. GOTO $ - D'2'
  1473.  
  1474. BTFSS SW_PG_UP ; 押されてる限り進まない
  1475. GOTO $ - D'1'
  1476. GOTO L_MODE_PLAY_LOOP_NEXT ; 繰り返し
  1477.  
  1478. L_MODE_PLAY_SW_DOWN
  1479. BTFSC SW_PG_DOWN ; 下が押されてた?
  1480. GOTO L_MODE_PLAY_CHECK_ENTER ; 押されてなかった
  1481.  
  1482. MOVLW D'20' ; チャタリング防止のためまつ
  1483. MOVWF PG_CNT1 ; 汎用カウンタ
  1484. CALL TIME1M
  1485. DECFSZ PG_CNT1, F
  1486. GOTO $ - D'2'
  1487.  
  1488. BTFSS SW_PG_DOWN ; 押されてる限り進まない
  1489. GOTO $ - D'1'
  1490. GOTO L_MODE_PLAY_LOOP_NEXT ; 繰り返し
  1491.  
  1492. L_MODE_PLAY_CHECK_ENTER ; 決定された
  1493. BTFSC SW_HOLD ; された?
  1494. GOTO L_MODE_PLAY_SW_UP ; されてないのでスイッチチェックに戻る
  1495. CALL FILE_READ_STOP ; 読み込み停止
  1496. CALL PLAY_PLAY ; されたので再生
  1497.  
  1498. GOTO L_MODE_EXIT
  1499.  
  1500. L_MODE_STOP
  1501. MOVLW MODE_STOP ; 停止?
  1502. SUBWF MODE_POS, W
  1503. BTFSS STATUS, Z
  1504. GOTO L_MODE_CH ; 違った
  1505.  
  1506. BCF INTCON, GIE
  1507. CALL PLAY_STOP ; 停止
  1508. BSF INTCON, GIE
  1509.  
  1510. GOTO L_MODE_EXIT
  1511.  
  1512. L_MODE_CH ; チャンネル変更?
  1513. MOVLW MODE_CH
  1514. SUBWF MODE_POS, W
  1515. BTFSS STATUS, Z
  1516. GOTO L_MODE_EXIT ; 違った
  1517.  
  1518. CALL LCD_CLR ; クリア
  1519. MOVLW LCD_CUR_1L ; 1行目へ
  1520. CALL LCD_CUR ; 位置設定
  1521.  
  1522. MOVLW 'C'
  1523. CALL LCD_SEND
  1524. MOVLW 'H'
  1525. CALL LCD_SEND
  1526. MOVLW 'A'
  1527. CALL LCD_SEND
  1528. MOVLW 'N'
  1529. CALL LCD_SEND
  1530. MOVLW 'N'
  1531. CALL LCD_SEND
  1532. MOVLW 'E'
  1533. CALL LCD_SEND
  1534. MOVLW 'L'
  1535. CALL LCD_SEND
  1536.  
  1537. L_MODE_CH_LOOP
  1538. L_MODE_CH_SW_UP
  1539. BTFSC SW_PG_UP ; 上がおされた?
  1540. GOTO L_MODE_CH_SW_DOWN ; おされてない
  1541.  
  1542. MOVLW D'20' ; チャタリング防止のためまつ
  1543. MOVWF PG_CNT1 ; 汎用カウンタ
  1544. CALL TIME1M
  1545. DECFSZ PG_CNT1, F
  1546. GOTO $ - D'2'
  1547.  
  1548. BTFSS SW_PG_UP ; 押されてる限り進まない
  1549. GOTO $ - D'1'
  1550. INCF MIDI_CH, F ; モード変更
  1551. MOVLW D'16' ; 最大値超えた?
  1552. SUBWF MIDI_CH, W
  1553. BTFSC STATUS, Z
  1554. CLRF MIDI_CH ; 0に
  1555.  
  1556. L_MODE_CH_SW_DOWN
  1557. BTFSC SW_PG_DOWN ; 下が押されてた?
  1558. GOTO L_MODE_CH_PUT ; 押されてなかった
  1559.  
  1560.  
  1561. MOVLW D'20' ; チャタリング防止のためまつ
  1562. MOVWF PG_CNT1 ; 汎用カウンタ
  1563. CALL TIME1M
  1564. DECFSZ PG_CNT1, F
  1565. GOTO $ - D'2'
  1566.  
  1567. BTFSS SW_PG_DOWN ; 押されてる限り進まない
  1568. GOTO $ - D'1'
  1569. DECF MIDI_CH, F ; モード変更
  1570. MOVLW 0xFF ; 0超えた?
  1571. SUBWF MIDI_CH, W
  1572. BTFSS STATUS, Z
  1573. GOTO L_MODE_CH_PUT
  1574. MOVLW D'15' ; 過ぎてたのでMAXに
  1575. MOVWF MIDI_CH
  1576.  
  1577. L_MODE_CH_PUT
  1578. MOVLW LCD_CUR_2L ; 2行目へ
  1579. CALL LCD_CUR ; 位置設定
  1580. MOVF MIDI_CH, W ; 読み出し
  1581. CALL TOSTR ; 文字に変換
  1582. MOVF TOSTR_10, W
  1583. CALL LCD_SEND
  1584. MOVF TOSTR_1, W
  1585. CALL LCD_SEND
  1586.  
  1587. BTFSS SW_HOLD ; 決定された?
  1588. GOTO L_MODE_EXIT ; された
  1589. GOTO L_MODE_CH_LOOP ; されてない
  1590.  
  1591. L_MODE_EXIT ; MODEモード終了
  1592. GOTO MAIN ; MAINに戻る ( 液晶を更新してもらう )
  1593.  
  1594. ; * INT ***********************************************************************
  1595.  
  1596. INT ; 割り込みルーチン開始
  1597. PUSH MOVWF TMP_W ; Wreg退避 ( 共通アクセス可能領域へ )
  1598. SWAPF STATUS, W ; SWAP命令はフラグに影響しないので、これを使ってSTATUS退避
  1599. CLRF STATUS ; BANK0に切り替え ( 割り込みはBANK0で )
  1600. MOVWF TMP_STATUS ; STATUS退避
  1601. MOVF PCLATH, W ; PCLATH退避
  1602. MOVWF TMP_PCLATH
  1603. CLRF PCLATH ; PAGE0へ ( 割り込みはPAGE0で )
  1604. MOVF FSR, W ; FSR退避
  1605. MOVWF TMP_FSR
  1606.  
  1607. INT_CHECK
  1608. BTFSS INTCON, T0IE ; タイマ0割り込み使えるか
  1609. GOTO $ + D'3' ; 使えない
  1610. BTFSC INTCON, T0IF ; タイマ0割り込み
  1611. GOTO INT_T0 ; T0のINTへ
  1612.  
  1613. BSF STATUS, RP0 ; BANK1へ
  1614. BTFSS PIE1, TXIE ; 送信割り込み許可?
  1615. GOTO $ + D'4'
  1616. BCF STATUS, RP0 ; BANK0
  1617. BTFSC PIR1, TXIF ; 送信完了割り込み
  1618. GOTO INT_TX ; TXのINTへ
  1619.  
  1620. BSF STATUS, RP0 ; BANK1へ
  1621. BTFSS PIE1, SSPIE ; SPI割り込み許可
  1622. GOTO $ + D'4'
  1623. BCF STATUS, RP0 ; BANK0
  1624. BTFSC PIR1, SSPIF ; SPI完了割り込み
  1625. GOTO INT_SPI ; SPIのINTへ
  1626.  
  1627. BCF STATUS, RP0 ; BANK0
  1628. GOTO POP ; 脱出
  1629.  
  1630. INT_T0 ; タイマ0割り込み ( MIDIプレーヤー用 )
  1631. BTFSS F_PLAY_DELTA ; デルタ処理中?
  1632. GOTO INT_T0_READ_NEXT ; 違った
  1633.  
  1634. INT_T0_DELTA ; デルタ処理
  1635. MOVF PLAY_TEMPO, W ; テンポ読み出し
  1636. MOVWF TMR0 ; タイマ0再設定 ( プリスケーラクリア、カウント再開 )
  1637.  
  1638. CLRF PLAY_D_BUF
  1639. MOVF PLAY_D_0, F ; 全部0かチェック
  1640. BTFSS STATUS, Z
  1641. INCF PLAY_D_BUF, F
  1642. MOVF PLAY_D_1, F
  1643. BTFSS STATUS, Z
  1644. INCF PLAY_D_BUF, F
  1645. MOVF PLAY_D_2, F
  1646. BTFSS STATUS, Z
  1647. INCF PLAY_D_BUF, F
  1648. MOVF PLAY_D_3, F
  1649. BTFSS STATUS, Z
  1650. INCF PLAY_D_BUF, F
  1651.  
  1652. MOVF PLAY_D_BUF, F
  1653. BTFSC STATUS, Z ; 0だった?
  1654. GOTO INT_T0_DELTA_SEND_MIDI ; MIDI送信へ
  1655.  
  1656. DECF PLAY_D_0, F ; 32bitデクリメント
  1657. MOVF PLAY_D_0, W
  1658. SUBLW 0xFF ; ボローした?
  1659. BTFSS STATUS, Z
  1660. GOTO INT_T0_OUT
  1661. DECF PLAY_D_1, F
  1662. MOVF PLAY_D_1, W
  1663. SUBLW 0xFF
  1664. BTFSS STATUS, Z
  1665. GOTO INT_T0_OUT
  1666. DECF PLAY_D_2, F
  1667. MOVF PLAY_D_2, W
  1668. SUBLW 0xFF
  1669. BTFSS STATUS, Z
  1670. GOTO INT_T0_OUT
  1671. DECF PLAY_D_3, F
  1672. MOVF PLAY_D_3, W
  1673. SUBLW 0xFF
  1674. BTFSS STATUS, Z
  1675. GOTO INT_T0_OUT
  1676.  
  1677. INT_T0_DELTA_SEND_MIDI ; MIDI送信 ( バッファにつめ込み )
  1678. CALL FIFO_SD_GET ; ファイル読み込み
  1679. CALL PLAY_PUT_BUF ; FIFOに詰め込み
  1680. DECFSZ PLAY_DATAS, F ; 読み込み数カウント
  1681. GOTO INT_T0_DELTA_SEND_MIDI
  1682.  
  1683. BCF F_PLAY_DELTA ; デルタ処理終了
  1684. GOTO INT_T0 ; すぐさま次のデータを処理
  1685.  
  1686. INT_T0_READ_NEXT ; 次のデータへ
  1687. CALL FIFO_SD_GET ; 1バイト読み込み
  1688. MOVWF PLAY_BUF ; バッファへ退避
  1689.  
  1690. INT_T0_READ_MIDI ; MIDIデータ
  1691. ANDLW B'10000000' ; MIDIかチェック
  1692. BTFSS STATUS, Z
  1693. GOTO INT_T0_READ_TEMPO ; 違った
  1694.  
  1695. MOVF PLAY_BUF, W ; バッファ取り出し
  1696. ANDLW 0xF0 ; 上位取り出し
  1697. MOVWF PLAY_DELTAS ; デルタ数に保存
  1698. BCF STATUS, C ; フラグクリア
  1699. RRF PLAY_DELTAS, F ; 4bitシフト
  1700. RRF PLAY_DELTAS, F
  1701. RRF PLAY_DELTAS, F
  1702. RRF PLAY_DELTAS, F
  1703.  
  1704. MOVF PLAY_BUF, W ; バッファ取り出し
  1705. ANDLW 0x0F ; 下位取り出し
  1706. MOVWF PLAY_DATAS ; データ数保存
  1707.  
  1708. CLRF PLAY_D_3 ; デルタクリア
  1709. CLRF PLAY_D_2
  1710. CLRF PLAY_D_1
  1711. CLRF PLAY_D_0
  1712.  
  1713. MOVLW PLAY_D_0 ; FSR経由でデルタ保存
  1714. MOVWF PLAY_D_BUF ; D_BUFをFSRに利用
  1715. INT_T0_READ_MIDI_DELTA_L
  1716. CALL FIFO_SD_GET ; 1バイト読み込み
  1717. MOVWF PLAY_BUF ; バッファへ
  1718. BCF STATUS, IRP ; BANK0-1
  1719. MOVF PLAY_D_BUF, W ; FSR読み出し
  1720. MOVWF FSR ; FSR設定
  1721. MOVF PLAY_BUF, W ; バッファ取り出し
  1722. MOVWF INDF ; FSR経由で書きこみ
  1723. INCF PLAY_D_BUF, F ; アドレスインクリメント
  1724. DECFSZ PLAY_DELTAS, F ; DELTA分よんだ?
  1725. GOTO INT_T0_READ_MIDI_DELTA_L; くりかえし
  1726.  
  1727. BSF F_PLAY_DELTA ; デルタ処理開始
  1728. GOTO INT_T0 ; すぐさま割り込みへ戻る
  1729.  
  1730. INT_T0_READ_TEMPO ; テンポ情報だった
  1731. MOVF PLAY_BUF, W ; バッファを取り出し
  1732. SUBLW 0xFE ; テンポ?
  1733. BTFSS STATUS, Z ;
  1734. GOTO INT_T0_READ_END ; 違った
  1735. CALL FIFO_SD_GET ; 次の1バイト取得
  1736. MOVWF PLAY_TEMPO ; テンポ情報保存
  1737. GOTO INT_T0 ; テンポ情報の場合はすぐさま次を読む
  1738.  
  1739. INT_T0_READ_END ; 終了だった
  1740. CALL PLAY_STOP ; 停止
  1741. ;BCF F_PLAY_PLAY ; 再生停止 ( CALL節約でここに書いた )
  1742. ;BCF INTCON, T0IE ; T0I禁止
  1743. ;BCF F_FIFO_SD_EN ; ディセーブル ( この時点でSPIが必ず開始しているので、割り込み側で終了させる )
  1744. GOTO INT_T0_OUT ; 脱出
  1745.  
  1746. INT_T0_OUT ; INTT0終了
  1747. BCF INTCON, T0IF ; 割り込みフラグ解除
  1748. GOTO INT_CHECK ; POP
  1749.  
  1750. INT_TX ; 送信完了割り込み
  1751. BTFSS F_PLAY_SEND ; 送信中フラグがたってなければPOPする
  1752. GOTO INT_TX_OUT ; 脱出
  1753.  
  1754. INT_TX_SEND ; 送信開始
  1755. BSF STATUS, IRP ; BANK2-3
  1756. DECF PLAY_COUNT, F ; 送信した分減らすした分減らす
  1757. MOVF PLAY_FSR_S, W ; 送信位置を読み込み
  1758. MOVF PLAY_FSR_S, W ; 送信位置を読み込み
  1759. MOVWF FSR ; FSR設定
  1760. INCF PLAY_FSR_S, F ; 送信位置インクリメント
  1761. MOVF PLAY_FSR_S, W ; バッファを飛び出していないかチェック
  1762. SUBLW PLAY_FSR_END ; 終点 + 1を引く
  1763. BTFSS STATUS, Z
  1764. GOTO INT_TX_SEND_SEND ; 送信部へ
  1765. MOVLW PLAY_FSR_START ; バッファの最初へ
  1766. MOVWF PLAY_FSR_S ; 送信位置再設定
  1767.  
  1768. INT_TX_SEND_SEND
  1769. MOVF INDF, W ; 1バイト読み込み
  1770. MOVWF TXREG ; 送信 ( TXIF解除 )
  1771.  
  1772. MOVF PLAY_COUNT, F ; 個数0になった?
  1773. BTFSS STATUS, Z ; ゼロ?
  1774. GOTO INT_TX_OUT ; ゼロではないので脱出
  1775. MOVLW PLAY_FSR_START ; FSR初期値再設定
  1776. MOVWF PLAY_FSR ; 初期化
  1777. MOVWF PLAY_FSR_S
  1778. BCF F_PLAY_SEND ; 送信中解除
  1779. BSF STATUS, RP0 ; BANK1へ
  1780. BCF PIE1, TXIE ; TX割り込み停止
  1781. BCF STATUS, RP0 ; BANK0へ
  1782. GOTO INT_TX_OUT ; 送信完了
  1783.  
  1784. INT_TX_OUT ; 割り込み終了
  1785. GOTO POP ; POP
  1786.  
  1787. INT_SPI ; SPI用割り込み
  1788. BTFSS F_FIFO_SD_EN ; イネーブル?
  1789. GOTO L_INT_SPI_DISABLE ; ディセーブルする
  1790.  
  1791. CALL FILE_READ_FIFO ; 受信データ取り出し ( 動くか心配 )
  1792. MOVWF FIFO_SD_BUF ; バッファへ
  1793. BSF STATUS, IRP ; BANK2-3
  1794. MOVF FIFO_SD_W, W ; 書き込みFSRロード
  1795. MOVWF FSR ; FSR設定
  1796. MOVF FIFO_SD_BUF, W
  1797. MOVWF INDF ; バッファへ書き込み
  1798.  
  1799. INCF FIFO_SD_W, F ; FSR加算
  1800. MOVF FIFO_SD_W, W ; FSRが飛び出してないかチェック
  1801. SUBLW FIFO_SD_END ; 終了アドレス + 1
  1802. BTFSS STATUS, Z ; 飛び出してた?
  1803. GOTO $ + D'3' ; 飛び出してなかった
  1804. MOVLW FIFO_SD_START ; 開始地点
  1805. MOVWF FIFO_SD_W ; 設定
  1806.  
  1807. INCF FIFO_SD_C, F ; たまり具合カウント
  1808. MOVF FIFO_SD_C, W ; 溜まりきったかチェック
  1809. SUBLW FIFO_SD_SIZE ; サイズを引く
  1810. BTFSC STATUS, Z ; 溜まりきってた?
  1811. GOTO L_INT_SPI_STOP ; 溜まりきってたので停止させる
  1812.  
  1813. MOVLW 0FFH ; 適当なデータ
  1814. MOVWF SSPBUF ; 通信開始
  1815.  
  1816. GOTO INT_SPI_EXIT ; 脱出
  1817.  
  1818. L_INT_SPI_STOP ; 受信停止
  1819. BCF F_FIFO_SD_START ; 停止
  1820. GOTO INT_SPI_EXIT ; 脱出
  1821.  
  1822. L_INT_SPI_DISABLE ; バッファ貯めこみ中止 ( 今は使っていない = 廃止してもOK )
  1823. CALL FILE_READ_FIFO ; 読み込み
  1824. CALL FILE_READ_STOP ; 読み込み停止
  1825.  
  1826. BCF F_FIFO_SD_START ; 停止
  1827. BSF STATUS, RP0 ; BANK1へ
  1828. BCF PIE1, SSPIE ; SSPI停止
  1829. BCF STATUS, RP0 ; BANK0へ
  1830.  
  1831. GOTO INT_SPI_EXIT ; 脱出
  1832.  
  1833. INT_SPI_EXIT
  1834. BCF PIR1, SSPIF ; 割り込みフラグ解除
  1835. GOTO INT_CHECK ; 脱出
  1836.  
  1837. POP MOVF TMP_FSR, W ; FSR復帰
  1838. MOVWF FSR
  1839. MOVF TMP_PCLATH, W ; PCLATH復帰
  1840. MOVWF PCLATH
  1841. SWAPF TMP_STATUS, W ; STATUS復帰
  1842. MOVWF STATUS
  1843. SWAPF TMP_W, F ; Wreg退避準備 ( STATUSに影響を与えないよう、SWAPをかます )
  1844. SWAPF TMP_W, W ; Wreg復帰
  1845. RETFIE ; 割り込みから復帰
  1846.  
  1847. ; * キーボード制御 ************************************************************
  1848.  
  1849. KEY_TO_MIDI ; KEYからMIDIに
  1850. ADDLW MIDI_INI_NOTE ; 初期値加算
  1851. ADDWF MIDI_LMH, W ; オクターブ情報加算
  1852.  
  1853. RETURN
  1854.  
  1855. KEY_READ_AD ; ADC読み込み
  1856. MOVLW B'10000000' ; ADCON0初期値
  1857. IORLW B'00000001' ; AN0変換開始
  1858. MOVWF ADCON0 ; チャンネル0選択、使用開始
  1859. CALL TIME50 ; 50マイクロまつ
  1860. BSF ADCON0, GO ; 変換開始
  1861. BTFSC ADCON0, GO ; 変換終了した?
  1862. GOTO $ - D'1' ; まだ
  1863. MOVF ADRESH, W ; 結果取り出し
  1864. MOVWF MIDI_VELO ; ベロシティへ
  1865.  
  1866. MOVLW B'10000000' ; ADCON0初期値
  1867. IORLW B'00001001' ; AN1変換開始
  1868. MOVWF ADCON0 ; チャンネル1選択、使用開始
  1869. CALL TIME50 ; 50マイクロまつ
  1870. BSF ADCON0, GO ; 変換開始
  1871. BTFSC ADCON0, GO ; 変換終了した?
  1872. GOTO $ - D'1' ; まだ
  1873. MOVF ADRESH, W ; 結果取り出し
  1874. MOVWF MIDI_BEND ; BENDへ
  1875.  
  1876. MOVLW B'10000000' ; ADCON0初期値
  1877. IORLW B'00011001' ; AN3変換開始
  1878. MOVWF ADCON0 ; チャンネル3選択、使用開始
  1879. CALL TIME50 ; 50マイクロまつ
  1880. BSF ADCON0, GO ; 変換開始
  1881. BTFSC ADCON0, GO ; 変換終了した?
  1882. GOTO $ - D'1' ; まだ
  1883. MOVF ADRESH, W ; 結果取り出し
  1884. MOVWF MIDI_VOL ; ボリュームへ
  1885.  
  1886. RETURN
  1887.  
  1888. ; * MIDI制御 ******************************************************************
  1889.  
  1890. MIDI_SEND_BYTE ; 1Byte送信
  1891. CALL PLAY_PUT_BUF ; バッファへ詰め込み
  1892.  
  1893. RETURN
  1894.  
  1895. MIDI_SEND_STA_NOTE_ON ; NOTE-ON送信
  1896. MOVF MIDI_CH, W ; チャンネル読み出し
  1897. IORLW MIDI_STA_ON ; 命令作成
  1898. CALL MIDI_SEND_BYTE ; 送信
  1899.  
  1900. RETURN
  1901.  
  1902. MIDI_SEND_STA_NOTE_OFF ; NOTE-OFF送信
  1903. MOVF MIDI_CH, W ; チャンネル読み出し
  1904. IORLW MIDI_STA_OFF ; 命令作成
  1905. CALL PLAY_PUT_BUF ; バッファへ詰め込み
  1906.  
  1907. RETURN
  1908.  
  1909. MIDI_SEND_STA_BEND ; BEND送信
  1910. MOVF MIDI_CH, W ; チャンネル読み出し
  1911. IORLW MIDI_STA_BEND ; 命令作成
  1912. CALL PLAY_PUT_BUF ; バッファへ詰め込み
  1913.  
  1914. RETURN
  1915.  
  1916. MIDI_SEND_STA_CTRL ; CTRL送信
  1917. MOVF MIDI_CH, W ; チャンネル読み出し
  1918. IORLW MIDI_STA_CTRL ; 命令作成
  1919. CALL PLAY_PUT_BUF ; バッファへ詰め込み
  1920.  
  1921. RETURN
  1922.  
  1923. MIDI_SEND_STA_PROG ; PC送信
  1924. MOVF MIDI_CH, W ; チャンネル読み出し
  1925. IORLW MIDI_STA_PROG ; 命令作成
  1926. CALL PLAY_PUT_BUF ; バッファへ詰め込み
  1927.  
  1928. RETURN
  1929.  
  1930. ; * TOSTR *********************************************************************
  1931.  
  1932. TOSTR ; printf関数のようなもの
  1933. MOVWF TOSTR_BUF ; バッファへ退避
  1934. MOVLW 0x30 ; ASCIIコード初期値設定
  1935. MOVWF TOSTR_1 ; 初期値セット
  1936. MOVWF TOSTR_10
  1937. MOVWF TOSTR_100
  1938.  
  1939. L_TOSTR_CHECK_100 ; 100の位チェック
  1940. MOVLW D'100' ; 100ひく
  1941. SUBWF TOSTR_BUF, W ; Wに結果を
  1942. BTFSS STATUS, C ; Cが0で負の数
  1943. GOTO L_TOSTR_CHECK_10 ; 10の位へ
  1944. MOVWF TOSTR_BUF ; 結果をコピー繰り返し
  1945. INCF TOSTR_100, F ; 結果加算
  1946. GOTO L_TOSTR_CHECK_100 ; 繰り返し
  1947.  
  1948. L_TOSTR_CHECK_10 ; 10の位チェック
  1949. MOVLW D'10' ; 10ひく
  1950. SUBWF TOSTR_BUF, W ; Wに結果を
  1951. BTFSS STATUS, C ; Cが0で負の数
  1952. GOTO L_TOSTR_CHECK_1 ; 1の位へ
  1953. MOVWF TOSTR_BUF ; 結果をコピー繰り返し
  1954. INCF TOSTR_10, F ; 結果加算
  1955. GOTO L_TOSTR_CHECK_10 ; 繰り返し
  1956.  
  1957. L_TOSTR_CHECK_1 ; 1の位チェック
  1958. MOVLW D'1' ; 1ひく
  1959. SUBWF TOSTR_BUF, W ; Wに結果を
  1960. BTFSS STATUS, C ; Cが0で負の数
  1961. RETURN ; 終了
  1962. MOVWF TOSTR_BUF ; 結果をコピー繰り返し
  1963. INCF TOSTR_1, F ; 結果加算
  1964. GOTO L_TOSTR_CHECK_1 ; 繰り返し
  1965.  
  1966. ; * LCD ***********************************************************************
  1967.  
  1968. LCD_SEND
  1969. MOVWF LCD_BUF ; バッファにコピー
  1970.  
  1971. BSF LCD_RS ; ピンを設定
  1972. BCF LCD_RW
  1973.  
  1974. CALL LCD_SEND_4BIT ; 4bit送信
  1975. SWAPF LCD_BUF, W ; 下位だけ
  1976. CALL LCD_SEND_4BIT ; 4bit送信
  1977.  
  1978. CALL LCD_BUSY ; ビジーチェック
  1979.  
  1980. RETURN
  1981.  
  1982. LCD_SEND_4BIT ; Wの上位4bitを転送する
  1983. ANDLW 0F0H ; 上位だけ
  1984. MOVWF LCD_BUF4 ; バッファへ
  1985. MOVLW 0FH ; マスク
  1986. ANDWF PORTB, F ; 0000xxxx
  1987. MOVF LCD_BUF4, W ; 上位だけ
  1988. IORWF PORTB, F ; PORTBに設定
  1989.  
  1990. BSF LCD_E ; 送信
  1991. NOP
  1992. BCF LCD_E ; 完了
  1993.  
  1994. RETURN
  1995.  
  1996. LCD_INIT ; LCD初期化
  1997. CALL TIME10M
  1998. CALL TIME10M
  1999. CALL TIME10M
  2000. CALL TIME10M ; 40ms待つ ( 初期化に失敗する場合ここを調整 )
  2001.  
  2002. BCF LCD_RS ; ピンを設定
  2003. BCF LCD_RW ;
  2004.  
  2005. MOVLW 030H ; 8bitモードに設定
  2006. CALL LCD_SEND_4BIT ; 4bit送信
  2007.  
  2008. CALL TIME5M ; 5msまつ
  2009.  
  2010. BCF LCD_RS ; ピンを設定
  2011. BCF LCD_RW ;
  2012.  
  2013. MOVLW 030H ; 8bitモードに設定
  2014. CALL LCD_SEND_4BIT ; 4bit送信
  2015.  
  2016. CALL TIME100 ; 100μsまつ
  2017.  
  2018. BCF LCD_RS ; ピンを設定
  2019. BCF LCD_RW ;
  2020.  
  2021. MOVLW 030H ; 8bitモードに設定
  2022. CALL LCD_SEND_4BIT ; 4bit送信
  2023.  
  2024. CALL TIME100 ; 100μsまつ
  2025.  
  2026. BCF LCD_RS ; ピンを設定
  2027. BCF LCD_RW ;
  2028.  
  2029. MOVLW 020H ; 8bitモードに設定
  2030. CALL LCD_SEND_4BIT ; 4bit送信
  2031.  
  2032. CALL TIME100 ; 100μまつ、ここから4bitモード
  2033.  
  2034. MOVLW 02CH ; ファンクション
  2035. CALL LCD_CMD
  2036. MOVLW 08H ; ディスプレイOFF
  2037. CALL LCD_CMD
  2038. MOVLW 0CH ; ディスプレイON
  2039. CALL LCD_CMD
  2040. MOVLW 06H ; エントリ
  2041. CALL LCD_CMD
  2042.  
  2043. RETURN
  2044.  
  2045. LCD_CMD ; LCDにコマンドを送る ( W )
  2046. MOVWF LCD_BUF ; バッファにコピー
  2047.  
  2048. BCF LCD_RS ; ピンを設定 ( コマンドモード )
  2049. BCF LCD_RW ;
  2050.  
  2051. CALL LCD_SEND_4BIT ; 4bit送信
  2052.  
  2053. SWAPF LCD_BUF, W ; 下位転送
  2054.  
  2055. BCF LCD_RS ; ピンを設定 ( コマンドモード )
  2056. BCF LCD_RW ;
  2057.  
  2058. CALL LCD_SEND_4BIT ; 4bit送信
  2059.  
  2060. CALL LCD_BUSY ; 書き終わるまで待つ
  2061.  
  2062. RETURN
  2063.  
  2064. LCD_BUSY ; LCDがBUSYでなくなるまで帰ってこない
  2065. BCF STATUS, RP1 ; BANK1へ
  2066. BSF STATUS, RP0
  2067. MOVLW 0F0H ; PORTB4-7を入力へ
  2068. IORWF TRISB, F ; 入力設定
  2069. BCF STATUS, RP1 ; BANK0へ
  2070. BCF STATUS, RP0
  2071.  
  2072. BCF LCD_RS ; ピンを設定 ( ビジーチェック )
  2073. BSF LCD_RW ; 読み込みモード
  2074.  
  2075. LCD_BUSY_1
  2076. BSF LCD_E ; 上位を受信
  2077. NOP
  2078. MOVF PORTB, W ; WにPORTBを転送
  2079. BCF LCD_E ; 完了
  2080.  
  2081. ANDLW 0F0H ; 上位 ( 4 : 7 ) だけを残す
  2082. MOVWF LCD_BUF ; バッファに退避
  2083.  
  2084. BSF LCD_E ; 下位を受信
  2085. NOP
  2086. SWAPF PORTB, W ; WにPORTBをSWAPして転送
  2087. BCF LCD_E ; 完了
  2088.  
  2089. ANDLW 0FH ; 下位だけ残す
  2090.  
  2091. IORWF LCD_BUF, F ; 結合!
  2092.  
  2093. BTFSC LCD_BUF, 7 ; BUSYフラグある?
  2094. GOTO LCD_BUSY_1 ; あったら繰り返し
  2095.  
  2096. BCF LCD_RW ; 書き込みモード
  2097.  
  2098. BCF STATUS, RP1 ; BANK1へ
  2099. BSF STATUS, RP0
  2100.  
  2101. MOVLW 0FH ; PORTB4-7を出力へ
  2102. ANDWF TRISB, F ; 出力設定
  2103.  
  2104. BCF STATUS, RP1 ; BANK0へ
  2105. BCF STATUS, RP0
  2106.  
  2107. RETURN
  2108.  
  2109. LCD_CLR ; LCDをクリア
  2110. MOVLW LCD_CMD_CLR ; クリアして
  2111. CALL LCD_CMD
  2112.  
  2113. RETURN
  2114.  
  2115. LCD_CUR ; Wregにカーソルをセット
  2116. IORLW LCD_CMD_CUR ; コマンド作成
  2117. CALL LCD_CMD
  2118.  
  2119. RETURN
  2120.  
  2121. ; * MIDIプレーヤ **************************************************************
  2122.  
  2123. PLAY_PLAY ; 再生開始
  2124. BTFSC F_PLAY_PLAY ; 再生中?
  2125. RETURN ; 再生中なら戻る
  2126. BSF F_PLAY_PLAY ; 再生開始
  2127. BCF F_PLAY_DELTA ; デルタ処理中じゃない
  2128.  
  2129. CALL MMC_INIT ; MMC初期化
  2130.  
  2131. MOVF PLAY_CLS_0, W ; 読み出しセクタ設定
  2132. MOVWF MMC_ARG2 ; 設定
  2133. MOVF PLAY_CLS_1, W ; 読み出しセクタ設定
  2134. MOVWF MMC_ARG1 ; 設定
  2135. CLRF MMC_ARG
  2136. CLRF MMC_ARG3
  2137.  
  2138. CALL FILE_READ_START ; ファイル読み込み開始
  2139. CLRF FIFO_SD_C ; バッファクリア
  2140. MOVLW FIFO_SD_START ; 起点設定
  2141. MOVWF FIFO_SD_R
  2142. MOVWF FIFO_SD_W
  2143. BSF F_FIFO_SD_START ; 起動
  2144. BSF F_FIFO_SD_EN ; イネーブル
  2145. BCF PIR1, SSPIF ; SSPの割り込みフラグ解除
  2146. MOVLW 0FFH ; 即通信開始
  2147. MOVWF SSPBUF ; 開始
  2148.  
  2149. BCF INTCON, GIE ; 割り込み停止
  2150. BSF INTCON, T0IE ; T0割り込み許可
  2151. BSF STATUS, RP0 ; BANK1へ
  2152. MOVLW B'10000101' ; 内部クロック、1:64に設定
  2153. MOVWF OPTION_REG ; 設定
  2154. BSF PIE1, SSPIE ; SSP割り込み許可
  2155. BCF STATUS, RP0 ; BANK0へ
  2156.  
  2157. BSF INTCON, T0IF ; すぐ割り込みが発生するように設定
  2158. BSF INTCON, GIE ; 割り込み許可 ( すぐ発生 )
  2159.  
  2160. RETURN
  2161.  
  2162. PLAY_STOP ; 再生停止
  2163. BTFSS F_PLAY_PLAY ; 再生中?
  2164. RETURN ; 再生中じゃない
  2165. BCF F_PLAY_PLAY ; 再生停止
  2166.  
  2167. BCF INTCON, T0IE ; T0I禁止
  2168.  
  2169. BSF STATUS, RP0 ; BANK1へ
  2170. BCF PIE1, SSPIE ; SSP割り込み停止
  2171. BCF STATUS, RP0 ; BANK0へ
  2172.  
  2173. BCF PIR1, SSPIF ; 一応フラグ解除
  2174. BCF F_FIFO_SD_EN ; ディセーブル
  2175.  
  2176. BTFSS F_FIFO_SD_START ; 開始されてた
  2177. GOTO L_PLAY_STOP_END ; されてなかった
  2178. BSF STATUS, RP0 ; BANK1へ
  2179. BTFSS SSPSTAT, BF ; 受信中のデータがあれば待つ
  2180. GOTO $ - D'1'
  2181. BCF STATUS, RP0 ; BANK0へ
  2182. CALL FILE_READ_FIFO ; 一応受信
  2183. BCF F_FIFO_SD_START ; SD用FIFO停止
  2184.  
  2185. L_PLAY_STOP_END
  2186. CALL FILE_READ_STOP ; 読み込み停止
  2187.  
  2188. RETURN
  2189.  
  2190. PLAY_PUT_BUF ; FIFOバッファに詰め込む ( 割り込み禁止で使う前提 )
  2191. MOVWF PLAY_FIFO ; バッファに一時退避
  2192.  
  2193. MOVLW PLAY_FIFO_SIZE ; FIFOのたまり具合チェック
  2194. SUBWF PLAY_COUNT, W ; 現在の個数から引く
  2195. BTFSC STATUS, Z ; 満タン?
  2196. CALL PLAY_SEND_BUF_BYTE ; 満タンだったので1バイト送信してしまう ( うまくいくか不明 )
  2197. L_PLAY_PUT_BUF_PUT
  2198. BSF STATUS, IRP ; BANK2-3
  2199. MOVF PLAY_FSR, W ; 書込み先
  2200. MOVWF FSR ; FSR設定
  2201. MOVF PLAY_FIFO, W ; データ復帰
  2202. MOVWF INDF ; INDF経由で書き込み
  2203. INCF PLAY_COUNT, F ; 個数加算
  2204. INCF PLAY_FSR, F ; 書込み先加算
  2205. MOVF PLAY_FSR, W ; バッファが飛び出してないかチェック
  2206. SUBLW PLAY_FSR_END ; 終点 + 1を引く
  2207. BTFSS STATUS, Z ; ゼロですか?
  2208. GOTO L_PLAY_PUT_BUF_EXIT ; ゼロではなかったので終了
  2209. MOVLW PLAY_FSR_START ; バッファ起点設定
  2210. MOVWF PLAY_FSR ; 設定
  2211. L_PLAY_PUT_BUF_EXIT
  2212. BTFSC F_PLAY_SEND ; バッファ送信中?
  2213. RETURN ; 送信中だったのでそのまま続行
  2214. BSF F_PLAY_SEND ; 送信フラグを立てる
  2215. BSF STATUS, RP0 ; BANK1へ
  2216. BSF PIE1, TXIE ; TX開始
  2217. BCF STATUS, RP0 ; BANK0へ
  2218.  
  2219. RETURN ; 終了
  2220.  
  2221. PLAY_SEND_BUF_BYTE ; PLAY_SEND_BUFのGIE制御がない, 1バイト送信版
  2222. BSF STATUS, IRP ; BANK2-3
  2223. DECF PLAY_COUNT, F ; 送信した分減らす
  2224. MOVF PLAY_FSR_S, W ; 送信位置を読み込み
  2225. MOVWF FSR ; FSR設定
  2226. INCF PLAY_FSR_S, F ; 送信位置インクリメント
  2227. MOVF PLAY_FSR_S, W ; バッファを飛び出していないかチェック
  2228. SUBLW PLAY_FSR_END ; 終点 + 1を引く
  2229. BTFSS STATUS, Z
  2230. GOTO L_PLAY_SEND_BUF_B_SEND ; 送信部へ
  2231. MOVLW PLAY_FSR_START ; バッファの最初へ
  2232. MOVWF PLAY_FSR_S ; 送信位置再設定
  2233.  
  2234. L_PLAY_SEND_BUF_B_SEND
  2235. BSF STATUS, RP0 ; BANK1に ( MIDI関数をCALLせず直接書いた )
  2236. BTFSS TXSTA, TRMT ; ビジー?
  2237. GOTO $ - D'1' ; ビジー解除を待つ
  2238. BCF STATUS, RP0 ; BANK0へ
  2239. MOVF INDF, W ; 1バイト読み込み
  2240. MOVWF TXREG ; 送信
  2241.  
  2242. MOVF PLAY_COUNT, F ; 個数0になった?
  2243. BTFSS STATUS, Z ; ゼロ?
  2244. RETURN ; ゼロではなかったので終了
  2245. MOVLW PLAY_FSR_START ; FSR初期値再設定
  2246. MOVWF PLAY_FSR ; 初期化
  2247. MOVWF PLAY_FSR_S
  2248. BCF F_PLAY_SEND ; 送信中解除
  2249. BSF STATUS, RP0 ; BANK1へ
  2250. BCF PIE1, TXIE ; TX停止
  2251. BCF STATUS, RP0 ; BANK0へ
  2252.  
  2253. RETURN
  2254.  
  2255. ; * SD用FIFO ( PLAYと連動用 ) *************************************************
  2256.  
  2257. FIFO_SD_GET ; FIFOから1バイト取得
  2258. MOVF FIFO_SD_C, W ; バッファに溜まっているかチェック
  2259. BTFSC STATUS, Z ; ゼロ?
  2260. GOTO L_FIFO_SD_GET_ZERO ; たまってなかった
  2261.  
  2262. DECF FIFO_SD_C, F ; 個数減らす
  2263. BSF STATUS, IRP ; BANK2-3
  2264. MOVF FIFO_SD_R, W ; 読み込み先をFSRへ
  2265. MOVWF FSR ; FSR設定
  2266. MOVF INDF, W ; バッファ取り出し
  2267. MOVWF FIFO_SD_BUF ; 保存
  2268. INCF FIFO_SD_R, F ; 読み込み先加算
  2269. MOVF FIFO_SD_R, W ; オーバーしてるかチェック
  2270. SUBLW FIFO_SD_END ; バッファ終点 + 1か
  2271. BTFSS STATUS, Z ; ゼロ?
  2272. GOTO $ + D'3' ; ゼロじゃなかった
  2273. MOVLW FIFO_SD_START ; 起点設定
  2274. MOVWF FIFO_SD_R
  2275.  
  2276. BTFSC F_FIFO_SD_START ; 開始されてる?
  2277. GOTO L_FIFO_SD_GET_RET ; されてたので終了
  2278.  
  2279. BSF F_FIFO_SD_START ; 起動
  2280. BCF PIR1, SSPIF ; フラグ一応解除
  2281. MOVLW 0FFH ; 通信開始
  2282. MOVWF SSPBUF ; 今度は割り込みを使って通信
  2283.  
  2284. L_FIFO_SD_GET_RET
  2285. MOVF FIFO_SD_BUF, W ; 取り出し
  2286. RETURN
  2287.  
  2288. L_FIFO_SD_GET_ZERO ; 開始してるけどたまってない
  2289. MOVLW FIFO_SD_START ; バッファ位置初期化
  2290. MOVWF FIFO_SD_R
  2291. MOVWF FIFO_SD_W
  2292.  
  2293. BSF STATUS, RP0 ; BANK1へ
  2294. BTFSS SSPSTAT, BF
  2295. GOTO $ - D'1'
  2296. BCF STATUS, RP0 ; BANK0へ
  2297.  
  2298. L_FIFO_SD_FILE_READ_FIFO ; FIFO用に使うREAD ( CALL節約用にコピー )
  2299. BTFSS F_FILE_START ; 読み込み中?
  2300. RETURN ; 違ったので終了
  2301.  
  2302. MOVF SSPBUF, W ; 送受信
  2303. MOVWF FILE_RECV ; 受信バッファへコピー
  2304.  
  2305. INCF FILE_BYTES, F ; 受信カウンタ加算
  2306. BTFSS STATUS, Z ; フロー?
  2307. GOTO L_FIFO_SD_FILE_READ_COMP; 読み込み完了
  2308. BTFSC FILE_BYTES1, 0 ; すでに256読んでいた?
  2309. GOTO L_FIFO_SD_FILE_READ_END ; 読み込み終了
  2310. INCF FILE_BYTES1, F ; 上位バイト加算
  2311. GOTO L_FIFO_SD_FILE_READ_COMP; 読み込み完了
  2312.  
  2313. L_FIFO_SD_FILE_READ_END ; 読み込み終了
  2314. CALL MMC_READ_FOOT ; フッター送信
  2315.  
  2316. INCF MMC_ARG2, F ; 次のセクターへ
  2317. BTFSC STATUS, Z ; フローした?
  2318. INCF MMC_ARG1, F
  2319. INCF MMC_ARG2, F
  2320. BTFSC STATUS, Z ; フローした?
  2321. INCF MMC_ARG1, F
  2322.  
  2323. CLRF FILE_BYTES ; 使う変数を初期化 ( 読み込み再開 )
  2324. CLRF FILE_BYTES1
  2325.  
  2326. CALL MMC_READ_HEAD ; 読み込み開始
  2327. L_FIFO_SD_FILE_READ_COMP ; 読み込み完了
  2328. MOVF FILE_RECV, W ; 読み込みデータをWregに
  2329. MOVWF FIFO_SD_BUF ; バッファへ
  2330.  
  2331. BCF PIR1, SSPIF ; 割り込みフラグ解除
  2332. MOVLW 0FFH ; 通信再開
  2333. MOVWF SSPBUF ; 通信
  2334.  
  2335. MOVF FIFO_SD_BUF, W ; 取り出し
  2336. RETURN
  2337.  
  2338. ; * ファイルアクセス ( 連続改変版 ) *******************************************
  2339.  
  2340. FILE_READ_STOP ; ファイル読み込みを初期化 ( 先頭ファイルの先頭バイトへ )
  2341. BTFSS F_FILE_START ; 読み込み中?
  2342. RETURN ; 違ったので終了
  2343. BCF F_FILE_START ; 読み込みフラグ解除
  2344.  
  2345. MOVLW 0FFH ; 読み込み開始 ( 送信は適当に0FFH )
  2346. CALL SPI_START ; 実行
  2347. INCF FILE_BYTES, F ; リードカウンタ加算
  2348. BTFSS STATUS, Z ; フロー?
  2349. GOTO $ - D'4' ; フローしてなかったので繰り返し
  2350. BTFSC FILE_BYTES1, 0 ; すでに256読み込んでいた ( 00000001 )
  2351. GOTO L_FILE_READ_STOP_1 ; 読み込み完了
  2352. INCF FILE_BYTES1, F ; 上位バイト加算
  2353. GOTO $ - D'8'
  2354. L_FILE_READ_STOP_1 ; 読み込み完了
  2355. CALL MMC_READ_FOOT ; フッター送信
  2356.  
  2357. RETURN
  2358.  
  2359. FILE_READ_SET_START ; ( 改変 ) ファイル読み込み開始セクタ指定
  2360. MOVWF MMC_ARG2 ; 引数設定
  2361. CLRF MMC_ARG
  2362. CLRF MMC_ARG1
  2363. CLRF MMC_ARG3
  2364.  
  2365. RETURN
  2366.  
  2367. FILE_READ_START ; ( 改変 )読み込み開始関数
  2368. BTFSC F_FILE_START ; 読み込み中?
  2369. RETURN ; だったので終了
  2370. BSF F_FILE_START ; 読み込みフラグセット
  2371.  
  2372. CLRF FILE_BYTES ; 使う変数を初期化
  2373. CLRF FILE_BYTES1
  2374.  
  2375. CALL MMC_READ_HEAD ; 読み込み開始
  2376.  
  2377. RETURN
  2378.  
  2379. FILE_READ ; ファイルから1バイト読み込んで、Wregに送る
  2380. BTFSS F_FILE_START ; 読み込み中?
  2381. RETURN ; 違ったので終了
  2382.  
  2383. MOVLW 0FFH ; 受信中には適当な値を送る
  2384. CALL SPI_START ; 送受信
  2385. MOVWF FILE_RECV ; 受信バッファへコピー
  2386.  
  2387. INCF FILE_BYTES, F ; 受信カウンタ加算
  2388. BTFSS STATUS, Z ; フロー?
  2389. GOTO L_FILE_READ_COMP ; 読み込み完了
  2390. BTFSC FILE_BYTES1, 0 ; すでに256読んでいた?
  2391. GOTO L_FILE_READ_END ; 読み込み終了
  2392. INCF FILE_BYTES1, F ; 上位バイト加算
  2393. GOTO L_FILE_READ_COMP ; 読み込み完了
  2394. L_FILE_READ_END ; 読み込み終了
  2395. CALL MMC_READ_FOOT ; フッター送信
  2396.  
  2397. INCF MMC_ARG2, F ; 次のセクターへ
  2398. BTFSC STATUS, Z ; フローした?
  2399. INCF MMC_ARG1, F
  2400. INCF MMC_ARG2, F
  2401. BTFSC STATUS, Z ; フローした?
  2402. INCF MMC_ARG1, F
  2403.  
  2404. CLRF FILE_BYTES ; 使う変数を初期化 ( 読み込み再開 )
  2405. CLRF FILE_BYTES1
  2406.  
  2407. CALL MMC_READ_HEAD ; 読み込み開始
  2408. L_FILE_READ_COMP ; 読み込み完了
  2409. MOVF FILE_RECV, W ; 読み込みデータをWregに
  2410.  
  2411. RETURN
  2412.  
  2413. FILE_READ_FIFO ; FIFO用に使うREAD ( 一部分改変して利用 )
  2414. BTFSS F_FILE_START ; 読み込み中?
  2415. RETURN ; 違ったので終了
  2416.  
  2417. MOVF SSPBUF, W ; 送受信
  2418. MOVWF FILE_RECV ; 受信バッファへコピー
  2419.  
  2420. INCF FILE_BYTES, F ; 受信カウンタ加算
  2421. BTFSS STATUS, Z ; フロー?
  2422. GOTO L_FILE_READ_COMP ; 読み込み完了
  2423. BTFSC FILE_BYTES1, 0 ; すでに256読んでいた?
  2424. GOTO L_FILE_READ_END ; 読み込み終了
  2425. INCF FILE_BYTES1, F ; 上位バイト加算
  2426. GOTO L_FILE_READ_COMP ; 読み込み完了
  2427.  
  2428. ; * SPI通信ルーチン ***********************************************************
  2429.  
  2430. SPI_INIT ; CLK初期化
  2431. MOVLW B'00110000' ; CKP = 1でSPI起動)
  2432. MOVWF SSPCON
  2433. BSF STATUS, RP0 ; BANK1へ
  2434. MOVLW B'10000001' ; SMP = 1, CKE = 0
  2435. MOVWF SSPSTAT
  2436. BCF STATUS, RP0 ; BANK0へ
  2437.  
  2438. RETURN ; 完了
  2439.  
  2440. SPI_START ; 通信を開始する。
  2441. MOVWF SSPBUF ; 送受信開始
  2442. BSF STATUS, RP0 ; BANK1へ
  2443. BTFSS SSPSTAT, BF
  2444. GOTO $ - D'1'
  2445. BCF STATUS, RP0 ; BANK0へ
  2446. MOVF SSPBUF, W ; 受信
  2447.  
  2448. RETURN ; 完了
  2449.  
  2450. ; * MMC制御ルーチン ( CALL軽量版 ) ********************************************
  2451.  
  2452. MMC_INIT ; MMCを初期化
  2453. CLRF MMC_ARG ; 引数を初期化
  2454. CLRF MMC_ARG1
  2455. CLRF MMC_ARG2
  2456. CLRF MMC_ARG3
  2457.  
  2458. CALL SPI_INIT ; SPI初期化
  2459.  
  2460. BSF MMC_CS ; CSをHに ( 開放 )
  2461.  
  2462. BSF SSPCON, SSPM1 ; Fosc/64に
  2463. BCF SSPCON, SSPM0
  2464.  
  2465. MOVLW D'20' ; 80クロック以上送る
  2466. MOVWF MMC_CNT1 ; カウンタへ
  2467.  
  2468. MOVLW 0FFH ; とりあえずFを送る
  2469. CALL SPI_START ; 送信
  2470. DECFSZ MMC_CNT1, F ; 80回送った?
  2471. GOTO $ - 3
  2472.  
  2473. BCF MMC_CS ; CSをLに ( 選択 )
  2474.  
  2475. MOVLW MMC_CMD_0 ; コマンド0送信
  2476. CALL MMC_SEND_COMMAND
  2477. CALL MMC_WAIT_RESP ; R1をまつ ( 失敗しない前提 )
  2478.  
  2479. MOVLW 0FFH ; 1回ダミーを送る
  2480. CALL SPI_START
  2481.  
  2482. MOVLW MMC_CMD_55 ; SDかチェック
  2483. CALL MMC_SEND_COMMAND
  2484. CALL MMC_WAIT_RESP
  2485.  
  2486. MOVLW 0FFH ; 1回ダミーを送る
  2487. CALL SPI_START
  2488.  
  2489. MOVLW MMC_CMD_41 ; SDかチェック
  2490. CALL MMC_SEND_COMMAND
  2491. CALL MMC_WAIT_RESP
  2492.  
  2493. MOVWF MMC_BUF1 ; バッファへ退避
  2494.  
  2495. SUBLW 01H ; SDだったか?
  2496. BTFSC STATUS, Z
  2497. GOTO $ - D'11'
  2498.  
  2499. MOVF MMC_BUF1, W ; Wregへ復帰
  2500.  
  2501. SUBLW 00H
  2502. BTFSC STATUS, Z
  2503. GOTO MMCICMPLT ; SDでしかも初期化完了
  2504.  
  2505. MOVLW 0FFH ; 1回ダミーを送る
  2506. CALL SPI_START
  2507.  
  2508. MOVLW MMC_CMD_1 ; コマンド1送信
  2509. CALL MMC_SEND_COMMAND
  2510. CALL MMC_WAIT_RESP ; R1を待つ
  2511. SUBLW 00H ; 0か調べる
  2512. BTFSS STATUS, Z
  2513. GOTO $ - D'7' ; 0になってないので再送信
  2514.  
  2515. ;BCF SSPCON, SSPM1 ; Fosc/16に ( 今のところこれ以上でない )
  2516. ;BSF SSPCON, SSPM0 ; DEBUG
  2517.  
  2518. MMCICMPLT
  2519. MOVLW 0FFH ; 1回ダミーを送る
  2520. CALL SPI_START
  2521.  
  2522. MOVLW D'2' ; ブロックを512に指定
  2523. MOVWF MMC_ARG2 ; 引数に設定
  2524. MOVLW MMC_CMD_16
  2525. CALL MMC_SEND_COMMAND
  2526.  
  2527. CALL MMC_WAIT_RESP
  2528.  
  2529. MOVLW 0FFH ; 1回ダミーを送る
  2530. CALL SPI_START
  2531.  
  2532. BSF MMC_CS ; 開放
  2533.  
  2534. RETURN ; 戻る
  2535.  
  2536. MMC_DUMY ; ダミー送信
  2537. MOVLW 0FFH
  2538. CALL SPI_START
  2539.  
  2540. RETURN
  2541.  
  2542. MMC_WAIT_RESP ; レスポンス待ち関数
  2543. MOVLW 0FFH ; 0FFHを送る
  2544. CALL SPI_START ; 送受信
  2545. MOVWF MMC_BUF2 ; 退避
  2546. SUBLW 0FFH ; 0FFHか調べる
  2547. BTFSC STATUS, Z ; ゼロになった?
  2548. GOTO $ - D'5' ; もう一度待つ
  2549. MOVF MMC_BUF2, W ; 受信できたものをWregに
  2550.  
  2551. RETURN
  2552.  
  2553. MMC_WRITE_HEAD ; 書き込み用ヘッダ
  2554. BCF MMC_CS ; 選択
  2555.  
  2556. MOVLW 0FFH ; 1回ダミーを送る
  2557. CALL SPI_START
  2558.  
  2559. MOVLW MMC_CMD_24 ; シングルブロックライト
  2560. CALL MMC_SEND_COMMAND
  2561.  
  2562. CALL MMC_WAIT_RESP ; レスポンス待ち
  2563.  
  2564. MOVLW 0FFH ; 1バイト空ける
  2565. CALL SPI_START
  2566.  
  2567. MOVLW B'11111110' ; データトークン開始
  2568. CALL SPI_START
  2569.  
  2570. RETURN ; 戻る
  2571.  
  2572. MMC_WRITE_FOOT ; 書き込み用フッタ
  2573. MOVLW 00H ; 適当にCRC送信
  2574. CALL SPI_START
  2575. MOVLW 00H
  2576. CALL SPI_START
  2577.  
  2578. CALL MMC_WAIT_RESP ; レスポンス待ち
  2579.  
  2580. MOVLW 0FFH ; busy解除をまつ
  2581. CALL SPI_START
  2582. SUBLW 0FFH ; FFになった?
  2583. BTFSS STATUS, Z
  2584. GOTO $ - D'4'
  2585.  
  2586. MOVLW 0FFH ; 1回ダミーを送る
  2587. CALL SPI_START
  2588.  
  2589. BSF MMC_CS ; 開放
  2590.  
  2591. RETURN
  2592.  
  2593. MMC_READ_HEAD ; シングルリード時のヘッダ
  2594. BCF MMC_CS ; 選択
  2595.  
  2596. MOVLW 0FFH ; 1回ダミーを送る
  2597. CALL SPI_START
  2598.  
  2599. MOVLW MMC_CMD_17 ; シングルブロックリード
  2600. CALL MMC_SEND_COMMAND
  2601.  
  2602. CALL MMC_WAIT_RESP ; レスポンス待ち
  2603.  
  2604. CALL MMC_WAIT_RESP ; トークン待ち(なんでもいい無視)
  2605.  
  2606. RETURN
  2607.  
  2608. MMC_READ_FOOT ; シングルリード時のフッタ
  2609. MOVLW 0FFH ; CRC受信 ( 2Bytes )
  2610. CALL SPI_START
  2611. MOVLW 0FFH
  2612. CALL SPI_START
  2613.  
  2614. MOVLW 0FFH ; 1回ダミーを送る
  2615. CALL SPI_START
  2616.  
  2617. BSF MMC_CS ; 開放
  2618.  
  2619. RETURN
  2620.  
  2621. MMC_READ_STOP ; 読み込み強制停止
  2622. MOVLW 0FFH ; 1回ダミーを送る
  2623. CALL SPI_START
  2624.  
  2625. MOVLW MMC_CMD_12 ; 読み込み停止
  2626. CALL MMC_SEND_COMMAND
  2627.  
  2628. CALL MMC_WAIT_RESP ; レスポンス待ち
  2629.  
  2630. MOVLW 0FFH ; busy解除をまつ
  2631. CALL SPI_START
  2632. SUBLW 0FFH ; FFになった?
  2633. BTFSS STATUS, Z
  2634. GOTO $ - D'4'
  2635.  
  2636. MOVLW 0FFH ; 1回ダミーを送る
  2637. CALL SPI_START
  2638.  
  2639. RETURN
  2640.  
  2641. MMC_SEND_COMMAND ; MMCにコマンド送信
  2642. IORLW B'01000000' ; コマンド作成
  2643. CALL SPI_START ; 送信
  2644.  
  2645. MOVF MMC_ARG, W ; 引数コピー
  2646. CALL SPI_START ; 送信
  2647.  
  2648. MOVF MMC_ARG1, W
  2649. CALL SPI_START ; 送信
  2650.  
  2651. MOVF MMC_ARG2, W
  2652. CALL SPI_START ; 送信
  2653.  
  2654. MOVF MMC_ARG3, W
  2655. CALL SPI_START ; 送信
  2656.  
  2657. MOVLW MMC_CRC_CMD0 ; CRC送信
  2658. CALL SPI_START ; 送信
  2659.  
  2660. RETURN ; 戻る
  2661.  
  2662. ; * ディレイ集 ****************************************************************
  2663.  
  2664. TIME1 ; 1μ秒 : 5ステップ
  2665. NOP ; 2 + 1
  2666. RETURN ; 2
  2667.  
  2668. TIME10 ; 10μ秒 : 50ステップ
  2669. MOVLW D'15'
  2670. MOVWF CNT1
  2671. DECFSZ CNT1, F
  2672. GOTO $ - 1
  2673. RETURN
  2674.  
  2675. TIME50 ; 50μ秒 : 250ステップ
  2676. NOP ; +1
  2677. NOP ; +1
  2678. MOVLW D'81'
  2679. MOVWF CNT1
  2680. DECFSZ CNT1, F
  2681. GOTO $ - 1
  2682. RETURN
  2683.  
  2684. TIME100 ; 100μ秒 : 500ステップ
  2685. MOVLW D'165'
  2686. MOVWF CNT1
  2687. DECFSZ CNT1, F
  2688. GOTO $ - 1
  2689. RETURN
  2690.  
  2691. TIME1M ; 1m秒 : 5000ステップ ( 補正項なしで5035 )
  2692. NOP ; 補正項開始
  2693. NOP
  2694. NOP
  2695. MOVLW D'154'
  2696. MOVWF CNT2
  2697. DECFSZ CNT2, F
  2698. GOTO $ - 1
  2699. NOP
  2700. NOP ; 補正項終わり
  2701. MOVLW D'9'
  2702. MOVWF CNT3
  2703. T_LP1 CALL TIME100
  2704. DECFSZ CNT3, F
  2705. GOTO T_LP1
  2706. RETURN
  2707.  
  2708. TIME5M ; 5m秒 ( 約 )
  2709. CALL TIME1M
  2710. CALL TIME1M
  2711. CALL TIME1M
  2712. CALL TIME1M
  2713. CALL TIME1M
  2714. RETURN
  2715.  
  2716. TIME10M ; 10m秒 ( 約 )
  2717. CALL TIME5M
  2718. CALL TIME5M
  2719. RETURN
  2720.  
  2721. TIME05S ; 0.5秒 ( 約 )
  2722. MOVLW D'50'
  2723. MOVWF CNT4
  2724. T_LP2 CALL TIME10M
  2725. DECFSZ CNT4, F
  2726. GOTO T_LP2
  2727. RETURN
  2728.  
  2729. ; * FAT12ルーチン *************************************************************
  2730.  
  2731. ORG 0x700 ; テーブル用に書き込み場所を変更 ( PAGE0の最後の256バイト )
  2732. T_GET_BOOTSECTOR ; ブートセクタの最初の部分 ( BANK0で実行前提 )
  2733. MOVLW 07H ; テーブルは0700H以降にあり
  2734. MOVWF PCLATH ; PCLATH設定
  2735.  
  2736. MOVF PG_POINT1, W ; 今の位置をWregへ
  2737. ADDWF PCL ,F ; PC書き換え
  2738.  
  2739. TABLE1 RETLW 0EBH ; テーブルルックアップ
  2740. RETLW 04EH
  2741. RETLW 090H
  2742. RETLW 'N'
  2743. RETLW 'O'
  2744. RETLW ' '
  2745. RETLW 'N'
  2746. RETLW 'A'
  2747. RETLW 'M'
  2748. RETLW 'E'
  2749. RETLW ' '
  2750. RETLW 00H
  2751. RETLW 02H
  2752. RETLW 01H
  2753. RETLW 01H
  2754. RETLW 00H
  2755. RETLW 02H
  2756. RETLW 0E0H
  2757. RETLW 00H
  2758. RETLW B'01000000'
  2759. RETLW B'00001011'
  2760. RETLW 0F0H
  2761. RETLW 09H
  2762. RETLW 00H
  2763. RETLW D'18'
  2764. RETLW 00H
  2765. RETLW 02H
  2766. RETLW 00H
  2767. RETLW 00H
  2768. RETLW 00H
  2769. RETLW 00H
  2770. RETLW 00H
  2771. RETLW B'01000000'
  2772. RETLW B'00001011'
  2773. RETLW 00H
  2774. RETLW 00H
  2775. RETLW 00H
  2776. RETLW 00H
  2777. RETLW 029H
  2778. RETLW 0FFH
  2779. RETLW 0FFH
  2780. RETLW 0FFH
  2781. RETLW 0FFH
  2782. RETLW 'P'
  2783. RETLW 'I'
  2784. RETLW 'C'
  2785. RETLW '-'
  2786. RETLW 'F'
  2787. RETLW 'A'
  2788. RETLW 'T'
  2789. RETLW ' '
  2790. RETLW ' '
  2791. RETLW ' '
  2792. RETLW ' '
  2793. RETLW 'F'
  2794. RETLW 'A'
  2795. RETLW 'T'
  2796. RETLW '1'
  2797. RETLW '2'
  2798. RETLW ' '
  2799. RETLW ' '
  2800. RETLW ' '
  2801.  
  2802. ; *****************************************************************************
  2803.  
  2804. END ; おわり
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement