SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|12|
2025|01|02|03|04|05|06|07|

2004-12-01(Wed) マイコン少年な思い出

  このBlogを書いていてちょっと楽しみなのが「本日のリンク元」である。サミしいことに、今のところ恒常的に固定リンクをしているサイトは自分のウチだけなのであるが、Googleなどの検索エンジンからどんな検索ワードでココに来たかわかるというのも、ちょっと楽しいのである。例えば「google検索(SVX エアコン 修理)」や「google検索(S端子 コンポジット 変換 自作)」なんかだと「ほっほっほっ、ジャストミートじゃろ、えがったのぉ」と嬉しくなるし「google検索(outrun mp3)」とか「BIGLOBE検索(柴咲コウ似)」なんかだと「そりゃ、残念じゃったのぉ」などと失笑できる。

  そんな中「google検索(ベンツネジ 買った)」というのを発見。おいら以外にも例の携帯電話用の特殊ネジを「ベンツネジ」なんて形容する奇特なヤツがいるんだなぁ、と思いつつ検索結果のページにいってみた。すると案の定、奇特な形容だけあって3件しかない。んが、そこで発見した「やねうらおのページ」というのにここ数年に一度という衝撃を受けたのであった。

  このしとには逆立ちしたってかなわねぇずら

  思わず全ページを読み切ってしまった。書いてあることの内容の濃いこと濃いこと。その生活スタイルや子供の頃の思い出など、基本的にフリープログラマの日記なのではあるが、見方を変えるとこれはまるでオリンピック選手の日記ではないか。何しろ視点を置く場所が深い。目指す方向性が自分と同じ方向なだけに、悔しいのなんの。

  なにせ、幼稚園の頃からTK-80をイジり始め、小学生にはBIOSを解析するばかりか、コピープロテクトを発案し、それで金儲けまで実践している。つーか、オイラそのコピープロテクト知ってたよ。考案したのは小学生だったんかいッ!! もーそりゃ、そら恐ろしい快進撃である。海外でたまにみる「小学生の歳で大学卒業」みたいな飛び級を目の当たりにした気分である。

  画像の説明

  オイラも小学6年にしてパソコンショップに通い詰めるわ、中学生になる前にマシン語に手をつけるわ、フロッピーディスクドライブの入手したその日に、友人からもらったFATの破損したシステムディスクをディスクエディタで復旧させるわ、という輝かしい過去(だと勝手に思っている)があるが、そんなの比べ物にさえならないじゃんッ!! 中学の頃、学校のクラブ活動の時間にマイコンクラブにおじゃましたことがあって、ちょうど同級生が今は亡きベーマガのプログラムをシコシコ打ちこみ「動かねぇ」と数人を巻き込んで悩んでいたところへ、ひょいと顔を出しスグさま「Syntax errorって、ここ打ち間違えてるじゃん」と指摘したところ、バケモノを見るような顔をされたことがあったが、いまバケモノを見るような顔をしているのはオイラの方な気がする……。

  オイラも幼稚園から始め、学校に行かずに飯を食わずに熱中し、親にキーボードを隠されたりせずに、PCと無関係な仕事に10年も従事せずに、ひたすらこの道を極めていたら……いや、それでも無理だろうな。オリンピックの選手はいくら幼少の頃からはじめても誰でもなれるわけではないのだ。天性の領域もあるんだろうなぁ。あーぁ、目指す方向性が自分と同じ方向なだけに、こうやって比べてしまうとイカに自分がぼやぼや生きてきたかが歴然としてしまって非常に悔しい。ぐもももも。

  しかしアレだな。以前に軽飛行機の免許を取ろうとロスに通った時に出会った何人かの人達と話していて感じたのだが、人は周囲にいる人間に触発されて変わっていくものなのかもしれない。そういう環境に身を置くだけでも変われるものなのかもしれないなぁ。


2009-12-01(Tue) 不定期刊「メーラを作る」

  周期的なリリースってのは、思いのほかたいへんだ。ある程度のところでキリをつけて、まとめ上げるのが、こんなに難しいとは。

  つーわけで、未だメールは送信できないが、どうにかメールの編集まではできるようにしたMaveである。

  メーラっては、覚え書きを置いておくにもよい場所だ。Maveを使い出してから、memo.txtが巨大に育つことも、hoge38.txtみたいなファイルが散乱することもなくなった。

  興味のある人は使ってみるべし。


2021-12-01(Wed) 「SEVENTH MOON」に指がかかる

  いまのところ、歌唱力の向上のためには、なにしろ音域を上に延ばし、それよりも下の音域の表現力、安定性を上げる、という認識で、日々、喉の筋肉を鍛えまくっている。

  そして週1〜2のカラオケでの練習であるが、定番曲を中心に、ちょくちょく新しい曲を加えつつ、時々、無理目だった曲に改めて挑戦してみるのだ。すると……あれほどに、高さが届かない、原曲の感じが出せない、と思っていた曲がフッと手の届く場所に下りてきていることに気づくのである。別に完璧に歌える状態ではない。あくまで「指がかかった」という感じ。しかし、そう思えた時の気持ちの高揚感といったらない。自分だけなのかな。こういう感覚を抱いているのは。

  今回、気づいたのは、マクロス7の主題歌「SEVENTH MOON」。主題歌なのに劇中では歌われておらず、あまり人気のない歌だが、全編がシャウト混じりで、かなり高音域。体力的にもキツい。しかし、まぁ、なんとか歌い切れるようになった感。

  調べるとマクロス7の放送は1994年下期。自分が23歳の頃だ。ほぼ、全話をリアルタイムで観るほど熱中していた気がする。別にその時から歌を目指していたわけではないが、カラオケに行く機会があれば、いくつかの曲を歌っていた。あれから四半世紀を経て、ようやくそれなりに歌えるレベルまで来たのか。長かったなぁ。

  バサラの曲を歌いこなすことが、ヴォーカル修行の大きな目的のひとつなので、そこに指がかかったことがなんとも嬉しい。引き続き、精度を上げていきたい。


2023-12-01(Fri) WebAssemblyのstackで開発がstuck

 WebAssemblyのひとつだけの使い道」ということで、ボチボチと開発を進めていたのだが、どうにも不可解な動きがあって、理解するまでにだいぶかかってしまった。

  まずは、以下のサンプルコードだ。Wasmの関数に引数として0を渡すと20、非0を渡すと10がログに出力される。

main = ->
    importObjects = {
        console:    { log: (arg) => console.log(arg) },
    }
    obj = await WebAssembly.instantiateStreaming(fetch('test.wasm'), importObjects)
    console.log('call test(0)')
    obj.instance.exports.test(0)
    console.log('call test(1)')
    obj.instance.exports.test(1)
main()
(module
    (import "console" "log" (func $log (param i32)))
    (func (export "test") (param $val i32)
        push        val
        if
            i32.push    10
            call        log
        else
            i32.push    20
            call        log
        end
    )
)

  したがって、結果はこうなる。

call test(0)
20
call test(1)
10

  ところが、以下のようにlog出力をifブロックの外に出すとアセンブルエラーが起きてしまう。

        push        val
        if
            i32.push    10
        else
            i32.push    20
        end
        call        log
test.wat:10:4: error: type mismatch in if true branch, expected [] but got [i32]
            i32.const       10
            ^^^^^^^^^
test.wat:13:3: error: type mismatch in if false branch, expected [] but got [i32]
        end
        ^^^
test.wat:14:3: error: type mismatch in call, expected [i32] but got []
        call        $log
        ^^^^

  これは、以下のようにすると解決する。「ifブロックを出る時にi32を返しますよ」という宣言を加えるわけだ。

        push        val
        if  (result i32)
            i32.push    10
        else
            i32.push    20
        end
        call        log

  そんなら「ifブロックを出る時にi32を『ふたつ』返しますよ」という宣言をしたらどうなるかというと、アセンブルエラーが起きてしまう。

        push        val
        if  (result i32) (result i32)
            i32.push    10
            i32.push    10
        else
            i32.push    20
            i32.push    20
        end
        call        log
        call        log
test.wat:9:3: error: multiple if results not currently supported.
        if  (result i32) (result i32)
        ^^

  「not currently supported.」なので、将来的には可能になるのかもしれないが、現状では認められない、というように読める。

  じゃ、こういうコードはどうか?

        i32.push    100
        push        val
        if  (result i32)
            i32.push    10
            i32.add
        else
            i32.push    20
            i32.add
        end
        call        log

  あらかじめ、スタックに100を積んでおいて、引数として0を渡すと20、非0を渡すと10を加算した値をログに出力させたい……のだが、アセンブルエラーが起きてしまう。

test.wat:12:4: error: type mismatch in i32.add, expected [i32, i32] but got [i32]
            i32.add
            ^^^^^^^
test.wat:15:4: error: type mismatch in i32.add, expected [i32, i32] but got [i32]
            i32.add
            ^^^^^^^
test.wat:17:3: error: type mismatch in function, expected [] but got [i32]
        call        $log
        ^^^^

  こうなることがどうにも理解できなくて、長らくグダグダしていた。MDNのifの項を読んでも、特段なにも触れられていない。が、これは「ifは関数コール」のようなものだ、と理解するべきだという結論にたどり着いた。

  ifブロックに入ったら「スタックの内容は持ち込めない」し「スタックの内容は持ち出せない(ただし返値としてひとつだけは許容される)」ということで、これは関数コールの特性そのものである。これまでのアセンブラ知識が邪魔になって必要以上に理解するのに時間がかかってしまった。

  上記のプログラムは、中で加算せず、加算対象を返値として、外で加算する形とすれば意図した結果が得られる。

        i32.push    100
        push        val
        if  (result i32)
            i32.push    10
        else
            i32.push    20
        end
        i32.add
        call        log

  「スタックの内容は持ち込めない」のはblockも同じだ。上記を書き直すと以下のようになる。

        i32.push    100
blk1:   block   (result i32)
            i32.push    10
            push        val
            br_if       blk1
            drop
            i32.push    20
        end
        i32.add
        call        log

  以下は、引数が0だった場合に、100をログに出力させるプログラムだが、非0だった場合はスタックに100が残ることになる。が、それは許容されるらしい。関数コールと考えれば、それが捨てられるだろうことは、まぁ理解できなくもないのだが。

blk1:   block
            i32.push    100         ;; [ 100
            push        val         ;; [ 100 val
            br_if       blk1        ;; [ 100
            call        log         ;; [
        end
;;                                  ;; [ ???

  では、返値を設定したらどうなるか。様々に試したところ、以下のコードから挙動を掴むことができた。

        i32.push    99              ;; [ 99
blk1:   block   (result i32)
            i32.push    100         ;; [ 99 100
            i32.push    12          ;; [ 99 100 12
            i32.push    11          ;; [ 99 100 12 11
            i32.push    10          ;; [ 99 100 12 11 10
            push        val         ;; [ 99 100 12 11 10 val
            br_if       blk1        ;; [ 99 100 12 11 10
            call        log         ;; [ 99 100 12 11
            drop                    ;; [ 99 100 12
            drop                    ;; [ 99 100
        end
        call        log             ;; [ ???
        call        log             ;; [ ???

  結果はこうなる。

call test(0)
10
100
99
call test(1)
10
99

  引数が0だった場合、brをスルーし、中のlogで10を出力した後、11, 12をdropし、外のlogで100と99を出力して終了する。一方で、引数が非0だった場合、スタックが「99 100 12 11 10」の状態でbrでblockを抜けるが、その際、頭の10が返値となり、blockに入る時の状態である「99」の上に10を積んだ「99 10」という状態でblockを抜けるらしい。

  というわけで、挙動については掴むことができたが、むしろ面倒くさい仕様に思えてならない。さて、だいぶ寄り道してしまったが、本来の目的に戻ろう。