ひとしれずひっそり

ひとしれずひっそり

主にソフトに関することをメモしていきます。過程をそのまま書いていたりするので間違いが含まれます。鵜呑みしない様に。

Duolingo 467日目

Duolingoで新たにMathとMusicのコースを選択している。
これらは英語で問題が出されるので躊躇していたが、今のところそれほど難しい表現が出ていない。

Mathで文章問題がたまに出て理解が足りてない時もあるが文脈から判断したりしている。
四則演算から分数に入ったところだ。昔は九九は見た瞬間に関係する数値が思い浮かんでいたが、簡単な物でも頭で計算しないと回答が出せず時間がかかってしまうばかりか間違ったりするのでいいリハビリになる。

Musicは音符を瞬時に読むのが難しい。

久しぶりにダイヤモンドリーグに1位で昇格した。
まだ1日しか経っていないがDiamond Leagueの上位は既に7000XPを超えている。 今回の昇格では1週間に6000XPで昇格したが一体どうやったらこんなに稼げるのかと思ってしまう。

YAML.load に permitted_classes を渡す

Time を 書き出しているYaml ファイルの読み込みで以下のエラーが発生。

`find': Tried to load unspecified class: Symbol (Psych::DisallowedClass)

YAML.load に permitted_classes を渡す必要があるようだ。

stackoverflow.com

YAML.load(filepath)
#  ↓
YAML.load(filepath, permitted_classes: [Time, Symbol])

Alertが表示されない

SwiftUIでalert()を使ってアラート表示している箇所があるが、いつの間にか表示されたりされなかったりする様になっていた。

ネットで調べてもしっくりくる回答がなかった。

画面遷移直後に表示される箇所があり、それが表示されると以降も問題ないことがわかった。
onApper()でフラグをセットし表示する様にしていたが、ひょっとするとこれが悪いのかもしれない。
Viewの階層が深くて、Alertを表示した時にその階層のどこかに紛れ込んでいて隠れて見えてないということかもしれない。
表示に使用しているフラグは確かにtrueになっているし、描画の箇所にも来ている。

それならばとDispatchQueue.main.asyncAfter()でフラグをセットするのを遅らせてみたら、しばらく試した限りではうまくいってそうだ。

この例ではViewは簡単なので問題はでていないが、対処例ということで載せておく。

gist.github.com

TK-80 save / load 実装

TK-80のモニターでは save / load はシリアル出力して外部に回路を加えることで音声データとしてカセットに記録できる様になっている。
TK-80BSがボーレート300だったとあるのでおそらく300bspではないか?
これをエミュレートしても良いのだがクロックが安定していない(300bpsならもしかすればという気もするが)のでデコードがうまく行くか分からないし面倒だし遅い。

全てが手中にあるので、メモリを全部ダンプすることにした。
'S'キーで'board.hex'ファイルに書き出し、'L'キーでそれをメモリに書き込む。

うっかりすると'S'キーで上書きしてしまうので、rakeコマンドでコピーを作るとか後で考えよう。

これで一通り機能は完成した。
5年前にやりかけてたのが一応形になった。

これを機にやってみたいことが2つあって、

  1. あのゲームが動くのか?
    • GUIをどうするかはあるのだがDXOpalでいけるのか?
  2. mruby が動かせるのか?
    • おそらくメモリが不足してダメだと思うのだが、8bit限定として機能制限版とか…
    • そもそもmrubyの知識が乏しいので最初から無理な感じはしている。

のでやるともやらないとも今のところどちらとも言えない。

github.com

TK-80 割込動作実装

割込も動作するようになった。

EIはEIの次の命令を実行すると割込可能になるとあった。

EIの次を実行した後に割込が入る様に実装していた。
これで試していると思った様な動作にならなかった。
TK-80ではステップモードにするとブレークポイントが未設定だと1命令ずつ実行されるのだが、同じアドレスに留まって先に進まなかった。

モニタープログラムの出口はこの様になっている。

;;
;; REGISTER RESTORE
;;
RESRG:  LHLD  SSAVE
        SPHL            ; PS RESTORE
        LHLD  PSAVE
        PUSH  H         ; PC STOERD IN USER STACK
        LHLD  LSAVE
        PUSH  H         ; HL STOERD BELOW USER STACK
        LHLD  FSAVE
        PUSH  H         ; PSW STOERD BELOW USER STACK
        LHLD  CSAVE
        MOV   C,L
        MOV   B,H       ; BC RESTORED
        LHLD  ESAVE
        XCHG            ; DE RESTORED
        POP   PSW       ; PSW RESTORED
        POP   H         ; HL RESTORED
        EI              ; INTERRUPT ENABLED
        RET             ; PC RESTORED & GO TO USER CONTR ROUTINE

最後にEIがっあって次にRETがある。
EIの次の命令であるRETを実行した後に割込が入ることになる。
RETはPSAVEに保存されたアドレスに飛ぶことになる。
モニタープログラムでは割込が入った時のアドレスがPSAVEに入っている。

仮に8200Hアドレスが入っているとして、ここで割込が入るとRST 7が実行されてスタックにPC(8200H)が積まれその後BRENTに飛ぶ。

;;
;; BREAK ENTRY
;; BREAK & ONE STEP OPERATION
;;
BRENT:  XTHL            ; HL<-->PC(SAVED)
        SHLD  PSAVE     ; PC(LO)$83E0,PC(HI) $83E1 SAVED
        PUSH  PSW       ; PSW SAVE
        LXI   H,4H

        DAD   SP        ; HL<--SP
        POP   PSW       ; PSW RECOVER
        SHLD  SSAVE     ; SP(LO)$83E2,SP(HI)$83E3 SAVED
        
        POP   H         ; HL RECOVER

XTHLでは積まれた8200HがPSAVEに保存される。同様にスタックのアドレスはSSAVEに保存される。
またモニターから抜ける時にはRESRGで逆にSSAVEをスタックに戻してRETでPSAVEに飛ぶことになる。
となるといつまで経っても8200Hから抜けなくなる。

本当はもう1つ進んでから割込が入って欲しい。
RETで割込から戻ってから1命令実行して割込がかかる様にしたい。
EIはEIの次の命令を実行すると割込可能となるが、実際に割込が入るのは2命令後とすると良さそうだ。

2命令後に変た事で意図した様に動作する結果となった。
ここに辿り着くまで結構かかってしまった。

youtu.be

EIは何で次の命令後に割込可能になるとか思っていたが、割込を動かすためには必要な要件だったことがわかった。
XTHLもほとんど使ったことがなかった様な気がするが、よく考えられているなと改めて感心した。

後はセーブ、ロード機能があれば完成となる。

SyscallError: setpriority(PRIO_DARWIN_ROLE, 5562, 3): No such process

Objcで書かれていたアプリをSwiftに移行する準備としてObjcの大半のコードをフレームワークに移した。
Embedded framework として埋め込むのだが、実行時に参照できる様に Runpath Search Paths に Frameworkのある場所として @executable_path/Frameworks を指定することで参照できる様になる。

これで問題なさそうだったので申請して結果を待っていたのだが、手元にiOS 12iPadがあって 試しにTestFlight からインストールしてみると起動してすぐにクラッシュする。慌てて審査を取り消した。

Xcodeから起動して直接確認してみようとするが、古くてDeviceSupport ファイルがなくて起動できない。
こちらを参照して組み込んで起動できる様になった。

qiita.com

iPadにはiOS 12.5.7がインストールされているが iOS 12.4 までしかなく動かせないかもと頭をよぎったがこれで試して問題なかった。

戻って、Xcodeから起動すると __abort_with_payload で終了している。
検索しても有用な情報がない。
コンソールには

SyscallError: setpriority(PRIO_DARWIN_ROLE, 5562, 3): No such process

と表示されている。
これで検索するとどうやら Framework が見つからない様だ。

試しに、該当FrameworkをOptionalにしてみるともう少し先まで行って、Framework内にあるメソッドが見つからない異常で終了している。やはりFrameworkが読み出せいなための様だ。
色々試してみるが解決に至らなかった。

iOS12で問題があるのは分かったので、iOS13からサポートすることとしたいが、iOS13のデバイスがないので大丈夫かは分からない。
しかし、iOS13が動くデバイスはiOS15まで動くので、シミュレータではiOS15.5で確認できているので何かあったら最新にしてくださいで対応することとしよう。