フォト
2025年3月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
無料ブログはココログ

« Propeller始めました(18) ポータブルゲーム機の実装 3 | トップページ | Propeller始めました(20) ポータブルゲーム機の実装 5 »

2016年2月 5日 (金)

Propeller始めました(19) ポータブルゲーム機の実装 4

実質的にSDカードからブードが出来ることが分かったので、今度はブートするプログラムを
選択できるランチャーメニューを実装しました。

ランチャープログラムはEEPROM上に書きこみます。
ハードウエア的にリセットがかかるとEEPROM上のランチャーメニューが起動します。

ランチャープログラムは、選択されたプログラムをSDカードからロードしてメインRAM
に書きこみます。その後ソフトウェアリセットにより、ロードしたプログラムが実行されます。

Dscn4830

操作としては、
ジョイスティック操作でメニューをスクロールさせて起動したいプログラムを選択します。
選択中のプログラムの説明を下段に表示します。

リセットボタンを押すことランチャープログラムがロードされて、メニュー画面に戻ります。

実際の操作の様子
(デジカメでの動画撮影なのでちょっと映像が劣化しています)


メニューに表示されるプログラム一覧は、SDカード内のテキストファイルに定義して
います。ランチャープログラムがその内容を読んで表示します。

ランチャーさえあれば、簡単にプログラムの入れ替えが出来ます。
SDカードだとプログラマやシリアル接続不要ですね。
こほ方式は色々と使えそうです。

ランチャープログラムのソースはこんな感じです。

{{
    LameStation SDカードローダー
}}

CON
    _clkmode        = xtal1 + pll16x
    _xinfreq        = 5_000_000
  
    'SDカード PIN接続
    sdDO  = 16        'EX0(P16)
    sdCLK = 17        'EX1(P17)
    sdDI  = 18        'EX2(P18)
    sdCS  = 19        'EX3(P19)

VAR
    'メニュー情報
    byte    text[2048]  'メニューファイルバッファ
    long    index[32]   'インデックス
    long    count       '登録数
    long    pos         'メニューファイルバッファ用ポインタ

    'メニュー表示用
    long    mnTop       'タイトル表示開始先頭番号
    long    mnSelect    'メニュー上の選択位置(0~3)

OBJ
    cm          : "LameSerial"
    sd          : "SD-MMC_FATEngine"
    lcd         : "LameLCD"
    gfx         : "LameGFX"
    txt         : "LameText"
    fn          : "LameFunctions"
    ctrl        : "LameControl"
    font_6x8    : "gfx_font6x8_normal_w"
    font_6x8b   : "gfx_font6x8"
    font_4x6    : "gfx_font4x6"

PUB Main | ctrlChange,prevCtrl,ctrlCode,fname,p
    mnTop := 0          'ランチャーメニューリスト先頭
    mnSelect := 0       '選択カーソル先頭
    prevCtrl := 0
    ctrlCode := 0
    cm.Start

    lcd.Start(gfx.Start)        
    gfx.ClearScreen(0)
  
    count:= LoadMEnu    'メニューデータをSDカードからロード
    DrawMenu            'ランチャーメニュー表示

    'ランチャーメニュー 操作
    repeat
        '操作状態取得
        ctrl.Update     
        prevCtrl := ctrlCode
        if ctrl.B 'タイトルを選択決定した
            p:= index[mnTop+mnSelect]
            repeat while text[p++] <> 0 
            fname := @text[p]
            quit           
        if ctrl.Down
            ctrlCode := ctrl.Down
        elseif ctrl.Up
            ctrlCode := ctrl.Up
        else
            ctrlCode := 0       
        if prevCtrl <> ctrlCode
            '操作に変化があった場合は表示の更新を行う             
            if  ctrl.Down 
                if mnSelect < 3
                    mnSelect++
                else
                    if mnTop < count-4
                        mnTop++
                    else
                        mnTop := 0
                        mnSelect := 0 
            if ctrl.Up
                if mnSelect > 0
                    mnSelect--
                else
                    if mnTop > 0
                        mnTop--
                    else
                        mnTop := count-4
                        mnSelect := 3
            if ctrlCode <> 0
                DrawMenu 
   
    Run(fname)

'メニュー画面表示
PUB DrawMenu |title,fname,info,i,p
    'メニュー部    
    gfx.ClearScreen(0)
    txt.Load(font_6x8b.Addr, " ", 6, 8)
    txt.Str(string("[Menu]"),0,0)
    
    'タイトルリスト部
    txt.Load(font_6x8.Addr, " ", 6, 8)
    repeat i from mnTop to (mnTop+4 <# count)-1               
        title := @text[index[i]]
        if (i<10)
            txt.Dec(i,12, 8 + (i-mnTop)<<3)     
        else
            txt.Dec(i, 6, 8 + (i-mnTop)<<3)     
        txt.Str(String(":"), 17, 8 + (i-mnTop)<<3)
        txt.Str(title, 23, 8 + (i-mnTop)<<3)
    txt.Str(String("*"), 0, 8 + (mnSelect)<<3)
       
    '選択したタイトルの説明表示
    p:= index[mnSelect+mnTop]
    repeat while text[p++] <> 0 
    repeat while text[p++] <> 0 
    txt.Load(font_4x6.Addr, " ", 4, 6)  
    txt.box(@text[p],0,40,128,18)    
    lcd.DrawScreen    

'指定イメージファイルによるブート
PUB Run(filePathName) : statusVal | statusStr 
  ifnot sd.partitionMounted
    Mount(0)

  statusStr := \ sd.bootPartition(filePathName)
  statusVal :=   sd.partitionError

PRI Mount(partition) : statusVal | statusStr
  ifnot sd.CogStatus
    Start    
  statusStr := \ sd.mountPartition(partition)
  statusVal :=   sd.partitionError

PRI Start : okay | statusStr     
  ifnot sd.CogStatus
    okay := sd.FATEngineStart(sdDO, sdCLK, sdDI, sdCS, -1, -1, -1, -1, -1)

'SDカードからメニュー情報を取得する
PUB LoadMenu | d,i
    pos  := 0
    i := 0

    'SDカードのマウント
    sd.fatEngineStart(sdDO, sdCLK, sdDI, sdCS, -1,-1,-1,-1,-1) 
        sd.mountPartition(0) 
    if strcomp( sd.listEntry(@myfname), @myfname )
        abort

    'メニューファイルのオープン    
    sd.openFile( @myfname, "R" ) 
    if sd.partitionError
       cm.Str( string("File I/O Error.",13) )
       abort
    
    'データの読み込み
    index[i]:=0
    repeat while d := sd.readByte    
       if d == "|" 'カラム区切り
            text[pos++] := 0                  
       elseif d == $0a 'LFは行終端
            text[pos++] := 0
            index[++i]:= pos
       elseif d => 32  'CRはスキップ '通常の文字    
            text[pos++] := d
   
    'ファイルのクローズ
    sd.closeFile
    
    'パーティションのアンマウント
    sd.unmountPartition 
    'エンジン解放
    sd.FATEngineStop
    result := i+1

DAT
'ファイル名
myfname         byte "menu.txt",0    

« Propeller始めました(18) ポータブルゲーム機の実装 3 | トップページ | Propeller始めました(20) ポータブルゲーム機の実装 5 »

Propeller」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: Propeller始めました(19) ポータブルゲーム機の実装 4:

« Propeller始めました(18) ポータブルゲーム機の実装 3 | トップページ | Propeller始めました(20) ポータブルゲーム機の実装 5 »