$prog &HFF , &H62 , &HD9 , &HFF 'ヒューズ設定。(ATmega328P工場出荷状態) ' ' ********************************************** ' * チャレンジ 5 ゲーム * ' * * ' * AVR is using ATmega328P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright By O-Family 2014.10. 9 * ' ********************************************** ' ' Ver 0.16 テスト・バージョン。2014. 9. 3 (お試し版) ' Ver 0.17 テスト・バージョン。2014. 9.20 ' Ver 1.01 初回公開バージョン。 2013.10. 9 ' ' Const Prgver = "01.01" 'プログラム・バージョン。 ' ' $regfile = "m328pdef.dat" '使用するAVRを設定。 $crystal = 8000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 Const Menuvalue = 5 - 1 'メニュー数。(メニュー数 - 1) ' ' * ポート名の定義 * ' Lcd_power Alias Portb.7 'LCDモジュールの電源制御ポート。 Lcd_bl Alias Portd.5 'LCDのバックライト制御ポート。 Sp_out Alias Portd.6 'スピーカー出力の接続ポート。 ' Led_1 Alias Portc.1 'LED1[橙]の接続ポート。 Led_2 Alias Portc.2 'LED2[青]の接続ポート。 Led_3 Alias Portc.3 'LED3[緑]の接続ポート。 Led_4 Alias Portc.4 'LED4[桃]の接続ポート。 Led_5 Alias Portc.5 'LED5[白]の接続ポート。 ' Sw_1 Alias Pinb.1 'スイッチ[1]の接続ポート。 Sw_2 Alias Pinb.2 'スイッチ[2]の接続ポート。 Sw_3 Alias Pinb.3 'スイッチ[3]の接続ポート。 Sw_4 Alias Pinb.4 'スイッチ[4]の接続ポート。 Sw_5 Alias Pinb.5 'スイッチ[5]の接続ポート。 Sw_6 Alias Pinb.0 'スイッチ[6]の接続ポート。 ' ' * 変数の宣言 * ' Dim Menuno As Byte 'ゲームメニュー選択番号。 Dim Maxlevel As Byte 'レベルの上限値。 Dim Level As Byte 'ゲーム・レベル。 Dim Hiscorepos As Byte 'EEPROMハイスコアのメモリー位置。 Dim Submenu As Byte 'サブメニューの表示項目。(&H0x:メニュー無し , &H1x:ハイスコアのみ , &H2x〜:各メニュー表示) Dim Submenusel As Byte 'サブメニュー(ゲーム設定メニュー)の表示選択。 Dim Led(6) As Byte '各LEDの輝度値。 Dim Ledset(6) As Byte '各LEDの輝度設定値。 Dim Ledcounter As Byte 'ダイナミック点灯カウンター。 ' Dim Score As Word 'スコア。(0〜65535) Dim Stage As Byte 'ステージ番号。 Dim Stgcount As Byte 'ステージ内のカウンター。 Dim Stghit As Byte 'ステージ内の当たり数。 Dim Stgtimer As Byte 'ステージ内のタイマー。 Dim Gdata(100) As Byte 'ゲームデータの保管用。 Dim ___rseed As Word '乱数のテーブル拡散用内部変数。 ' Dim Swcount As Byte 'スイッチ入力チェック用タイマーカウンター。 Dim Swflag As Byte 'スイッチ入力検出フラグ。 Dim Swdata As Byte 'スイッチ入力データ。 Dim Swtemp As Byte 'スイッチ入力データの一時保管用。 ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Temp2 As Byte '汎用テンポラリ変数 Byte型 No.2 Dim Temp3 As Byte '汎用テンポラリ変数 Byte型 No.3 Dim Temp4 As Byte '汎用テンポラリ変数 Byte型 No.4 Dim Temp5 As Byte '汎用テンポラリ変数 Byte型 No.5 Dim Temp6 As Byte '汎用テンポラリ変数 Byte型 No.6 Dim Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 Dim Tempw2 As Word '汎用テンポラリ変数 Word型 No.2 Dim Tempw3 As Word '汎用テンポラリ変数 Word型 No.3 Dim Templ1 As Long '汎用テンポラリ変数 Long型 No.1 Dim Templ2 As Long '汎用テンポラリ変数 Long型 No.2 Dim Tempstr As String * 20 '汎用テンポラリ変数 String型 No.1 Dim Tempstr2 As String * 20 '汎用テンポラリ変数 String型 No.2 ' Dim Dummy As Eram Long 'EEPROM 4バイトのダミーエリア。 Dim Eeplevel(10) As Eram Byte 'EEPROM ゲーム・レベル。 Dim Eephiscore(50) As Eram Word 'EEPROM ハイスコア。 Dim Eepusecheck As Eram Byte 'EEPROM 使用状態チェックバイト。 ' ' * ポートの初期設定 * ' Config Clockdiv = 1 'AVRの動作クロックを8MHzに変更する。 ' Config Portc = &B0011_1111 'LEDの接続ポートを出力に設定する。 Config Portb = &B0000_0000 'スイッチの接続ポートを入力に設定する。 Portb = &B0011_1111 'スイッチの接続ポートをプルアップする。 Config Lcd_power = Output 'LCDモジュールの電源制御ポートを出力に設定する。 Config Lcd_bl = Output 'LCDのバックライト制御ポートを出力に設定する。 Set Lcd_power 'LCDモジュールの電源を入れる。 Reset Lcd_bl 'LCDのバックライトを点灯させる。 Config Sp_out = Output 'スピーカーの接続ポートを出力に設定する。 Set Portd.7 '未使用ポートをプルアップする。 ' ' * LCDの初期設定 * ' Config Lcdmode = Port 'LCDを4ビットのポートモードに設定。 Config Lcdbus = 4 'LCDデータバスを4bitに設定。 Config Lcdpin = Pin , Db4 = Portd.3 , Db5 = Portd.2 'LCDのポート割り当て。 Config Lcdpin = Pin , Db6 = Portd.1 , Db7 = Portd.0 Config Lcdpin = Pin , E = Portd.4 , Rs = Portb.6 Config Lcd = 16 * 2 'LCD表示を16文字2行に設定。 Gosub Lcdinit 'LCDを初期化する。 ' ' * Timerの設定 * ' Config Timer2 = Timer , Prescale = 32 'LEDのダイナミック点灯用 8,000,000Hz / 32 / 256 = 約976.6Hz Stop Timer2 'Timer2を停止させておく。 On Timer2 Tint2 Nosave 'TIMER2オーバーフロー割り込みルーチンのラベルを設定。 Enable Timer2 'TIMER2オーバーフロー割り込みを許可。 On Compare2a Tint2a Nosave 'TIMER2比較一致A割り込みルーチンのラベルを設定。 Enable Compare2a 'TIMER2比較一致A割り込みを許可。 On Compare2b Tint2b Nosave 'TIMER2比較一致B割り込みルーチンのラベルを設定。 Enable Compare2b 'TIMER2比較一致B割り込みを許可。 ' Config Timer0 = Timer , Prescale = 1024 , Clear Timer = 1 '10mSタイマー 8,000,000Hz / 1024 = 7,812.5Hz Compare0a = 78 - 1 '7,812.5Hz / 100Hz(10mS) = 約78(カウント) ' ' * EEPROMのデータを確認する * ' If Eepusecheck <> &H75 Then 'If EEPROMが初期値か? Then Eeplevel(1) = 3 '[1] LEDたたき ゲーム。 Eeplevel(2) = 1 '[2] ルーレット ゲーム。 Eeplevel(3) = 1 '[3] LED危機一髪 ゲーム。 Eeplevel(4) = 3 '[4] LED記憶力 ゲーム。 For Temp1 = 1 To 50 'EEPROMに初期値を書き込む。 Eephiscore(temp1) = 0 Next Temp1 Eepusecheck = &H75 End If ' ' * プログラム・バージョンの表示 * ' If Sw_6 = 0 Then 'If [スイッチ1]が押されているか? Then Locate 1 , 1 'プログラム・バージョンを表示。 Lcd "LEDゲーム チャレンジ5" Locate 2 , 4 Lcd "Ver. " ; Prgver Bitwait Sw_6 , Set '[スイッチ1]が離されるまで待つ。 End If ' ' * 初期値の設定 * ' Gosub Beep50ms '4KHzの音を50mS鳴らす。 Menuno = 0 Submenusel = 0 Enable Interrupts 'すべての割り込みを許可。 ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: Cls 'LCDの表示をすべて消去する。 Gosub Menudisp 'LCDにメニューを表示する。 ' Main1: ___rseed = ___rseed + Timer0 '乱数のテーブルを拡散する。 ' Gosub Swintimer 'Timer 10mS スイッチ入力。 ' If Swflag <> 0 Then 'スイッチ入力が有ったか? Then Swflag = 0 Select Case Swdata Case &B0000_0010 : '[1]スイッチが押された場合。 If Submenusel = 0 Then 'If レベル設定画面か? Then Gosub Beep50ms '4KHzの音を50mS鳴らす。 Menuno = Menuno - 1 If Menuno > Menuvalue Then 'If メニュー番号が下限を超えたか? Then Menuno = Menuvalue End If Goto Main Else 'ハイスコアのクリア。 Locate 1 , 10 Lcd "00000" Sound Sp_out , 4000 , 167 '4KHzの音を1S鳴らす。 Eephiscore(hiscorepos) = 0 'ハイスコアのクリアして保存する。 Gosub Menudisp2 'LCD2行目のメニューを表示する。 End If ' Case &B0000_0100 : '[2]スイッチが押された場合。 If Submenusel = 0 Then 'If レベル設定画面か? Then Gosub Beep50ms '4KHzの音を50mS鳴らす。 Menuno = Menuno + 1 If Menuno > Menuvalue Then 'If メニュー番号が上限を超えたか? Then Menuno = 0 End If Goto Main End If ' Case &B0000_1000 : '[3]スイッチが押された場合。 If Submenu > &H10 Then 'If サブメニューの表示が有るか? Then If Submenusel = 0 Then 'If レベル設定画面か? Then If Level > 1 Then 'If ゲームレベルが下限ではないか? Then Gosub Beep50ms '4KHzの音を50mS鳴らす。 Level = Level - 1 'ゲームレベルを下げる。 Eeplevel(menuno) = Level 'ゲームレベルをEEPROMに保存する。 Gosub Menudisp2 'LCD2行目のメニューを表示する。 End If End If End If ' Case &B0001_0000 : '[4]スイッチが押された場合。 If Submenu > &H10 Then 'If サブメニューの表示が有るか? Then If Submenusel = 0 Then 'If レベル設定画面か? Then If Level < Maxlevel Then 'If ゲームレベルが上限ではないか? Then Gosub Beep50ms '4KHzの音を50mS鳴らす。 Level = Level + 1 'ゲームレベルを上げる。 Eeplevel(menuno) = Level 'ゲームレベルをEEPROMに保存する。 Gosub Menudisp2 'LCD2行目のメニューを表示する。 End If End If End If ' Case &B0010_0000 : '[5]スイッチが押された場合。 If Submenu > &H00 Then 'If ハイスコア・クリアが有るか? Then Gosub Beep50ms '4KHzの音を50mS鳴らす。 Submenusel = Submenusel + 1 If Submenusel > 1 Then 'If ゲーム設定メニューが上限を超えたか? Then Submenusel = 0 Gosub Menudisp 'LCDにメニューを表示する。 Else Gosub Menudisp2 'LCD2行目のメニューを表示する。 End If End If ' Case &B0000_0001 : '[スタート/ストップ]スイッチが押された場合。 Gosub Beep50ms '4KHzの音を50mS鳴らす。 Select Case Menuno Case 0 : Goto Illumination 'イルミネーション・モード。 Case 1 : Goto Ledattack 'LEDたたき ゲーム。 Case 2 : Goto Roulette 'ルーレット ゲーム。 Case 3 : Goto Ledcrisis 'LED危機一髪 ゲーム。 Case 4 : Goto Ledmemory 'LED記憶力 ゲーム。 ' End Select End Select End If Goto Main1 ' ' ------------------------------------ ' * 4KHzの音を50mS鳴らすサブルーチン * ' ------------------------------------ ' Beep50ms: Sound Sp_out , 200 , 167 '4KHzの音を50mS鳴らす。 Return ' ' --------------------------------------- ' * LCDにメニューを表示するサブルーチン * ' --------------------------------------- ' Menudisp: Locate 1 , 1 Lcd "1{008}2" ; Spc(13) 'メニュー選択ボタンを表示する。 ' Tempstr = Lookupstr(menuno , Menudata) 'ゲーム選択メニューを表示する。 Locate 1 , 4 Lcd Tempstr ' Temp1 = Lookup(menuno , Menusetdata) 'メニュー設定用のテーブルを参照する。 Maxlevel = Temp1 And &H0F 'レベルの上限値。 Submenu = Temp1 And &HF0 'サブメニューの表示項目。 Submenusel = 0 'サブメニュー(ゲーム設定メニュー)の表示選択をクリアする。 ' Menudisp2: If Submenu <> 0 Then 'If 2行目の表示(サブメニュー)が有るか? Then Level = Eeplevel(menuno) 'ゲームレベルを読み出す。 Temp1 = Menuno * 5 Hiscorepos = Temp1 + Level 'EEPROMハイスコアのメモリー位置を計算する。 Locate 2 , 1 If Submenusel = 0 Then 'If ゲーム設定か? Then Locate 2 , 1 'LCDの2行目メニューを表示する。 Select Case Submenu Case &H20 'サブメニューがレベル選択の場合。 Lcd "3{008}4 レベル [" ; Level ; "] " Case &H30 'サブメニューがプレーヤー選択の場合。 Lcd "3{008}4 プレーヤー[" ; Level ; "] " Case Else 'サブメニューがハイスコア・クリアのみの場合。 Lcd Spc(14); End Select Else 'ハイスコアクリアの場合。 Lcd "1{001} ハイスコア クリア " Tempw1 = Eephiscore(hiscorepos) Tempstr = Str(tempw1) '手持ちコイン数を表示する。 Locate 1 , 1 Lcd " ハイスコア " ; Format(tempstr , " 0") ; " " End If Locate 2 , 15 Lcd "{001}5" End If Return ' ' ---------------------------------------- ' * Timer 10mS スイッチ入力 サブルーチン * (Swflag = 1 : スイッチ入力有り) ' ---------------------------------------- (Swdata = スイッチ データ) ' Swintimer: If Tifr0.ocf0a = 1 Then 'If 10mS経過したか? Then Set Tifr0.ocf0a 'Timer0 比較A一致フラグをリセット。 Gosub Swin 'スイッチ入力を確認する。 End If Return ' ' ----------------------------- (10mS毎に呼び出す) ' * スイッチ入力 サブルーチン * (Swflag = 1 : スイッチ入力有り) ' ----------------------------- (Swdata = スイッチ データ) ' Swin: Select Case Swcount Case 0 : 'スイッチ入力チェック開始。 Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swdata <> 0 Then 'If スイッチ入力が有るか? Then Swtemp = Swdata 'スイッチ データを一時保存。 Swcount = 1 End If ' Case Is < 4 : 'チャタリング除去期間。 Swcount = Swcount + 1 ' Case 4 : 'スイッチ入力を再確認。 Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swdata = Swtemp Then 'If スイッチ入力が確定か? Then Swflag = 1 Swcount = Swcount + 1 Else 'エラーの場合。 Swcount = 0 End If ' Case Else : 'スイッチが離されるのを待つ。 Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swdata <> Swtemp Then 'If スイッチの状態が変わったか? Then Swcount = 0 End If End Select Return ' ' -------------------------------------------------- ' * スイッチ接続ポートからのデータ入力サブルーチン * (Swdata = スイッチ データ) ' -------------------------------------------------- ' Swport: Swdata = Not Pinb Swdata = Swdata And &B0011_1111 Return ' ' ------------------- ' * LCDを初期化するサブルーチン * ' ------------------- ' Lcdinit: Initlcd 'LCDを初期化する。 Cls 'LCDを全面消去する。 Cursor Off 'LCDのカーソルをオフにする。 Lcdinit1: Deflcdchar 0 , &H00 , &H00 , &H0A , &H1B , &H0A , &H00 , &H00 , &H00 'カスタム文字[左右矢印]をLCDへ書き込む。 Deflcdchar 1 , &H00 , &H08 , &H0C , &H0E , &H0C , &H08 , &H00 , &H00 'カスタム文字[右▲]をLCDへ書き込む。 Deflcdchar 2 , &H00 , &H00 , &H04 , &H0E , &H1F , &H00 , &H00 , &H00 'カスタム文字[上▲]をLCDへ書き込む。 Deflcdchar 7 , &H18 , &H08 , &H08 , &H08 , &H02 , &H05 , &H05 , &H02 'カスタム文字[10]をLCDへ書き込む。 Return ' ' Lcdinit2: Deflcdchar 0 , &H03 , &H07 , &H07 , &H07 , &H07 , &H07 , &H07 , &H03 'カスタム文字[大数字0]をLCDへ書き込む。 Deflcdchar 1 , &H18 , &H1C , &H1C , &H1C , &H1C , &H1C , &H1C , &H18 'カスタム文字[大数字1]をLCDへ書き込む。 Deflcdchar 2 , &H1F , &H1F , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 'カスタム文字[大数字2]をLCDへ書き込む。 Deflcdchar 3 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H1F , &H1F 'カスタム文字[大数字3]をLCDへ書き込む。 Deflcdchar 4 , &H1F , &H1F , &H00 , &H00 , &H00 , &H00 , &H1F , &H1F 'カスタム文字[大数字4]をLCDへ書き込む。 Deflcdchar 5 , &H03 , &H07 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 'カスタム文字[大数字5]をLCDへ書き込む。 Deflcdchar 6 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H1C , &H1C 'カスタム文字[大数字6]をLCDへ書き込む。 Deflcdchar 7 , &H00 , &H00 , &H00 , &H00 , &H00 , &H00 , &H07 , &H03 'カスタム文字[大数字7]をLCDへ書き込む。 Return ' ' ------------------------------------- ' * LCDに大数字を表示するサブルーチン * (score = Wardデータ) ' ------------------------------------- ' Bignum2disp: '2桁版。 Temp6 = 4 Temp1 = 11 'LCDの[X]アドレス。 Goto Bignum5disp1 ' ' Bignum4disp: '4桁版。 Temp6 = 2 Temp1 = 5 'LCDの[X]アドレス。 Goto Bignum5disp1 ' ' Bignum5disp: '5桁版。 Temp6 = 1 Temp1 = 2 'LCDの[X]アドレス。 Bignum5disp1: Tempstr = Str(score) '数値を文字列に変換する。 Tempstr = Format(tempstr , " 0") '5桁にそろえる。 For Temp2 = Temp6 To 5 '5桁の数字を表示する。 Tempstr2 = Mid(tempstr , Temp2 , 1) If Tempstr2 = " " Then 'If スペースか? Then Temp3 = 10 Else '数字の場合。 Temp3 = Val(tempstr2) End If Temp3 = Temp3 * 6 'テーブルの位置を計算する。 Locate 1 , Temp1 '上段の3キャラクタを表示する。 Gosub Bignumdispsub Locate 2 , Temp1 '下段の3キャラクタを表示する。 Gosub Bignumdispsub Temp1 = Temp1 + 3 Next Temp2 Return ' ' Bignumdispsub: For Temp4 = 1 To 3 '各段の3キャラクタを表示する。 Temp5 = Lookup(temp3 , Bignumbers) Lcd Chr(temp5); Temp3 = Temp3 + 1 Next Temp4 Return ' ' --------------------------------------------- ' * LCDに開始のイベントを表示するサブルーチン * ' --------------------------------------------- ' Startdisp: Locate 2 , 1 Lcd " --- ヨウイ --- " Waitms 500 Sound Sp_out , 100 , 1333 '500Hzの音を200mS鳴らす。 Waitms 300 Sound Sp_out , 100 , 1333 '500Hzの音を200mS鳴らす。 Waitms 300 Sound Sp_out , 100 , 1333 '500Hzの音を200mS鳴らす。 Waitms 300 Locate 2 , 1 Lcd " >>> スタート <<< " Sound Sp_out , 500 , 666 '1000Hzの音を500mS鳴らす。 Waitms 500 Cls 'LCDを全面消去する。 Return ' ' --------------------------------------------------------- ' * ダイナミック点灯モードのLEDを全て消灯するサブルーチン * ' --------------------------------------------------------- ' Dinledoff: For Temp1 = 1 To 5 'すべてのLED を消灯させる。 Led(temp1) = 0 Ledset(temp1) = 0 Next Temp1 Return ' ' -------------------------------------------------------- ' * スイッチビットからバイナリー数に変換するサブルーチン * (Swdata = ビット データ) ' -------------------------------------------------------- (Temp1 = バイナリー データ) ' Bittobin: Select Case Swdata Case &B0000_0001 : Temp1 = 6 Case &B0000_0010 : Temp1 = 1 Case &B0000_0100 : Temp1 = 2 Case &B0000_1000 : Temp1 = 3 Case &B0001_0000 : Temp1 = 4 Case &B0010_0000 : Temp1 = 5 Case Else : Temp1 = 0 End Select Return ' ' ------------------------------------------------ ' * バイナリー数からビットに変換するサブルーチン * (Temp1 = バイナリー データ) ' ------------------------------------------------ (Temp2 = ビット データ) ' Bintobit: Select Case Temp1 Case 6 : Temp2 = &B0000_0001 Case 1 : Temp2 = &B0000_0010 Case 2 : Temp2 = &B0000_0100 Case 3 : Temp2 = &B0000_1000 Case 4 : Temp2 = &B0001_0000 Case 5 : Temp2 = &B0010_0000 Case Else : Temp2 = &B0000_0000 End Select Return '############################################################################### ' ' **************************** ' * イルミネーション・モード * ' **************************** ' Illumination: Locate 1 , 1 Lcd " " Gosub Dinledoff 'ダイナミック点灯モードのLEDを全て消灯する。 Led(6) = 64 'LCDのバックライトを減光させる。 Start Timer2 'Timer2を始動させる。 ' Illumi1: 'LEDの点灯パターンデータに合わせて点灯する。 Restore Illumidata Illumi2: Read Temp1 'LEDの点灯パターンを読み込む。 If Temp1 = &HFF Then Goto Illumi1 'If データテーブルの終了位置か? Then Read Temp2 'LEDの点灯時間を読み込む。 ' For Temp3 = 1 To 5 'テーブルからLEDの点灯パターンを設定する。 If Temp1.temp3 = 1 Then 'If LEDを点灯するか? Then Ledset(temp3) = 253 Else '消灯する場合。 Ledset(temp3) = 0 End If Next Temp3 ' Illumi3: If Tifr0.ocf0a = 1 Then 'If 10mS経過したか? Then Set Tifr0.ocf0a 'Timer0 比較A一致フラグをリセット。 Gosub Swin 'スイッチ入力を確認する。 Gosub Brightcnt 'LEDの輝度を調光する。 Temp2 = Temp2 - 1 End If If Swflag <> 0 Then Goto Illumi4 'スイッチ入力が有ったか? Then If Temp2 = 0 Then Goto Illumi2 'If 点灯期間を経過したか? Then Goto Illumi3 ' ' Illumi4: 'スイッチ入力の処理。 Swflag = 0 Stop Timer2 'Timer2を停止させる。 Gosub Beep50ms '4KHzの音を50mS鳴らす。 Reset Lcd_bl 'LCDのバックライトを点灯させる。 If Swdata = &B0000_0001 Then Goto Illumi5 'If [スタート/ストップ]スイッチか? Then ' Illumi6: 'スイッチのテストモード。 Gosub Swport 'スイッチ接続ポートからデータを入力。 Locate 2 , 1 Lcd "SW: " ; Bin(swdata) Portc = Swdata If Swdata <> 0 Then Goto Illumi6 'If スイッチが押されているか? Then Locate 2 , 1 Lcd Spc(16) Start Timer2 'Timer2を始動させる。 Goto Illumi3 ' Illumi5: 'イルミネーション・モードの終了。 Gosub Dinledoff 'ダイナミック点灯モードのLEDを全て消灯する。 Portc = &B0000_0000 'LEDを全て消灯する。 Goto Main ' ' ----------------------------------- ' * LEDの輝度を調光するサブルーチン * ' ----------------------------------- ' Brightcnt: For Temp5 = 1 To 5 If Ledset(temp5) > Led(temp5) Then 'If LED輝度の変更有りか? Then Led(temp5) = Led(temp5) + 2 Else If Ledset(temp5) < Led(temp5) Then 'If LED輝度の変更有りか? Then Led(temp5) = Led(temp5) - 1 End If End If Next Temp5 Return '############################################################################### ' ' ******************** ' * LEDたたき ゲーム * ' ******************** ' Ledattack: Config Timer1 = Timer , Prescale = 1024 , Clear Timer = 1 '打撃許容時間用Timer 8,000,000Hz / 1,024 = 7,812.5Hz(128uS) Cls 'LCDを全面消去する。 Tempstr = Lookupstr(menuno , Menudata) 'ゲームメニューを表示する。 Locate 1 , 2 Lcd Tempstr Gosub Lcdinit2 'LCDのカスタム文字を[大数字]に変更する。 Gosub Startdisp 'LCDに開始のイベントを表示する。 ' Temp1 = Level - 1 'レベルごとの打撃許容時間を設定する。(Timer1の設定値) Temp1 = Temp1 + Temp1 '2倍する。 Tempw1 = Lookup(temp1 , Ledattacktime) '開始時の許容時間。 Temp1 = Temp1 + 1 Tempw2 = Lookup(temp1 , Ledattacktime) '難易度アップ率。 Stage = 1 'ステージ番号。 Score = 0 'スコア。 Swflag = 1 Gosub Bignum4disp 'LCDに大数字で得点を表示する。 ' ' * ステージ開始 * ' Ledattack1: Locate 1 , 1 'LCDにステージ番号を表示する。 Lcd "S" ; Stage Compare1a = Tempw1 '打撃許容時間をTimer1に設定する。 Tempw3 = Tempw1 / 2 Compare1b = Tempw3 '高得点の打撃時間をTimer1に設定する。 Stgcount = 1 '1ステージの打撃数カウント。 Stghit = 0 '1ステージの当たり数。 Locate 2 , 3 Lcd " 0" '当たり数表示を消去する。 ' ' * 1ステージ中の処理 * ' Ledattack2: Tempstr = Str(stgcount) '数値を文字列に変換する。 Locate 2 , 1 Lcd Format(tempstr , " 0") 'ステージの打撃数カウント数を表示する。 ' Stop Timer1 Sound Sp_out , 100 , 333 '2000Hzの音を50mS鳴らす。 Timer1 = 0 Set Tifr1.ocf1a 'Timer1 比較A一致フラグをリセット。 Set Tifr1.ocf1b 'Timer1 比較B一致フラグをリセット。 ' Temp1 = Rnd(5) '乱数を発生させる。 Select Case Temp1 '乱数によりLEDを点灯させる。 Case 0 : Set Led_1 Temp6 = &B0000_0010 Case 1 : Set Led_2 Temp6 = &B0000_0100 Case 2 : Set Led_3 Temp6 = &B0000_1000 Case 3 : Set Led_4 Temp6 = &B0001_0000 Case Else : Set Led_5 Temp6 = &B0010_0000 End Select Start Timer1 'Timer1を始動させる。 ' ' * スイッチ入力処理 * ' Ledattack3: Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swflag <> 0 Then Goto Ledattack11 'If スイッチが離されるのを待つか? Then If Swdata <> 0 Then Goto Ledattack12 'If スイッチが押されたか? Then Ledattack4: If Tifr1.ocf1a = 0 Then Goto Ledattack3 'If 打撃許容時間内か? Then ' Ledattack5: '1打終了。 Portc = &B0000_0000 'LEDを全て消灯する。 Stgcount = Stgcount + 1 'ステージ内のゲーム数をカウントする。 If Stgcount < 11 Then Goto Ledattack2 'If 1ステージ内か? Then ' ' * 1ステージ終了 * ' If Stghit < 5 Then Goto Gameend1 'If ステージクリア条件未達成か ? Then Sound Sp_out , 88 , 758 '880Hzの音を100mS鳴らす。 Sound Sp_out , 70 , 955 '698Hzの音を100mS鳴らす。 Sound Sp_out , 88 , 758 '880Hzの音を100mS鳴らす。 Sound Sp_out , 349 , 955 '698Hzの音を500mS鳴らす。 If Level > 3 Then Goto Ledattack6 'If レベルが4以上か? Then If Stage = 10 Then Goto Gameend1 'If 全ステージ終了か? Then Stage = Stage + 1 Ledattack7: Tempw1 = Tempw1 - Tempw2 'ステージの難易度を上げる。 Ledattack8: Wait 2 Goto Ledattack1 ' Ledattack6: 'レベルが4,5の場合。 If Stage = 99 Then Goto Gameend1 'If 全ステージ終了か? Then Stage = Stage + 1 If Stage < 11 Then Goto Ledattack7 'If 10ステージ以内か? Then Goto Ledattack8 ' ' Ledattack11: 'スイッチが離されるのを待つ。 If Swdata <> 0 Then Goto Ledattack4 'If スイッチが押されたままか? Then Swflag = 0 Waitms 30 'チャタリングの待ち時間。 Goto Ledattack4 ' ' * スイッチが押された場合 * ' Ledattack12: If Swdata = &B0000_0001 Then Goto Gameend1 'If [スタート/ストップ]スイッチが押されたか? Then If Swdata = Temp6 Then 'If スイッチが正解か? Then If Tifr1.ocf1b = 0 Then 'If 高得点時間内か? Then Score = Score + 10 '高得点。 Else Score = Score + 5 End If If Score > 9999 Then Score = 9999 'If スコアが上限か? Then Stghit = Stghit + 1 '正解数を計測する。 Portc = &B0000_0000 'LEDを全て消灯する。 Else 'スイッチの押し間違い。(減点) If Score < 5 Then 'If スコアが5点未満か? Then Score = 0 Else Score = Score - 5 End If End If ' Tempstr = Str(stghit) '数値を文字列に変換する。 Locate 2 , 3 Lcd Format(tempstr , " 0") '当たり数を表示する。 Gosub Bignum4disp 'LCDに大数字で得点を表示する。(40mSかかるのでチャタリングの待ちは不要) Ledattack13: If Tifr1.ocf1a = 0 Then Goto Ledattack13 'If 打撃許容時間内か? Then Swflag = 1 Goto Ledattack5 ' ' * ゲーム終了 * ' Gameend1: Sound Sp_out , 70 , 1904 '350Hzの音を200mS鳴らす。 Waitms 200 Sound Sp_out , 280 , 1904 '350Hzの音を800mS鳴らす。 Portc = &B0000_0000 'LEDを全て消灯する。 ' Tempw1 = Eephiscore(hiscorepos) If Score > Tempw1 Then 'If ハイスコアを更新したか? Then Tempw1 = Score Eephiscore(hiscorepos) = Score 'EEPROMハイスコアを更新する。 End If ' Tempstr = Str(tempw1) '数値を文字列に変換する。 Locate 1 , 6 Lcd "ハイスコア= " ; Format(tempstr , " 0") 'ハイスコアを表示する。 Tempstr = Str(score) '数値を文字列に変換する。 Locate 2 , 1 Lcd "レベル" ; Level ; " スコア= " ; Format(tempstr , " 0") 'スコアを表示する。 Swflag = 0 ' Gameend2: Gosub Swintimer 'Timer 10mS スイッチ入力。 If Swflag = 0 Then Goto Gameend2 'スイッチ入力が無いか? Then Swflag = 0 Gosub Beep50ms '4KHzの音を50mS鳴らす。 If Swdata <> &B0000_0001 Then Goto Ledattack 'If [スタート/ストップ]スイッチ以外か? Then Gosub Lcdinit1 'LCDのカスタム文字を[メニュー用]に変更する。 Goto Main '############################################################################### ' ' ********************* ' * ルーレット ゲーム * ' ********************* ' Roulette: Score = Eephiscore(hiscorepos) If Score = 0 Then 'If 手持ちコインが[$0]か? Then Score = 30 'コインの初期値。 End If ' Roulette1: For Temp1 = 1 To 5 '賭けコインのバッファーを全てクリアする。 Gdata(temp1) = 0 Next Temp1 ' Locate 1 , 1 '初期画面の表示。 Lcd "x2{126} x4{126} $" Locate 2 , 1 Lcd "x8{126} x15{126} x30{126} " ' ' * 賭けコイン数を表示する * ' Roulette2: Locate 1 , 4 Temp1 = Gdata(1) Gosub Coindisp Locate 1 , 9 Temp1 = Gdata(2) Gosub Coindisp Locate 2 , 4 Temp1 = Gdata(3) Gosub Coindisp Locate 2 , 10 Temp1 = Gdata(4) Gosub Coindisp Locate 2 , 16 Temp1 = Gdata(5) Gosub Coindisp Locate 1 , 12 Tempstr = Str(score) '手持ちコイン数を表示する。 Lcd Format(tempstr , " 0") ' ' * スイッチ入力処理 * ' Roulette3: Gosub Swintimer 'Timer 10mS スイッチ入力。 If Swflag = 0 Then Goto Roulette3 'スイッチ入力が無いか? Then Swflag = 0 Gosub Bittobin 'スイッチビットからバイナリー数に変換する。 If Temp1 = 0 Then Goto Roulette3 'スイッチ入力エラーか? Then If Temp1 = 6 Then Goto Roulette4 'If [スタート/ストップ]スイッチが押されたか? Then ' If Gdata(temp1) = 10 Then 'If 賭けコインが10を超えるか? Then Gdata(temp1) = 0 '賭けコインを無しにする。 Score = Score + 10 '賭けコインを戻す。 Sound Sp_out , 50 , 666 '1000Hzの音を50mS鳴らす。 Else '賭けコインが10未満の場合。 If Score = 0 Then 'If 手持ちコインが[$0]か? Then Sound Sp_out , 70 , 1904 '350Hzの音を200mS鳴らす。 Else Gosub Beep50ms '4KHzの音を50mS鳴らす。 Score = Score - 1 Gdata(temp1) = Gdata(temp1) + 1 '賭けコインを加算する。 End If End If Goto Roulette2 ' ' * [スタート/ストップ]スイッチが押された場合 * ' Roulette4: Gosub Beep50ms '4KHzの音を50mS鳴らす。 Temp2 = 0 For Temp1 = 1 To 5 '賭けコインの有無を確認する。 Temp2 = Temp2 + Gdata(temp1) Next Temp1 If Temp2 = 0 Then Goto Main 'If 賭けコインが全く無いか? Then ' ' * 抽選の開始 * ' Temp2 = Rnd(24) '乱数を発生させる。 Select Case Temp2 Case Is < 12 : '[1] 1/2 50% Stgcount = Gdata(1) '賭けたコイン数。 Temp1 = 1 'LEDの点灯個数。 Stghit = 2 '当たり倍率。 Locate 1 , 3 '当たりのLCD位置。 Case Is < 18 : '[2] 1/4 25% Stgcount = Gdata(2) '賭けたコイン数。 Temp1 = 2 'LEDの点灯個数。 Stghit = 4 '当たり倍率。 Locate 1 , 8 '当たりのLCD位置。 Case Is < 21 : '[3] 1/8 12.5% Stgcount = Gdata(3) '賭けたコイン数。 Temp1 = 4 'LEDの点灯個数。 Stghit = 8 '当たり倍率。 Locate 2 , 3 '当たりのLCD位置。 Case Is < 23 : '[4] 1/12 8.33% Stgcount = Gdata(4) '賭けたコイン数。 Temp1 = 3 'LEDの点灯個数。 Stghit = 15 '当たり倍率。 Locate 2 , 9 '当たりのLCD位置。 Case Else : '[5] 1/24 4.16% Stgcount = Gdata(5) '賭けたコイン数。 Temp1 = 5 'LEDの点灯個数。 Stghit = 30 '当たり倍率。 Locate 2 , 15 '当たりのLCD位置。 End Select ' Temp2 = Temp1 + 40 '点灯数を計算する。 Tempw1 = 1 Temp4 = &B0010_0000 For Temp3 = 1 To Temp2 'LEDを回転表示させる。 Select Case Temp4 Case &B0000_0010 : Temp4 = &B0000_0100 Case &B0000_0100 : Temp4 = &B0001_0000 Case &B0001_0000 : Temp4 = &B0000_1000 Case &B0000_1000 : Temp4 = &B0010_0000 Case Else : Temp4 = &B0000_0010 End Select Portc = Temp4 Sound Sp_out , 100 , 333 '2000Hzの音を50mS鳴らす。 Waitms Tempw1 Tempw1 = Tempw1 + 8 '遅延時間を延ばす。 Next Temp3 ' Cursor Blink '当たり位置の表示。 For Temp3 = 1 To 2 Portc = &B0000_0000 '全てのLEDを消灯する。 Waitms 400 Portc = Temp4 If Stgcount <> 0 Then 'If 当たりに賭けて有るか? Then Sound Sp_out , 88 , 758 '880Hzの音を100mS鳴らす。 Sound Sp_out , 279 , 955 '698Hzの音を400mS鳴らす。 Else Sound Sp_out , 175 , 1904 '350Hzの音を500mS鳴らす。 End If Next Temp3 Cursor Noblink Lcd Chr(&Hef) ' If Stgcount <> 0 Then 'If 当たりに賭けて有るか? Then Tempw1 = Stgcount * Stghit '獲得コインを計算する。 Do '手持ちコインを増やす表示。 Score = Score + 1 If Score > 60000 Then 'スコアの上限か? Then Score = 60000 End If Locate 1 , 12 Tempstr = Str(score) '手持ちコイン数を表示する。 Lcd Format(tempstr , " 0") Sound Sp_out , 50 , 133 '5000Hzの音を10mS鳴らす。 Waitms 20 Tempw1 = Tempw1 - 1 Loop Until Tempw1 = 0 End If Eephiscore(hiscorepos) = Score 'EEPROMハイスコアを更新する。 ' Wait 1 Portc = &B0000_0000 '全てのLEDを消灯する。 Goto Roulette1 ' ' ---------------------------------- ' * コイン数を表示するサブルーチン * ' ---------------------------------- ' Coindisp: Select Case Temp1 Case 0 : Lcd " " Case 10 : Lcd Chr(7) Case Else : Lcd Temp1 End Select Return '############################################################################### ' ' ********************** ' * LED危機一髪 ゲーム * ' ********************** ' Ledcrisis: Gosub Dinledoff 'ダイナミック点灯モードのLEDを全て消灯する。 Led(6) = 255 'LCDのバックライトを点灯させる。 Start Timer2 'Timer2を始動させる。 Locate 1 , 1 Lcd " " Locate 2 , 1 Lcd Spc(16) Gosub Lcdinit2 'LCDのカスタム文字を[大数字]に変更する。 Score = 0 '1人用の得点をクリアする。 Gdata(1) = 0 '得点のバッファーをクリアする。 Gdata(2) = 0 Gdata(3) = 0 Gdata(4) = 0 Stage = 1 'プレーヤーの順番。 ' ' * ステージの開始 * ' Ledcrisis1: Waitms 200 For Temp1 = 1 To 5 'すべてのLEDを点灯させる。 Led(temp1) = 255 Next Temp1 ' For Temp1 = 255 To 0 Step -1 'すべてのLED輝度を下げていく。 For Temp2 = 1 To 5 'すべてのLEDを点灯させる。 Led(temp2) = Temp1 Next Temp2 Waitms 3 Next Temp1 Locate 1 , 1 Lcd Spc(16) ' Ledcrisis6: Stgcount = 0 '1ゲームのセーフカウント。 Stghit = Rnd(5) + 1 '乱数を発生させる。 ' ' * 得点と順番の表示 * ' Ledcrisis2: Cursor Noblink If Level = 1 Then 'If 1人プレーか? Then Tempstr = Lookupstr(menuno , Menudata) 'ゲームタイトルを表示する。 Tempstr = Mid(tempstr , 2 , 10) Locate 1 , 1 Lcd Tempstr Tempw1 = Eephiscore(hiscorepos) 'ハイスコアを表示する。 Tempstr = Str(tempw1) '数値を文字列に変換する。 Locate 2 , 2 Lcd "ハイスコア:" ; Format(tempstr , " 0") 'ハイスコアを表示する。 Gosub Bignum2disp 'LCDに大数字で得点を表示する。 Else '2人以上の場合。 Temp2 = 1 'LCDにプレーヤーの順番とスコアを表示する。 For Temp1 = 1 To Level Locate 1 , Temp2 If Temp1 = Stage Then 'If 順番がきたプレーヤーか? Then Lcd " (" ; Temp1 ; ")" '順番が来たプレーヤーの番号を表示する。 Else Lcd " -" ; Temp1 ; "-" '待機プレーヤーの番号を表示する。 End If Locate 2 , Temp2 '各プレーヤーの得点を表示する。 Tempstr = Str(gdata(temp1)) Lcd Format(tempstr , " 0") Temp2 = Temp2 + 4 Next Temp1 ' Temp1 = Stage * 4 '順番が来たプレーヤーの番号にカーソルを点滅させる。 Temp1 = Temp1 - 1 Cursor Blink Locate 1 , Temp1 End If ' ' * スイッチ入力処理 * ' Ledcrisis3: Gosub Swintimer 'Timer 10mS スイッチ入力。 If Swflag = 0 Then Goto Ledcrisis3 'スイッチ入力が無いか? Then Swflag = 0 Gosub Bittobin 'スイッチビットからバイナリー数に変換する。 If Temp1 = 0 Then Goto Ledcrisis3 'スイッチ入力エラーか? Then If Temp1 = 6 Then Goto Ledcrisis4 'If [スタート/ストップ]スイッチが押されたか? Then If Led(temp1) <> 0 Then Goto Ledcrisis3 'If すでに押されたボタンか? Then ' ' * LEDの輝度を上げていくイベント * ' Temp4 = 0 '選ばれたLEDの輝度をゆっくり上げる。 For Temp2 = 1 To 5 '5段階でブザーを鳴らす。 Sound Sp_out , 25 , 133 '5000Hzの音を5mS鳴らす。 For Temp3 = 1 To 51 Led(temp1) = Temp4 If Temp4 <> 255 Then 'LEDの輝度が上限でないか? Then Temp4 = Temp4 + 1 '輝度を上げる。 End If Waitms 13 Next Temp3 Next Temp2 ' ' * 合否の判定 * ' Waitms 800 If Temp1 = Stghit Then Goto Ledcrisis5 'If ハズレを引いたか? Then ' ' * セーフの場合 * ' Sound Sp_out , 88 , 758 '880Hzの音を100mS鳴らす。 Sound Sp_out , 349 , 955 '698Hzの音を500mS鳴らす。 Waitms 100 ' If Level = 1 Then 'If 1人プレーか? Then Score = Score + 1 '得点を加算する。 If Score > 99 Then 'If スコアの上限か? Then Score = 99 End If Stgcount = Stgcount + 1 '1ゲームのセーフカウント数を加算する。 If Stgcount = 4 Then 'If ステージクリアか? Then Score = Score + 1 'ボーナス得点を加算する。 If Score > 99 Then 'If スコアの上限か? Then Score = 99 End If Waitms 800 Gosub Dinledoff 'ダイナミック点灯モードのLEDを全て消灯する。 Stop Timer2 'Timer2を停止させる。 Portc = &B0000_0000 'LEDを全て消灯する。 Reset Lcd_bl 'LCDのバックライトを点灯させる。 Temp1 = Stghit 'ハズレのLEDを点灯させる。 Gosub Bintobit 'バイナリー数からビットに変換する。 Portc = Temp2 ' For Temp2 = 1 To 3 'ステージ終了の音を鳴らす。 Sound Sp_out , 52 , 1275 '523Hzの音を100mS鳴らす。 Waitms 50 Next Temp2 Sound Sp_out , 349 , 955 '698Hzの音を500mS鳴らす。 Wait 1 Start Timer2 'Timer2を始動させる。 Goto Ledcrisis6 ' End If Else '2人以上の場合。 If Gdata(stage) < 250 Then 'If 点数の上限ではないか? Then Gdata(stage) = Gdata(stage) + 1 End If Stage = Stage + 1 'プレーヤーの順番を次へ。 If Stage > Level Then 'If 最後のプレーヤか? Then Stage = 1 End If End If Goto Ledcrisis2 ' ' * ハズレを引いた場合 * ' Ledcrisis5: Gosub Dinledoff 'ダイナミック点灯モードのLEDを全て消灯する。 Stop Timer2 'Timer2を停止させる。 Portc = &B0000_0000 'LEDを全て消灯する。 Reset Lcd_bl 'LCDのバックライトを点灯させる。 Temp3 = 0 Temp2 = 0 For Tempw1 = 1500 To 18500 Step 100 'ハズレのLED点滅処理。 Sound Sp_out , 1 , Tempw1 '350Hzから音程を下げながら鳴らす。 Temp2 = Temp2 + 1 If Temp2 > 16 Then 'If 点滅時間か? Then Temp2 = 0 If Temp3 = 0 Then '点灯か? Then Temp3 = 1 Portc = Swdata Else Temp3 = 0 Portc = &B0000_0000 'LEDを全て消灯する。 End If End If Next Tempw1 Portc = &B0000_0000 'LEDを全て消灯する。 Waitms 500 ' If Level = 1 Then 'If 1人プレーか? Then Tempw1 = Eephiscore(hiscorepos) If Score > Tempw1 Then 'If ハイスコアを更新したか? Then Eephiscore(hiscorepos) = Score 'EEPROMハイスコアを更新する。 End If Score = 0 Else '2人以上の場合。 If Gdata(stage) < 2 Then 'If 点数が0以下になるか? Then Gdata(stage) = 0 Else Gdata(stage) = Gdata(stage) - 2 '2点減点する。 End If End If Start Timer2 'Timer2を始動させる。 Waitms 500 Goto Ledcrisis1 ' ' * [スタート/ストップ]スイッチが押された場合 * ' Ledcrisis4: Gosub Dinledoff 'ダイナミック点灯モードのLEDを全て消灯する。 Stop Timer2 'Timer2を停止させる。 Gosub Beep50ms '4KHzの音を50mS鳴らす。 Reset Lcd_bl 'LCDのバックライトを点灯させる。 Portc = &B0000_0000 'LEDを全て消灯する。 Cursor Noblink Gosub Lcdinit1 'LCDのカスタム文字を[メニュー用]に変更する。 Goto Main '############################################################################### ' ' ******************** ' * LED記憶力 ゲーム * ' ******************** ' Ledmemory: Cls 'LCDを全面消去する。 Config Timer1 = Timer , Prescale = 1 , Clear Timer = 1 '音発生用Timer 8,000,000Hz / COMPARE0A = 音の周波数 / 2 Gosub Lcdinit2 'LCDのカスタム文字を[大数字]に変更する。 ' Score = 0 'スコア。 Stgcount = 50 'ガイド表示の点灯時間。(x10ms) Stgtimer = 150 'ガイド表示の消灯時間。(x1ms) Locate 1 , 1 'レベルの表示。 Lcd "レベル:" ; Level Tempw1 = Eephiscore(hiscorepos) 'ハイスコアの表示。 Locate 2 , 1 Lcd "ハイスコア:" ; Tempw1 Gosub Bignum2disp 'LCDに大数字で得点を表示する。 Waitms 500 ' If Level.0 = 1 Then 'If LEDが4個のモードか? Then Temp3 = 4 Else Temp3 = 5 End If For Temp1 = 1 To 2 'LEDを回転表示させる。 For Temp2 = 1 To Temp3 Select Case Temp2 Case 1 : Temp4 = &B0000_0010 Case 2 : Temp4 = &B0000_0100 Case 3 : Temp4 = &B0001_0000 Case 4 : Temp4 = &B0000_1000 Case Else : Temp4 = &B0010_0000 End Select Portc = Temp4 Waitms 70 Next Temp2 Portc = &B0000_0000 'LEDを全て消灯する。 Waitms 400 Next Temp1 Wait 1 ' ' * ステージの開始 * ' Ledmemory1: Temp1 = Rnd(5) '乱数を発生させる。 If Temp1 = 4 Then 'If 乱数が4か? Then If Level.0 = 1 Then Goto Ledmemory1 'If LEDが4個のモードか? Then End If Stage = Score + 1 'ステージの問題の個数。 Gdata(stage) = Temp1 + 1 ' For Temp2 = 1 To Stage Temp1 = Gdata(temp2) Gosub Ledsound 'LEDを点灯し音程をセットする。 Temp5 = Stgcount 'LED点灯と発音の時間。 ' Ledmemory2: If Tifr1.ocf1a = 1 Then 'If 音の周波数に達したか? Then Set Tifr1.ocf1a 'Timer1 比較A一致フラグをリセット。 Toggle Sp_out End If If Tifr0.ocf0a = 0 Then Goto Ledmemory2 'If 10mS経過していないか? Then Set Tifr0.ocf0a 'Timer0 比較A一致フラグをリセット。 Temp5 = Temp5 - 1 If Temp5 <> 0 Then Goto Ledmemory2 '発音時間内か? Then Reset Sp_out Portc = &B0000_0000 'LEDを全て消灯する。 Waitms Stgtimer '消灯の待ち時間。 Next Temp2 ' ' * スイッチ入力処理 * ' Stghit = 0 'スイッチを押した回数。 Ledmemory3: Gosub Swintimer 'Timer 10mS スイッチ入力。 If Swflag = 0 Then Goto Ledmemory3 'スイッチ入力が無いか? Then Swflag = 0 Gosub Bittobin 'スイッチビットからバイナリー数に変換する。 If Temp1 = 0 Then Goto Ledmemory3 'スイッチ入力エラーか? Then If Temp1 = 6 Then Goto Ledmemory5 'If [スタート/ストップ]スイッチが押されたか? Then Gosub Ledsound 'LEDを点灯し音程をセットする。 ' Ledmemory4: If Tifr1.ocf1a = 1 Then 'If 音の周波数に達したか? Then Set Tifr1.ocf1a 'Timer1 比較A一致フラグをリセット。 Toggle Sp_out End If Gosub Swport 'スイッチ接続ポートからデータを入力。 If Swdata <> 0 Then Goto Ledmemory4 'If スイッチが押されたままか? Then Reset Sp_out Waitms 100 Portc = &B0000_0000 'LEDを全て消灯する。 ' Stghit = Stghit + 1 'スイッチを押した回数を加算する。 If Temp1 <> Gdata(stghit) Then Goto Ledmemory6 'If ハズレか? Then If Stghit <> Stage Then Goto Ledmemory3 'If ステージ終了ではないか? Then ' If Score <> 99 Then 'If スコアの上限ではないか? Then Score = Score + 1 End If Gosub Bignum2disp 'LCDに大数字で得点を表示する。 If Level > 2 Then 'If レベルが3,4か? Then If Stgcount > 16 Then 'If 100ms以上か? Then Stgcount = Stgcount - 2 'ガイド表示の点灯時間。(x10ms) Stgtimer = Stgtimer - 2 'ガイド表示の消灯時間。(x1ms) End If End If Wait 1 Goto Ledmemory1 ' ' * ハズレの場合 * ' Ledmemory6: Temp1 = Gdata(stghit) '正解のLEDを点灯させる。 Gosub Bintobit 'バイナリー数からビットに変換する。 Temp3 = 0 For Temp1 = 1 To 8 If Temp3 = 0 Then '点灯か? Then Temp3 = 1 Portc = Temp2 Sound Sp_out , 9 , 15256 '1F 43.7Hzの音を200mS鳴らす。 Else '消灯の場合。 Temp3 = 0 Portc = &B0000_0000 'LEDを全て消灯する。 Sound Sp_out , 9 , 15256 '1F 43.7Hzの音を200mS鳴らす。 End If Next Temp1 ' Tempw1 = Eephiscore(hiscorepos) 'ハイスコアの確認。 If Score > Tempw1 Then 'If ハイスコアを更新したか? Then Tempw1 = Score Eephiscore(hiscorepos) = Score 'EEPROMハイスコアを更新する。 End If Locate 2 , 7 'ハイスコアを表示する。 Lcd Tempw1 ' Ledmemory7: Gosub Swintimer 'Timer 10mS スイッチ入力。 If Swflag = 0 Then Goto Ledmemory7 'スイッチ入力が無いか? Then Swflag = 0 Gosub Beep50ms '4KHzの音を50mS鳴らす。 If Swdata <> &B0000_0001 Then Goto Ledmemory 'If [スタート/ストップ]スイッチ以外か? Then Gosub Lcdinit1 'LCDのカスタム文字を[メニュー用]に変更する。 Goto Main ' ' * [スタート/ストップ]スイッチが押された場合 * ' Ledmemory5: Gosub Beep50ms '4KHzの音を50mS鳴らす。 Gosub Lcdinit1 'LCDのカスタム文字を[メニュー用]に変更する。 Goto Main ' ' ------------------------------------------- ' * LEDを点灯し音程をセットするサブルーチン * ' ------------------------------------------- ' Ledsound: Select Case Temp1 Case 1 : Set Led_1 Compare1a = 9091 '4A 440.0Hz Case 2 : Set Led_2 Compare1a = 7215 '5C# 554.4Hz Case 3 : Set Led_3 Compare1a = 6067 '5E 659.3Hz Case 4 : Set Led_4 Compare1a = 4545 '5A 880.0Hz Case Else : Set Led_5 Compare1a = 3608 '6C# 1108.8Hz End Select Return '############################################################################### ' ' ****************************************** ' * TIMER2 オーバーフロー 割り込みルーチン * ' * LEDのダイナミック点灯用 * ' * 8,000,000Hz / 32 / 256 = 約976.6Hz * ' ****************************************** ' $notransform On 'R23またはR0を使用する命令に自動修正させない。 ' $asm Tint2: PUSH R1 IN R1,SREG 'ステータス・レジスタを待避。 PUSH R24 ; LDS R24,{LEDcounter} CPI R24,$00 BREQ Tint2a1 'If [LED1,2]か? Then CPI R24,$01 BREQ Tint2a2 'If [LED3,4]か? Then ; LDS R24,{Led(5)} '[LED5,LCDバックライト]の場合。 CPI R24,$00 BREQ Tint2a3 'If 輝度が0か? Then STS Ocr2A,R24 'TIMER2の比較器Aにパルス幅を設定する。 SBI Portc,5 '[LED5]を点灯させる。 Tint2a3: LDS R24,{Led(6)} '[LCDバックライト]の場合。 CPI R24,$00 BREQ Tint2a4 'If 輝度が0か? Then STS Ocr2B,R24 'TIMER2の比較器Bにパルス幅を設定する。 CBI PortD,5 '[LCDバックライト]を点灯させる。 Tint2a4: LDI R24,$00 ; Tint2a9: STS {LEDcounter},R24 ; POP R24 Out Sreg , R1 'ステータス・レジスタを復帰 POP R1 RETI ; ; Tint2a1: '[LED1,2]の場合。 LDS R24,{Led(1)} CPI R24,$00 BREQ Tint2a5 'If 輝度が0か? Then STS Ocr2A,R24 'TIMER2の比較器Aにパルス幅を設定する。 SBI Portc,1 '[LED1]を点灯させる。 Tint2a5: LDS R24,{Led(2)} CPI R24,$00 BREQ Tint2a6 'If 輝度が0か? Then STS Ocr2B,R24 'TIMER2の比較器Bにパルス幅を設定する。 SBI Portc,2 '[LED2]を点灯させる。 Tint2a6: LDI R24,$01 RJMP Tint2a9 ; Tint2a2: '[LED3,4]の場合。 LDS R24,{Led(3)} CPI R24,$00 BREQ Tint2a7 'If 輝度が0か? Then STS Ocr2A,R24 'TIMER2の比較器Aにパルス幅を設定する。 SBI Portc,3 '[LED3]を点灯させる。 Tint2a7: LDS R24,{Led(4)} CPI R24,$00 BREQ Tint2a8 'If 輝度が0か? Then STS Ocr2B,R24 'TIMER2の比較器Bにパルス幅を設定する。 SBI Portc,4 '[LED4]を点灯させる。 Tint2a8: LDI R24,$02 RJMP Tint2a9 $end Asm ' ' *************************************** ' * TIMER2 比較一致(A) 割り込みルーチン * ' *************************************** ' $asm Tint2a: CBI PORTC,1 '[LED1]を消灯させる。 CBI PORTC,3 '[LED3]を消灯させる。 CBI PORTC,5 '[LED5]を消灯させる。 RETI $end Asm ' ' *************************************** ' * TIMER2 比較一致(B) 割り込みルーチン * ' *************************************** ' $asm Tint2b: CBI PORTC,2 '[LED2]を消灯させる。 CBI PORTC,4 '[LED4]を消灯させる。 SBI PortD,5 '[LCDバックライト]を消灯させる。 RETI $end Asm ' ' $notransform Off ' ' End '############################################################################### ' ' * メニュー設定用 データ テーブル * ' Menusetdata: Data &H00 '[0] イルミネーション・モード。(サブメニュー 無し) Data &H25 '[1] LEDたたき ゲーム。(サブメニュー = レベル) Data &H35 '[2] ルーレット ゲーム。(サブメニュー = プレーヤー) Data &H34 '[3] LED危機一髪 ゲーム。(サブメニュー = プレーヤー) Data &H24 '[4] LED記憶力 ゲーム。(サブメニュー = レベル) ' ' * メニュー表示用 データ テーブル * ' Menudata: Data " イルミネーション " '[0] イルミネーション・モード。 Data " LEDタタキ ゲーム " '[1] LEDたたき ゲーム。 Data " ルーレット ゲーム " '[2] ルーレット ゲーム。 Data " LEDキキイッパツ " '[3] LED危機一髪 ゲーム。 Data " LED キオクリョク " '[4] LED記憶力 ゲーム。 ' ' * 大数字 キャラクタ データ テーブル * ' Bignumbers: Data &H00 , &H02 , &H01 , &H00 , &H03 , &H01 '大数字[0] Data &H20 , &H00 , &H20 , &H20 , &H00 , &H20 '大数字[1] Data &H05 , &H04 , &H01 , &H00 , &H03 , &H06 '大数字[2] Data &H05 , &H04 , &H01 , &H07 , &H03 , &H01 '大数字[3] Data &H00 , &H03 , &H01 , &H20 , &H20 , &H01 '大数字[4] Data &H00 , &H04 , &H20 , &H07 , &H03 , &H01 '大数字[5] Data &H00 , &H04 , &H20 , &H00 , &H03 , &H01 '大数字[6] Data &H05 , &H02 , &H01 , &H20 , &H20 , &H01 '大数字[7] Data &H00 , &H04 , &H01 , &H00 , &H03 , &H01 '大数字[8] Data &H00 , &H04 , &H01 , &H20 , &H03 , &H01 '大数字[9] Data &H20 , &H20 , &H20 , &H20 , &H20 , &H20 '大数字[スペース] ' ' * イルミネーション・モード用 点灯パターン データ・テーブル * ' Illumidata: Data &B0000_0010 , 127 '右回りで回転。 Data &B0000_0100 , 127 Data &B0001_0000 , 127 Data &B0000_1000 , 127 Data &B0000_0010 , 127 Data &B0000_0100 , 127 Data &B0001_0000 , 127 Data &B0000_1000 , 127 Data &B0010_0000 , 255 '[星]点灯。 Data &B0000_0000 , 255 ' Data &B0000_0110 , 255 '[橙・青]点灯。 Data &B0001_1000 , 255 '[緑・桃]点灯。 Data &B0000_0000 , 127 Data &B0000_1010 , 255 '[橙・緑]点灯。 Data &B0001_0100 , 255 '[青・桃]点灯。 Data &B0000_0000 , 127 Data &B0001_0010 , 255 '[橙・桃]点灯。 Data &B0000_1100 , 255 '[青・緑]点灯。 Data &B0000_0000 , 127 Data &B0010_0000 , 255 '[星]点灯。 Data &B0000_0000 , 255 ' Data &B0011_1110 , 255 '[全]点灯。 Data &B0000_0000 , 255 ' Data &HFF ' ' * LEDたたきゲーム * ' Ledattacktime: 'レベル毎の打撃許容時間。(Timer1の設定値) Data 23437% , 1562% 'レベル[1] (3s , -0.2s) Data 15625% , 1171% 'レベル[2] (2s , -0.15s) Data 7812% , 468% 'レベル[3] (1s , -0.06s) Data 6250% , 390% 'レベル[4] (0.8s , -0.05s) Data 3906% , 195% 'レベル[5] (0.5s , -0.025s)