Madsiur pointed me to an actual spell animation script that someone wrote up, and it's impressive. After looking at the scripts for Haste and Doom, it seems the problem lies in how the background is loaded. For Doom, the "background" is the faded character sprite that gets dragged by the reaper; for Haste, it's the sprite with the clocks superimposed on it. Both of them have slightly different behaviour from other spells based on their "graphics 2" values according to Mnrogar's spell graphics document; understandably, this is because the animation uses the target sprite.
Here's the animation script for Doom:
D0/5C36: BD A0 hide bg1 thread
D0/5C38: CC E0 set bg1 animation palette color subtraction to 0 (black)
D0/5C3A: 89 10 loop start (16 times)
D0/5C3C: 83 C0 move up 1
D0/5C3E: 1F [---]
D0/5C3F: CF E2 increase bg1 animation palette color subtraction by 2 (black)
D0/5C41: 8A loop end
D0/5C42: D0 30 set tile priority to 3 for all character/monster sprites
D0/5C44: BD 80 show bg1 thread
D0/5C46: C0 return from subroutine
; [ Animation Script $003C: Doom, Roulette (bg1) ]
D0/5C47: 00 20 speed 1, align to center of character/monster
D0/5C49: 80 72 01 branch to $5C4D if attack hit
D0/5C4C: FF end of script
D0/5C4D: EE 20 set target sprite tile priority to 2
D0/5C4F: F0 jump based on target ($5C6D, $5C87, $5CA1, $5CBB, $5C5A)
D0/5C5A: C4 80 move bg1 thread to this thread's position
D0/5C5C: BD A0 hide bg1 thread
D0/5C5E: 89 58 loop start (88 times)
D0/5C60: 83 C0 move up 1
D0/5C62: 0F [$0F]
D0/5C63: 8A loop end
D0/5C64: BF 36 5C jump to subroutine $5C36
D0/5C67: C4 80 move bg1 thread to this thread's position
D0/5C69: BD A0 hide bg1 thread
D0/5C6B: 0F [$0F]
D0/5C6C: FF end of script
D0/5C6D: EA 81 set bg1 tile data quadrant to 1
D0/5C6F: 0F [$0F]
D0/5C70: EA 82 set bg1 tile data quadrant to 2
D0/5C72: 0F [$0F]
D0/5C73: EA 83 set bg1 tile data quadrant to 3
D0/5C75: 0F [$0F]
D0/5C76: 89 58 loop start (88 times)
D0/5C78: 83 C0 move up 1
D0/5C7A: 00 [$00]
D0/5C7B: 8A loop end
D0/5C7C: BF 36 5C jump to subroutine $5C36
D0/5C7F: 83 3F move down 32
D0/5C81: 83 3F move down 32
D0/5C83: 83 38 move down 25
D0/5C85: 0F [$0F]
D0/5C86: FF end of script
D0/5C87: EA 81 set bg1 tile data quadrant to 1
D0/5C89: 0F [$0F]
D0/5C8A: EA 82 set bg1 tile data quadrant to 2
D0/5C8C: 0F [$0F]
D0/5C8D: EA 83 set bg1 tile data quadrant to 3
D0/5C8F: 0F [$0F]
D0/5C90: 89 58 loop start (88 times)
D0/5C92: 83 C0 move up 1
D0/5C94: 01 [$01]
D0/5C95: 8A loop end
D0/5C96: BF 36 5C jump to subroutine $5C36
D0/5C99: 83 3F move down 32
D0/5C9B: 83 3F move down 32
D0/5C9D: 83 38 move down 25
D0/5C9F: 0F [$0F]
D0/5CA0: FF end of script
D0/5CA1: EA 81 set bg1 tile data quadrant to 1
D0/5CA3: 0F [$0F]
D0/5CA4: EA 82 set bg1 tile data quadrant to 2
D0/5CA6: 0F [$0F]
D0/5CA7: EA 83 set bg1 tile data quadrant to 3
D0/5CA9: 0F [$0F]
D0/5CAA: 89 58 loop start (88 times)
D0/5CAC: 83 C0 move up 1
D0/5CAE: 02 [$02]
D0/5CAF: 8A loop end
D0/5CB0: BF 36 5C jump to subroutine $5C36
D0/5CB3: 83 3F move down 32
D0/5CB5: 83 3F move down 32
D0/5CB7: 83 38 move down 25
D0/5CB9: 0F [$0F]
D0/5CBA: FF end of script
D0/5CBB: EA 81 set bg1 tile data quadrant to 1
D0/5CBD: 0F [$0F]
D0/5CBE: EA 82 set bg1 tile data quadrant to 2
D0/5CC0: 0F [$0F]
D0/5CC1: EA 83 set bg1 tile data quadrant to 3
D0/5CC3: 0F [$0F]
D0/5CC4: 89 58 loop start (88 times)
D0/5CC6: 83 C0 move up 1
D0/5CC8: 03 [$03]
D0/5CC9: 8A loop end
D0/5CCA: BF 36 5C jump to subroutine $5C36
D0/5CCD: 83 3F move down 32
D0/5CCF: 83 3F move down 32
D0/5CD1: 83 38 move down 25
D0/5CD3: 0F [$0F]
D0/5CD4: FF end of script
And here's the script for Haste:
; [ Animation Script $00AD: Haste, Haste2 (bg3) ]
D0/5F6C: 00 20 speed 1, align to center of character/monster
D0/5F6E: D1 01 invalidate character/monster sprite priority
D0/5F70: C9 00 play default sound effect
D0/5F72: C4 40 move bg3 thread to this thread's position
D0/5F74: F7 A0 wait until scanline 160
D0/5F76: 80 3E 13 enable (sprites, bg2, bg1) in main screen
D0/5F79: AA FF set bg3 animation palette color subtraction to 31 (black)
D0/5F7B: 00 [$00]
D0/5F7C: EA 41 set bg3 tile data quadrant to 1
D0/5F7E: 00 [$00]
D0/5F7F: BD 50 hide bg3 thread
D0/5F81: F7 A0 wait until scanline 160
D0/5F83: 80 3E 17 enable (sprites, bg3, bg2, bg1) in main screen
D0/5F86: 89 1F loop start (31 times)
D0/5F88: 83 60 move forward 1
D0/5F8A: B4 F1 decrease bg3 animation palette color subtraction by 1 (black)
D0/5F8C: 00 [$00]
D0/5F8D: 8A loop end
D0/5F8E: 89 40 loop start (64 times)
D0/5F90: 83 60 move forward 1
D0/5F92: 00 [$00]
D0/5F93: 8A loop end
D0/5F94: 89 1F loop start (31 times)
D0/5F96: 83 60 move forward 1
D0/5F98: B4 E1 increase bg3 animation palette color subtraction by 1 (black)
D0/5F9A: 00 [$00]
D0/5F9B: 8A loop end
D0/5F9C: BD 40 show bg3 thread
D0/5F9E: EA 41 set bg3 tile data quadrant to 1
D0/5FA0: 09 [$09]
D0/5FA1: FF end of script
I don't see anything wrong with the scripts themselves. I think the problem is in the setup.