ポケモン赤緑で今流れている曲を鍵盤に表示する
追記(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