バイナリエディタを真似して作ってみた

追記2018/02/16:本家のが公開されているみたいです
 おふがお氏のバイナリエディタ公開場所→http://offgao.net/poke/
 >このサイトの内容またはアドレスを、NAVERまとめへ転載・引用・掲載することを禁ず。





さっきの記事を書いたのはこちらの動画を見て自分も使ってみたかったからです
そして今から書く記事もそうです
(ソースが無ければ作ればいいという発想ですw)


さっきの記事の方法を使って
ボックスのステータス欄に書き込んでいます

BGM変更も無ければUIも微妙に違います


WRA1:D9B4 21 00 D0         ld   hl,D000;開始したときはD000に合わせておきます
WRA1:D9B7 CD 0D DA         call DA0D;キー入力関連
WRA1:D9BA E5               push hl;描画中はhlを退避
WRA1:D9BB 54               ld   d,h
WRA1:D9BC 5D               ld   e,l
WRA1:D9BD 3E F8            ld   a,F8;deを描画する先頭にあわせます
WRA1:D9BF 83               add  e
WRA1:D9C0 5F               ld   e,a
WRA1:D9C1 38 01            jr   c,D9C4;dに繰り下がり
WRA1:D9C3 15               dec  d
WRA1:D9C4 06 12            ld   b,12;ループ回数
WRA1:D9C6 21 AB C3         ld   hl,C3AB;描画位置の指定
WRA1:D9C9 3E 7C            ld   a,7C;横枠ここから18回ループ
WRA1:D9CB 22               ldi  (hl),a
WRA1:D9CC 7A               ld   a,d
WRA1:D9CD CD 01 DA         call DA01;dの上位ビットを描画
WRA1:D9D0 7A               ld   a,d
WRA1:D9D1 CD 03 DA         call DA03;dの下位ビットを描画
WRA1:D9D4 7B               ld   a,e
WRA1:D9D5 CD 01 DA         call DA01;eの上位ビットを描画
WRA1:D9D8 7B               ld   a,e
WRA1:D9D9 CD 03 DA         call DA03;eの上位ビットを描画
WRA1:D9DC 3E 7F            ld   a,7F;空白
WRA1:D9DE 22               ldi  (hl),a
WRA1:D9DF 1A               ld   a,(de)
WRA1:D9E0 CD 01 DA         call DA01;(de)の上位ビットを描画
WRA1:D9E3 1A               ld   a,(de)
WRA1:D9E4 CD 03 DA         call DA03;(de)の上位ビットを描画
WRA1:D9E7 3E 7C            ld   a,7C;横枠
WRA1:D9E9 22               ldi  (hl),a
WRA1:D9EA 3E 0B            ld   a,0B;次の行へ
WRA1:D9EC 85               add  l
WRA1:D9ED 6F               ld   l,a
WRA1:D9EE 30 01            jr   nc,D9F1;hに繰り上がり
WRA1:D9F0 24               inc  h
WRA1:D9F1 1C               inc  e
WRA1:D9F2 20 01            jr   nz,D9F5;dに繰り上がり
WRA1:D9F4 14               inc  d
WRA1:D9F5 05               dec  b
WRA1:D9F6 20 D1            jr   nz,D9C9;ループ範囲ここまで
WRA1:D9F8 21 4B C4         ld   hl,C44B
WRA1:D9FB 36 ED            ld   (hl),ED;カーソル黒を描画
WRA1:D9FD E1               pop  hl
WRA1:D9FE C3 B7 D9         jp   D9B7;最初に戻ります(hlの指定を除く)


WRA1:DA01 CB 37            swap a;上位ビットと下位ビットを入れ替えます

WRA1:DA03 E6 0F            and  a,0F;aを下位ビットだけにします
WRA1:DA05 C6 F6            add  a,F6;数字を文字に変換します
WRA1:DA07 30 02            jr   nc,DA0B;アルファベットの場合オーバーフローします
WRA1:DA09 C6 60            add  a,60;アルファベットを文字に変換します
WRA1:DA0B 22               ldi  (hl),a
WRA1:DA0C C9               ret  


WRA1:DA0D CD 67 38         call 3867;キー入力を取得します(VC版ならこれでいいはず)(赤初期ならcall 3879
WRA1:DA10 F0 B3            ld   a,(ff00+B3);今入力されたキー入力
WRA1:DA12 CB 5F            bit  3,a;スタートが押された場合
WRA1:DA14 28 02            jr   z,DA18
WRA1:DA16 C1               pop  bc;メインルーチンを飛ばすための空打ち
WRA1:DA17 C9               ret;バイナリエディタを終了する
WRA1:DA18 CB 57            bit  2,a;セレクトが押された場合
WRA1:DA1A 28 06            jr   z,DA22
WRA1:DA1C 01 B7 D9         ld   bc,D9B7
WRA1:DA1F D1               pop  de;戻り先を変更するために空打ちします
WRA1:DA20 C5               push bc;戻り先をバイナリエディタの最初にしておきます
WRA1:DA21 E9               jp   hl;現在のアドレスから実行します
WRA1:DA22 47               ld   b,a;今入力されたキーをbに退避します
WRA1:DA23 F0 B4            ld   a,(ff00+B4);入力されているキーをcに入れておきます
WRA1:DA25 4F               ld   c,a
WRA1:DA26 CB 70            bit  6,b;上が入力された場合
WRA1:DA28 28 04            jr   z,DA2E
WRA1:DA2A 3E FF            ld   a,FF;-01をaに入れておきます
WRA1:DA2C 18 15            jr   DA43
WRA1:DA2E CB 78            bit  7,b;下が入力された場合
WRA1:DA30 28 04            jr   z,DA36
WRA1:DA32 3E 01            ld   a,01;01をaに入れておきます
WRA1:DA34 18 0D            jr   DA43
WRA1:DA36 CB 60            bit  4,b;右が入力された場合
WRA1:DA38 28 04            jr   z,DA3E
WRA1:DA3A 3E 10            ld   a,10;10をaに入れておきます
WRA1:DA3C 18 05            jr   DA43
WRA1:DA3E CB 68            bit  5,b
WRA1:DA40 C8               ret  z;方向キーが入力されていない場合描画に進みます
WRA1:DA41 3E F0            ld   a,F0;左が入力された場合は-10をaに入れておきます
WRA1:DA43 CB 41            bit  0,c;Aが入力されている場合
WRA1:DA45 28 03            jr   z,DA4A
WRA1:DA47 86               add  (hl);現在のアドレスの中身にaを加算します
WRA1:DA48 77               ld   (hl),a
WRA1:DA49 C9               ret  
WRA1:DA4A CB 49            bit  1,c;Bが入力されていた場合
WRA1:DA4C 28 03            jr   z,DA51
WRA1:DA4E 84               add  h;現在のアドレスの上位バイトにaを加算します
WRA1:DA4F 67               ld   h,a
WRA1:DA50 C9               ret  
WRA1:DA51 CB 7F            bit  7,a;aがマイナスだった場合
WRA1:DA53 28 05            jr   z,DA5A
WRA1:DA55 85               add  l;現在のアドレスの下位バイトにaを加算します
WRA1:DA56 6F               ld   l,a
WRA1:DA57 D8               ret  c
WRA1:DA58 25               dec  h;hに繰り下がり
WRA1:DA59 C9               ret  
WRA1:DA5A 85               add  l;aがプラスだった場合
WRA1:DA5B 6F               ld   l,a;現在のアドレスの下位バイトにaを加算します
WRA1:DA5C D0               ret  nc
WRA1:DA5D 24               inc  h;hに繰り上がり
WRA1:DA5E C9               ret  


注意:むやみに変なところを書き換えるとプログラムが暴走してデータが壊れることがあるかもしれません
いじるならある程度は知識をつけておいたほうがいいです
また、変にいじってデータが消えた場合の保証は出来ませんのであしからず


実行方法はこちらの動画を見てみると
「なかよしバッヂ」でも任意コードが実行出来るようです
やり方は
・サファリゾーンに1回入って即効で出る
・育て屋さんにニックネーム「てえるのの」を預けておく
その後「なかよしバッヂ」を実行すればD9B4から開始できるはずです



操作方法は
セレクトで今指しているアドレスをcallしてD9B7に復帰
スタートで終了
上下キーで指しているアドレスを+-1
左右キーで指しているアドレスを+-10
Bを押しながら上下キーだと指しているアドレスを+-100
Bを押しながら左右キーだと指しているアドレスを+-1000
Aを押しながら上下キーだと指しているアドレスの中身を+-1
Aを押しながら左右キーだと指しているアドレスの中身+-10




ところで「なかよしバッヂ」でも実行できるといってた動画のブロマガ
4かい」でFA67(DA67のコピー)から実行出来ると書いてあるので
このバイナリエディタの後(DA5Fから空いてます)にプログラムを書くにはちょうどいいアドレスかもしれませんね

追記2019/04/02:
>SELECTで終了とするとアイテム整理のコマンドと被ってしまい、意図せずセレクトバグを起こしてしまう恐れがあると考え、私はSTARTとSELECTを入れ替えて使わせていただいております。一考の余地はあると思うのですが、いかがでしょうか。
と、コメントに頂いたので入れ替えてみました

コメント

afver

No title
やり方をもう少し詳しく教えてもらえませんか?

thfan

No title
> afverさん
どこの事か分からないけど、こんな感じ↓でいいのかな?

>WRA1:D9B4 21 00 D0 ld hl,D000 ;開始したときはD000に合わせておきます
だったら
21 → 00 → D0
の順で入力して、そのまま次の行
→ CD → 0D → DA
を入力します。
これを最後(WRA1:DA5E C9 ret)まで繰り返します

afver

No title
> thfanさん
返信ありがとうございます(^^)
入力をするときはその座標のところで「5かいバグで座標を使ってバイナリ打ち込み」の記事にあるコードを実行すればいいんですか?

thfan

No title
> afverさん
そうですね
ついでに該当記事に追記しておきました

’M

No title
お世話になっております。当記事を拝見致しました後、自分なりにニモニックを勉強し、現在練習がてらにマップチップを編集するプログラムを作ろうとしています。
なんとかinvalid opcodeの発生を防ぐまでには至ったのですが(知識ゼロからのスタートなので、本当にこのレベルです…)、肝心のキー入力が受け付けされず、何が原因なのか分からないという状況です…
つきましては、お時間がある折で結構ですので、添付したプログラムの内容を添削していただけると嬉しく存じます。なお、キーワードは「なかよし」です。
厚かましいお願いで恐縮ですが、何卒よろしくお願い申し上げます。

thfan

No title
> ’Mさん
自分も知識ゼロからだったので結構アドリブで処理してたりします(ぇ
キー入力に関しては、キー入力がaのレジスタに入ったままなので
>CB 41 bit 0,c ;Aが入力された場合
の所だったら
bit 0,a
という感じにすれば動くはず

’M

No title
ありがとうございます!無事反応するようになりました。
追加でもう一件お聞きしたいのですが、上記バイナリエディタにおける「Aを押しながら上下」のような操作はどのように実現しているのですか?

thfan

No title
> ’Mさん
上下の分岐内でまたAを押しているかの判定で分岐すれば大丈夫です
また、aレジスタを途中で使う場合は
4F ld c,a
等で別のレジスタに退避させたり等で対処しています
CB 41 bit 0,c ;Aが入力されている場合
と、cレジスタで判定しているのはこのためです

ちなみに上記プログラムでは入力されているキーを取得する所を
F0 B4 ld a,(ff00+B4) で取得しちゃってますが、たぶん
F0 B3 ld a,(ff00+B3) で大丈夫な気はする

’M

No title
迅速なご対応ありがとうございます。検証したところ、FFB3はキー入力の有無を、FFB4はキー入力の継続を監視しているようですね。

利便性向上のため、あれから操作方法を少し変更し、現在はc,dレジスタを用いて(hl)=タイルの番号をバックアップしたり復元したりといった動きを作っているのですが、ここでまた一つ問題が…

[カーソル移動処理後に元のタイルをcに退避→dに予め入れたタイルを(hl)へ→ret→call 3867→カーソル移動処理前にcを(hl)へ]とすると、キーを取得する際にcレジスタが上書きされてしまうらしく、どのタイミング(あるいはどのレジスタ)でバックアップを取れば良いのか迷っている状況です。

何度もお手数おかけし大変申し訳なく存じますが、お力添えのほど何卒よろしくお願い致します。なお、キーワードは「つうしんじゅんびちゅう!」です。加えて、実際に動作させる上ではDB00から打ち込んでいただきますようお願いします。

thfan

No title
> ’Mさん
バックアップをとる先はレジスタ以外にも
スタックを使う方法や
E5 push hl
21 xx yy ld hl,yyxx
71 ld (hl),c
E1 pop hl
などとする方法も取れます
xxyyは適当に空きスペースを用意してください

’M

No title
お久しぶりです。例のプログラムが正常に動作するようになりましたので、ご報告いたします。(SELECTの挙動にこだわっていたら思いのほか時間を食ってしまった…)
最適化の余地はあるかと思いますが、ひとまずこれにて完成とします。
パスは「いしはら」です。しばらくの間あげておきますので、お時間がありましたら見てやって下さい。

thfan

No title
> ’Mさん
完成おめでと~
ちゃんと動作するのが作れるとなんかうれしいですよね(^ω^)

というわけで試しに動かしてたら遅くなりましたorz
面白かったです!(小並感)
余計なお世話かもしれませんが、ブログか何かで公開してみてはいかがでしょうか?

’M

No title
楽しんでいただけたようで何よりです笑
ブログですか…考えてもいませんでしたが、私としても5かいプログラミングの楽しさを広めたいという思いはあります。
ウェブページには手をつけなくなって久しいのですが、近いうちに公開しようと思います!
何から何までお世話になりました(^^)

Bandicoot

No title
描画をする処理の書き方がわからないのでお教え願います。
また、アセンブリ言語を学ぶのにお勧めのサイト等ありましたらそれもお願いします

’M

No title
ご無沙汰しております。この度先日のプログラムを公開いたしましたので、ご報告いたします。
ttp://pkmn.tk
自作プログラムだけを淡々と載せるのもつまらないので、簡単なものですがプログラミングの手引きのようなものを書いてみました。お気軽にご訪問ください。また、修正箇所等ございましたらご連絡ください。励みになります(笑)

ところで、上記のバイナリエディタを少し縮めてみました(名前欄からアクセスできます)。これで「やまぐち」も使用できるようになります。
ご迷惑でなければ、更なる最適化にあたってご想定されているものの実行に至っていない点などございましたらご報告願います。


> Bandicootさん
横から申し訳ございませんが、お答えいたします。

描画処理におきましては、バッファを保持しているC3A0から360バイトの領域を弄ると良いかと。

言語の学習に関しましては、ポケモン赤緑に限った話であれば「ぽけもんばぐ・りっちーず」様が参考になると思います。
残念ながら現在は本家の閲覧はできないので、wayback machineをご利用ください。

Bandicoot

No title
> ’Mさん
ありがとうございます。
本当に助かりました。
申し訳ありませんが、またわからないことがありましたらお願いします

thfan

No title
> ’Mさん
お、サイトができたんですね。
見にいきますね~

バイナリエディタ短縮(゚∀゚)
短い方が入力が楽になっていいですよね
最適化は今のところは思いつかないです

あと、代わりに返信ありがとね

Bandicoot

No title
乱数を生成するにはどうすれば良いでしょうか。カセットは緑後期ロットです。

thfan

No title
> Bandicootさん
なんとか探し出してみました
CD 7A 3E call 3E7A
でaレジスタに乱数が生成されるはず

Bandicoot

No title
> thfanさん
ありがとうございます。

k

質問失礼しますm(_ _)m
このプログラムを全て書いた後に何をすればバイナリエディタが使えるようになるのでしょうか?
また18回ループ書かれているところは18回同じものを書き込めばよろしいのでしょうか?
答えていただけると幸いですm(_ _)m

thfan

Re: タイトルなし
> 質問失礼しますm(_ _)m
> このプログラムを全て書いた後に何をすればバイナリエディタが使えるようになるのでしょうか?
> また18回ループ書かれているところは18回同じものを書き込めばよろしいのでしょうか?
> 答えていただけると幸いですm(_ _)m

まずサファリゾーンに1回入って即効で出て(やったほうが安全)
そして育て屋さんにニックネームを「てえるのの」にしたポケモンを預けておいて
「なかよしバッヂ」を実行すれば使えます

実行するだけなら横のコメントは関係ありませんので
18回ループのところも1回書き込めば大丈夫です

k

>thfanさん
大変丁寧に質問に答えてくださりありがとうございます
ひとつだけ確かめたいことがございますので再度質問させて頂きたいのですが
打ち込んだプログラムはD9B4が開始アドレスになるというのは具体的にどのような行動を指すのでしょうか?
書いてある通りにプログラムを打ち込んだら勝手にバイナリエディタが起動するということですか?

thfan

Re: タイトルなし
kさん
> 打ち込んだプログラムはD9B4が開始アドレスになるというのは具体的にどのような行動を指すのでしょうか?

D9B4 からのプログラムを実行するようにニックネーム等を設定してください
という意味です
「てえるのの」というニックネームをつけることで D9B4 から実行するように設定できます


> 書いてある通りにプログラムを打ち込んだら勝手にバイナリエディタが起動するということですか?

プログラムを打ち込んでも「なかよしバッヂ」を使わなければバイナリエディタは起動しません

-

青VCでのキー入力取得
青VCでは388Fへのcallでキー入力が取得できるようです

nanashi

jr c+1 38 01 を実行するとフリーズする件
コメント失礼致します。知識ゼロからこのバイナリエディタを打ち込み、実行してるものです。
vc版だと全て問題なくバイナリエディタのプログラムの打ち込みが出来たのですが、実機(初期版赤)でバイナリエディタを打ち込もうとすると最初の方の「38 01」の01で必ずフリーズしてしまいます。
何か初期版では動作が違うのでしょうか?
非公開コメント

プロフィール

thfan

好きなキャラクターはフランドール・スカーレットです

フランちゃんについて妄想や空想、夢想などをしてみたり考察してみたりしてる人です