pokecrystal/engine/dma_transfer.asm

626 lines
9.5 KiB
NASM
Raw Normal View History

2016-05-05 02:34:09 +00:00
HDMATransferAttrMapAndTileMapToWRAMBank3:: ; 104000
2015-12-23 03:19:33 +00:00
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
.Function:
2015-11-30 16:04:14 +00:00
decoord 0, 0, AttrMap
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
2015-12-09 23:25:44 +00:00
call CutAndPasteAttrMap
2015-11-30 16:04:14 +00:00
decoord 0, 0
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
2015-12-09 23:25:44 +00:00
call CutAndPasteTilemap
2015-11-30 16:04:14 +00:00
ld a, $0
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransferToWRAMBank3
2015-11-30 16:04:14 +00:00
ld a, $1
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
call HDMATransferToWRAMBank3
2015-11-30 16:04:14 +00:00
ret
; 10402d
2016-05-05 02:34:09 +00:00
HDMATransferTileMapToWRAMBank3:: ; 10402d
2015-12-23 03:19:33 +00:00
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
.Function:
2015-11-30 16:04:14 +00:00
decoord 0, 0
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
2015-12-09 23:25:44 +00:00
call CutAndPasteTilemap
2015-11-30 16:04:14 +00:00
ld a, $0
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransferToWRAMBank3
2015-11-30 16:04:14 +00:00
ret
; 104047
2016-05-05 02:34:09 +00:00
HDMATransferAttrMapToWRAMBank3: ; 104047
2015-12-23 03:19:33 +00:00
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
.Function:
2015-11-30 16:04:14 +00:00
decoord 0, 0, AttrMap
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
2015-12-09 23:25:44 +00:00
call CutAndPasteAttrMap
2015-11-30 16:04:14 +00:00
ld a, $1
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
call HDMATransferToWRAMBank3
2015-11-30 16:04:14 +00:00
ret
; 104061
ReloadMapPart:: ; 104061
2015-12-23 03:19:33 +00:00
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
.Function:
2015-11-30 16:04:14 +00:00
decoord 0, 0, AttrMap
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
2015-12-09 23:25:44 +00:00
call CutAndPasteAttrMap
2015-11-30 16:04:14 +00:00
decoord 0, 0
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
2015-12-09 23:25:44 +00:00
call CutAndPasteTilemap
2015-11-30 16:04:14 +00:00
call DelayFrame
2016-05-05 02:34:09 +00:00
2015-11-30 16:04:14 +00:00
di
ld a, [rVBK]
push af
ld a, $1
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
call HDMATransfer_Wait127Scanlines_toBGMap
2015-11-30 16:04:14 +00:00
ld a, $0
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransfer_Wait127Scanlines_toBGMap
2015-11-30 16:04:14 +00:00
pop af
ld [rVBK], a
ei
2016-05-05 02:34:09 +00:00
2015-11-30 16:04:14 +00:00
ret
2016-05-05 02:34:09 +00:00
Mobile_ReloadMapPart: ; 104099
2015-11-30 16:04:14 +00:00
ld hl, ReloadMapPart ; useless
2015-12-23 03:19:33 +00:00
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
.Function:
2015-11-30 16:04:14 +00:00
decoord 0, 0, AttrMap
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
2015-12-09 23:25:44 +00:00
call CutAndPasteAttrMap
2015-11-30 16:04:14 +00:00
decoord 0, 0
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
2015-12-09 23:25:44 +00:00
call CutAndPasteTilemap
2015-11-30 16:04:14 +00:00
call DelayFrame
2016-05-05 02:34:09 +00:00
2015-11-30 16:04:14 +00:00
di
ld a, [rVBK]
push af
ld a, $1
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
call HDMATransfer_NoDI
2015-11-30 16:04:14 +00:00
ld a, $0
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransfer_NoDI
2015-11-30 16:04:14 +00:00
pop af
ld [rVBK], a
ei
2016-05-05 02:34:09 +00:00
2015-11-30 16:04:14 +00:00
ret
; 1040d4
2016-05-05 02:34:09 +00:00
; XXX
ld hl, .unreferenced_1040da
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
2016-05-05 02:34:09 +00:00
.unreferenced_1040da
2015-11-30 16:04:14 +00:00
ld a, $1
ld [rVBK], a
ld a, $3
ld [rSVBK], a
ld de, w3_d800
ld a, [hBGMapAddress + 1]
ld [rHDMA1], a
ld a, [hBGMapAddress]
ld [rHDMA2], a
ld a, d
ld [rHDMA3], a
ld a, e
ld [rHDMA4], a
ld a, $23
ld [hDMATransfer], a
2015-12-23 03:19:33 +00:00
call WaitDMATransfer
2015-11-30 16:04:14 +00:00
ret
; 1040fb
2016-05-05 02:34:09 +00:00
; XXX
ld hl, .unreferenced_104101
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
2016-05-05 02:34:09 +00:00
.unreferenced_104101
2015-11-30 16:04:14 +00:00
ld a, $1
ld [rVBK], a
ld a, $3
ld [rSVBK], a
ld hl, w3_d800
2016-05-05 02:34:09 +00:00
call HDMATransferToWRAMBank3
2015-11-30 16:04:14 +00:00
ret
; 104110
2016-05-05 02:34:09 +00:00
OpenAndCloseMenu_HDMATransferTileMapAndAttrMap:: ; 104110
2015-12-09 23:25:44 +00:00
; OpenText
2015-12-23 03:19:33 +00:00
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
.Function:
2016-05-05 02:34:09 +00:00
; Transfer AttrMap and Tilemap to BGMap
; Fill vBGAttrs with $00
; Fill vBGTiles with " "
2015-11-30 16:04:14 +00:00
decoord 0, 0, AttrMap
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
2015-12-09 23:25:44 +00:00
call CutAndPasteAttrMap
2015-11-30 16:04:14 +00:00
decoord 0, 0
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
2015-12-09 23:25:44 +00:00
call CutAndPasteTilemap
2015-11-30 16:04:14 +00:00
call DelayFrame
2015-12-09 23:25:44 +00:00
2015-11-30 16:04:14 +00:00
di
ld a, [rVBK]
push af
ld a, $1
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
call HDMATransfer_Wait123Scanlines_toBGMap
2015-11-30 16:04:14 +00:00
ld a, $0
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransfer_Wait123Scanlines_toBGMap
2015-11-30 16:04:14 +00:00
pop af
ld [rVBK], a
ei
ret
; 104148
2016-05-05 02:34:09 +00:00
Mobile_OpenAndCloseMenu_HDMATransferTileMapAndAttrMap: ; 104148 (41:4148)
2015-12-23 03:19:33 +00:00
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
.Function:
2016-05-05 02:34:09 +00:00
; Transfer AttrMap and Tilemap to BGMap
; Fill vBGAttrs with $00
; Fill vBGTiles with $ff
2015-11-30 16:04:14 +00:00
decoord 0, 0, AttrMap
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
2015-12-09 23:25:44 +00:00
call CutAndPasteAttrMap
2015-11-30 16:04:14 +00:00
ld c, $ff
decoord 0, 0
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
2015-12-09 23:25:44 +00:00
call CutAndPasteMap
2016-05-05 02:34:09 +00:00
2015-11-30 16:04:14 +00:00
ld a, $1
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchAttrMap
call HDMATransfer_Wait127Scanlines_toBGMap
2015-11-30 16:04:14 +00:00
ld a, $0
ld [rVBK], a
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransfer_Wait127Scanlines_toBGMap
2015-11-30 16:04:14 +00:00
ret
; 104177
2015-12-09 23:25:44 +00:00
CallInSafeGFXMode: ; 104177
2015-11-30 16:04:14 +00:00
ld a, [hBGMapMode]
push af
ld a, [hMapAnims]
push af
xor a
ld [hBGMapMode], a
ld [hMapAnims], a
ld a, [rSVBK]
push af
ld a, $6
2015-11-30 16:04:14 +00:00
ld [rSVBK], a
ld a, [rVBK]
push af
2015-12-09 23:25:44 +00:00
2015-11-30 16:04:14 +00:00
call ._hl_
2015-12-09 23:25:44 +00:00
2015-11-30 16:04:14 +00:00
pop af
ld [rVBK], a
pop af
ld [rSVBK], a
pop af
ld [hMapAnims], a
pop af
ld [hBGMapMode], a
ret
; 10419c
._hl_ ; 10419c
jp hl
2015-11-30 16:04:14 +00:00
; 10419d
2016-05-05 02:34:09 +00:00
HDMATransferToWRAMBank3: ; 10419d (41:419d)
call _LoadHDMAParameters
2015-11-30 16:04:14 +00:00
ld a, $23
ld [hDMATransfer], a
2015-12-23 03:19:33 +00:00
WaitDMATransfer: ; 104a14
.loop
2015-11-30 16:04:14 +00:00
call DelayFrame
ld a, [hDMATransfer]
and a
2015-12-23 03:19:33 +00:00
jr nz, .loop
2015-11-30 16:04:14 +00:00
ret
2016-05-05 02:34:09 +00:00
HDMATransfer_Wait127Scanlines_toBGMap: ; 1041ad (41:41ad)
; HDMA transfer from hl to [hBGMapAddress]
; hBGMapAddress -> de
; 2 * SCREEN_HEIGHT -> c
2015-11-30 16:04:14 +00:00
ld a, [hBGMapAddress + 1]
ld d, a
ld a, [hBGMapAddress]
ld e, a
2016-05-05 02:34:09 +00:00
ld c, 2 * SCREEN_HEIGHT
jr HDMATransfer_Wait127Scanlines
2015-11-30 16:04:14 +00:00
2016-05-05 02:34:09 +00:00
HDMATransfer_Wait123Scanlines_toBGMap: ; 1041b7 (41:41b7)
; HDMA transfer from hl to [hBGMapAddress]
2015-12-09 23:25:44 +00:00
; hBGMapAddress -> de
2016-05-05 02:34:09 +00:00
; 2 * SCREEN_HEIGHT -> c
2015-12-09 23:25:44 +00:00
; $7b --> b
2015-11-30 16:04:14 +00:00
ld a, [hBGMapAddress + 1]
ld d, a
ld a, [hBGMapAddress]
ld e, a
2016-05-05 02:34:09 +00:00
ld c, 2 * SCREEN_HEIGHT
jr HDMATransfer_Wait123Scanlines
2015-11-30 16:04:14 +00:00
; 1041c1 (41:41c1)
2016-05-05 02:34:09 +00:00
HDMATransfer_NoDI: ; 1041c1
; HDMA transfer from hl to [hBGMapAddress]
; [hBGMapAddress] --> de
; 2 * SCREEN_HEIGHT --> c
2015-11-30 16:04:14 +00:00
ld a, [hBGMapAddress + 1]
ld d, a
ld a, [hBGMapAddress]
ld e, a
2016-05-05 02:34:09 +00:00
ld c, 2 * SCREEN_HEIGHT
; [rHDMA1, rHDMA2] = hl & $fff0
2015-11-30 16:04:14 +00:00
ld a, h
ld [rHDMA1], a
ld a, l
and $f0
ld [rHDMA2], a
2016-05-05 02:34:09 +00:00
; [rHDMA3, rHDMA4] = de & $1ff0
2015-11-30 16:04:14 +00:00
ld a, d
and $1f
ld [rHDMA3], a
ld a, e
and $f0
ld [rHDMA4], a
2016-05-05 02:34:09 +00:00
; b = c | %10000000
2015-11-30 16:04:14 +00:00
ld a, c
dec c
or $80
ld b, a
2016-05-05 02:34:09 +00:00
; d = $7f - c + 1
2015-11-30 16:04:14 +00:00
ld a, $7f
sub c
ld d, a
2016-05-05 02:34:09 +00:00
; while [rLY] >= d: pass
2015-11-30 16:04:14 +00:00
.loop1
ld a, [rLY]
cp d
jr nc, .loop1
2016-05-05 02:34:09 +00:00
; while not [rSTAT] & 3: pass
2015-11-30 16:04:14 +00:00
.loop2
ld a, [rSTAT]
and $3
jr z, .loop2
2016-05-05 02:34:09 +00:00
; load the 5th byte of HDMA
2015-11-30 16:04:14 +00:00
ld a, b
ld [rHDMA5], a
2016-05-05 02:34:09 +00:00
; wait until rLY advances (c + 1) times
2015-11-30 16:04:14 +00:00
ld a, [rLY]
inc c
ld hl, rLY
.loop3
cp [hl]
jr z, .loop3
ld a, [hl]
dec c
jr nz, .loop3
ld hl, rHDMA5
res 7, [hl]
ret
; 104205
2016-05-05 02:34:09 +00:00
HDMATransfer_Wait123Scanlines:
2015-11-30 16:04:14 +00:00
ld b, $7b
2016-05-05 02:34:09 +00:00
jr _continue_HDMATransfer
2015-11-30 16:04:14 +00:00
2016-05-05 02:34:09 +00:00
HDMATransfer_Wait127Scanlines:
2015-11-30 16:04:14 +00:00
ld b, $7f
2016-05-05 02:34:09 +00:00
_continue_HDMATransfer:
; a lot of waiting around for hardware registers
; [rHDMA1, rHDMA2] = hl & $fff0
2015-11-30 16:04:14 +00:00
ld a, h
ld [rHDMA1], a
ld a, l
and $f0 ; high nybble
ld [rHDMA2], a
2016-05-05 02:34:09 +00:00
; [rHDMA3, rHDMA4] = de & $1ff0
2015-11-30 16:04:14 +00:00
ld a, d
and $1f ; lower 5 bits
ld [rHDMA3], a
ld a, e
and $f0 ; high nybble
ld [rHDMA4], a
2016-05-05 02:34:09 +00:00
; e = c | %10000000
2015-11-30 16:04:14 +00:00
ld a, c
dec c
2016-05-05 02:34:09 +00:00
or $80
2015-11-30 16:04:14 +00:00
ld e, a
2016-05-05 02:34:09 +00:00
; d = b - c + 1
2015-11-30 16:04:14 +00:00
ld a, b
sub c
ld d, a
2016-05-05 02:34:09 +00:00
; while [rLY] >= d: pass
2015-11-30 16:04:14 +00:00
.ly_loop
ld a, [rLY]
cp d
jr nc, .ly_loop
di
2016-05-05 02:34:09 +00:00
; while [rSTAT] & 3: pass
2015-11-30 16:04:14 +00:00
.rstat_loop_1
ld a, [rSTAT]
and $3
jr nz, .rstat_loop_1
2016-05-05 02:34:09 +00:00
; while not [rSTAT] & 3: pass
2015-11-30 16:04:14 +00:00
.rstat_loop_2
ld a, [rSTAT]
and $3
jr z, .rstat_loop_2
2016-05-05 02:34:09 +00:00
; load the 5th byte of HDMA
2015-11-30 16:04:14 +00:00
ld a, e
ld [rHDMA5], a
2016-05-05 02:34:09 +00:00
; wait until rLY advances (c + 1) times
2015-11-30 16:04:14 +00:00
ld a, [rLY]
inc c
ld hl, rLY
.final_ly_loop
cp [hl]
jr z, .final_ly_loop
ld a, [hl]
dec c
jr nz, .final_ly_loop
ld hl, rHDMA5
res 7, [hl]
ei
ret
; 10424e
2016-05-05 02:34:09 +00:00
_LoadHDMAParameters: ; 10424e (41:424e)
2015-11-30 16:04:14 +00:00
ld a, h
ld [rHDMA1], a
ld a, l
ld [rHDMA2], a
ld a, [hBGMapAddress + 1]
and $1f
ld [rHDMA3], a
ld a, [hBGMapAddress]
ld [rHDMA4], a
ret
2015-12-09 23:25:44 +00:00
CutAndPasteTilemap: ; 10425f (41:425f)
2015-11-30 16:04:14 +00:00
ld c, " "
2015-12-09 23:25:44 +00:00
jr CutAndPasteMap
2015-11-30 16:04:14 +00:00
2015-12-09 23:25:44 +00:00
CutAndPasteAttrMap: ; 104263 (41:4263)
2015-11-30 16:04:14 +00:00
ld c, $0
2015-12-09 23:25:44 +00:00
CutAndPasteMap: ; 104265 (41:4265)
2015-11-30 16:04:14 +00:00
; back up the value of c to hMapObjectIndexBuffer
ld a, [hMapObjectIndexBuffer]
push af
ld a, c
ld [hMapObjectIndexBuffer], a
; for each row on the screen
ld c, SCREEN_HEIGHT
.loop1
; for each tile in the row
ld b, SCREEN_WIDTH
.loop2
; copy from de to hl
ld a, [de]
inc de
ld [hli], a
dec b
jr nz, .loop2
; load the original value of c into hl 12 times
ld a, [hMapObjectIndexBuffer]
2016-05-05 02:34:09 +00:00
ld b, BG_MAP_WIDTH - SCREEN_WIDTH
2015-11-30 16:04:14 +00:00
.loop3
ld [hli], a
dec b
jr nz, .loop3
dec c
jr nz, .loop1
; restore the original value of hMapObjectIndexBuffer
pop af
ld [hMapObjectIndexBuffer], a
ret
_Get2bpp:: ; 104284
; 2bpp when [rLCDC] & $80
; switch to WRAM bank 6
ld a, [rSVBK]
push af
ld a, $6
ld [rSVBK], a
push bc
push hl
2016-05-05 02:34:09 +00:00
; Copy c tiles of the 2bpp from b:de to wScratchTileMap
2015-11-30 16:04:14 +00:00
ld a, b ; bank
ld l, c ; number of tiles
ld h, $0
; multiply by 16 (16 bytes of a 2bpp = 8 x 8 tile)
add hl, hl
add hl, hl
add hl, hl
add hl, hl
2015-11-30 16:04:14 +00:00
ld b, h
ld c, l
ld h, d ; address
ld l, e
2016-05-05 02:34:09 +00:00
ld de, wScratchTileMap
2015-11-30 16:04:14 +00:00
call FarCopyBytes
2015-11-30 16:04:14 +00:00
pop hl
pop bc
push bc
call DelayFrame
pop bc
ld d, h
ld e, l
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransfer_Wait127Scanlines
2015-11-30 16:04:14 +00:00
; restore the previous bank
pop af
ld [rSVBK], a
ret
; 1042b2
_Get1bpp:: ; 1042b2
; 1bpp when [rLCDC] & $80
.loop
ld a, c
cp $10
jp c, .bankswitch
jp z, .bankswitch
push bc
push hl
push de
ld c, $10
call .bankswitch
pop de
ld hl, $80
add hl, de
ld d, h
ld e, l
pop hl
lb bc, 1, 0
add hl, bc
pop bc
ld a, c
sub $10
ld c, a
jr .loop
; 1042d6
.bankswitch ; 1042d6
2015-11-30 16:04:14 +00:00
ld a, [rSVBK]
push af
ld a, $6
ld [rSVBK], a
push bc
push hl
ld a, b
ld l, c
ld h, $0
add hl, hl ; multiply by 8
add hl, hl ; multiply by 8
add hl, hl ; multiply by 8
2015-11-30 16:04:14 +00:00
ld c, l
ld b, h
ld h, d
ld l, e
2016-05-05 02:34:09 +00:00
ld de, wScratchTileMap
2015-11-30 16:04:14 +00:00
call FarCopyBytesDouble_DoubleBankSwitch
pop hl
pop bc
push bc
call DelayFrame
pop bc
ld d, h
ld e, l
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
call HDMATransfer_Wait127Scanlines
2015-11-30 16:04:14 +00:00
pop af
ld [rSVBK], a
ret
; 104303
2016-05-05 02:34:09 +00:00
HDMATransfer_OnlyTopFourRows: ; 104303
ld hl, .Function
2015-12-09 23:25:44 +00:00
jp CallInSafeGFXMode
2015-11-30 16:04:14 +00:00
; 104309
2016-05-05 02:34:09 +00:00
.Function:
ld hl, wScratchTileMap
2015-11-30 16:04:14 +00:00
decoord 0, 0
2016-05-05 02:34:09 +00:00
call .Copy
ld hl, wScratchTileMap + $80
2015-11-30 16:04:14 +00:00
decoord 0, 0, AttrMap
2016-05-05 02:34:09 +00:00
call .Copy
2015-11-30 16:04:14 +00:00
ld a, $1
ld [rVBK], a
ld c, $8
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap + $80
2015-11-30 16:04:14 +00:00
debgcoord 0, 0, VBGMap1
2016-05-05 02:34:09 +00:00
call HDMATransfer_Wait127Scanlines
2015-11-30 16:04:14 +00:00
ld a, $0
ld [rVBK], a
ld c, $8
2016-05-05 02:34:09 +00:00
ld hl, wScratchTileMap
2015-11-30 16:04:14 +00:00
debgcoord 0, 0, VBGMap1
2016-05-05 02:34:09 +00:00
call HDMATransfer_Wait127Scanlines
2015-11-30 16:04:14 +00:00
ret
2016-05-05 02:34:09 +00:00
.Copy: ; 10433a (41:433a)
2015-11-30 16:04:14 +00:00
ld b, 4
.outer_loop
ld c, SCREEN_WIDTH
.inner_loop
ld a, [de]
ld [hli], a
inc de
dec c
jr nz, .inner_loop
ld a, l
2016-05-05 02:34:09 +00:00
add BG_MAP_WIDTH - SCREEN_WIDTH
2015-11-30 16:04:14 +00:00
ld l, a
ld a, h
adc $0
ld h, a
dec b
jr nz, .outer_loop
ret
; 104350