追記(2023/2/10):以下のプログラムは全然正しく音階を表示していませんでした。修正版はこちら→ポケモン赤緑で今流れている曲を鍵盤に表示する その2 - 理科
ポケモン赤緑のなかよしバッヂを使った任意コード実行で今流れている曲を鍵盤に表示しました。
2つのパルスチャンネルのみ出力しています。ウェーブチャンネルとノイズチャンネルの表示は未実装です。
合っているか確かめてません…。また、白鍵と黒鍵を分けずに一列に並べています。
Aボタン入力で脱出できます。
今流れている音楽を鍵盤(?)に表示するやつ作った
— でぃぐ(ゲーム用垢) (@fujidig_game) 2023年2月9日
(合っているか確かめてない; 白鍵と黒鍵を分けずに一列に並べている) pic.twitter.com/K31AjdHSdv
アイスさんの動画を超参考にしました:
【初代ポケモン】ポケモンで作曲をする方法 バグ・任意コード実行 - YouTube
白鍵と黒鍵のあるバージョンも作成してみたいかも。
0xda00からスタート
cd 67 01 21 00 90 06 88 0e 88 cd 36 da 0e f8 cd 36 da 0e 8f cd 36 da cd 81 01 cd 67 38 fa b3 ff cb 47 c0 21 a0 c3 3e 00 cd 41 da 21 dc c3 3e 01 cd 41 da c3 1a da 16 08 78 22 79 22 15 c2 38 da c9 cd 73 da 4f 06 00 78 87 b9 c2 52 da 3e 01 c3 60 da 78 87 3c b9 c2 5e da 3e 02 c3 60 da 3e 00 77 e5 c5 01 14 00 09 77 c1 e1 23 04 78 fe 14 c2 47 da c9 e5 16 00 5f 21 06 c0 19 19 7e 23 4f 7e 47 0a cb 37 e6 0f 4f 21 d6 c0 19 19 7e fe 04 da a1 da fe 06 d2 a1 da d6 04 47 80 80 17 17 81 e1 c9 3e ff e1 c9
ソースコード (https://github.com/ulrikdamm/Assemblerでアセンブルできるものです)
PlaySound = 0x0e33 wTileMap = 0xc3a0 wChannelCommandPointers = 0xc006 wChannelOctaves = 0xc0d6 DisableLCD = 0x0167 EnableLCD = 0x0181 JoypadLowSensitivity = 0x3867 hJoyPressed = 0xffb3 vTileset = 0x9000 SCREEN_WIDTH = 0x14 [org(0xda00)] start: call DisableLCD ld hl, vTileset ld b, 0x88 ld c, 0x88 call CreateTile ld c, 0xf8 call CreateTile ld c, 0x8f call CreateTile call EnableLCD loop: call JoypadLowSensitivity ld a, [hJoyPressed] bit 0, a ret nz ld hl, wTileMap ld a, 0 call do ld hl, wTileMap + SCREEN_WIDTH * 3 ld a, 1 call do # ld hl, wTileMap + SCREEN_WIDTH * 6 # ld a, 2 # call do jp loop CreateTile: ld d, 8 CreateTile_loop: ld a, b ld [hl+], a ld a, c ld [hl+], a dec d jp nz, CreateTile_loop ret do: call calculate_position ld c, a ld b, 0 lp: ld a, b add a, a cp c jp nz, nonhit1 # b + b == cならタイルを1に ld a, 1 jp join nonhit1: ld a, b add a, a inc a cp c jp nz, nonhit2 # b + b + 1 == cならタイルを2に ld a, 2 jp join nonhit2: ld a, 0 join: ld [hl], a push hl push bc ld bc, SCREEN_WIDTH add hl, bc ld [hl], a pop bc pop hl inc hl inc b ld a, b cp 20 jp nz, lp ret calculate_position: push hl ld d, 0 ld e, a ld hl, wChannelCommandPointers add hl, de add hl, de ld a, [hl] inc hl ld c, a ld a, [hl] ld b, a ld a, [bc] swap a and 0xf ld c, a ld hl, wChannelOctaves add hl, de add hl, de ld a, [hl] cp 4 jp c, outofrange cp 6 jp nc, outofrange sub a, 4 # 12倍 ld b, a add a, b add a, b rla rla add a, c pop hl ret outofrange: ld a, 0xff pop hl ret