Zelda II: The Adventure of Link/Luck Manipulation
Summary
The Zelda II RNG changes with every frame. In the NES version, the counter starts when SDA timing starts. Generally that doesn't matter, since things will never happen at the same time, but the one key exception is that in any category where the North Palace Magic Container is done first, a 50 point bag can be manipulated.
Opening 50 PBag
Here is a chart of the Zelda II RNG at the start of the game, with a 10 frame moving average. Each bar represents the numbered frame, and the 9 frames preceding.
For the P Bag drop, the two key windows are the ones at about 1600 frames, and at about 1920 frames. Hit either of those windows reliably, and P Bag drops go from the usual 1/8 chance, to much higher.
Technical details
The following comes courtesy of __sdfg on the SDA forums, with permission.
Anyway, here's a bucket of FCEUX for a small drop:
003612: A:01 X:01 Y:01 S:EF P:nvUBdIzc $E899:FE DE 05 INC $05DE,X @ $05DF = #$05 ; Increment 6-count, this time for a small drop 003612: A:01 X:01 Y:01 S:EF P:nvUBdIzc $E89C:BD DE 05 LDA $05DE,X @ $05DF = #$06 ; And then load that value 003612: A:06 X:01 Y:01 S:EF P:nvUBdIzc $E89F:C9 06 CMP #$06 ; And see if it's 6 yet 003612: A:06 X:01 Y:01 S:EF P:nvUBdIZC $E8A1:D0 1C BNE $E8BF 003612: A:06 X:01 Y:01 S:EF P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; It is! Zero the counter for next time 003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05DF = #$06 003612: A:00 X:01 Y:01 S:EF P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; Load Mystery Value into X. It's 4 here 003612: A:00 X:04 Y:01 S:EF P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$01 ; ??? 003612: A:00 X:04 Y:01 S:EF P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$82 ; Read RNG byte 4 003612: A:82 X:04 Y:01 S:EF P:NvUBdIzC $E8B0:29 07 AND #$07 ; Actually, we just need the 3 low bits 003612: A:02 X:04 Y:01 S:EF P:nvUBdIzC $E8B2:C0 02 CPY #$02 ; This is a small drop, so skip to E8B8 003612: A:02 X:04 Y:01 S:EF P:NvUBdIzc $E8B4:D0 02 BNE $E8B8 003612: A:02 X:04 Y:01 S:EF P:NvUBdIzc $E8B8:A8 TAY ; Load the drop at position 2 this time (A=2) 003612: A:02 X:04 Y:02 S:EF P:nvUBdIzc $E8B9:B9 70 E8 LDA $E870,Y @ $E872 = #$8A ; 8A = 50-bag. Nice! 003612: A:8A X:04 Y:02 S:EF P:NvUBdIzc $E8BC:9D 8E 04 STA $048E,X @ $0492 = #$00 003612: A:8A X:04 Y:02 S:EF P:NvUBdIzc $E8BF:A6 10 LDX $0010 = #$04 ; And now we're past the drop code
And for a large drop:
029149: A:02 X:02 Y:02 S:F1 P:nvUBdIzc $E899:FE DE 05 INC $05DE,X @ $05E0 = #$05 ; Increment large 6-count 029149: A:02 X:02 Y:02 S:F1 P:nvUBdIzc $E89C:BD DE 05 LDA $05DE,X @ $05E0 = #$06 029149: A:06 X:02 Y:02 S:F1 P:nvUBdIzc $E89F:C9 06 CMP #$06 ; Which is a 6 029149: A:06 X:02 Y:02 S:F1 P:nvUBdIZC $E8A1:D0 1C BNE $E8BF 029149: A:06 X:02 Y:02 S:F1 P:nvUBdIZC $E8A3:A9 00 LDA #$00 ; So we zero it 029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A5:9D DE 05 STA $05DE,X @ $05E0 = #$06 029149: A:00 X:02 Y:02 S:F1 P:nvUBdIZC $E8A8:A6 10 LDX $0010 = #$04 ; Mystery value is 4 again 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIzC $E8AA:7E 14 04 ROR $0414,X @ $0418 = #$07 029149: A:00 X:04 Y:02 S:F1 P:NvUBdIzC $E8AD:BD 1B 05 LDA $051B,X @ $051F = #$D0 ; The low 3 RNG bits are 0 029149: A:D0 X:04 Y:02 S:F1 P:NvUBdIzC $E8B0:29 07 AND #$07 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIZC $E8B2:C0 02 CPY #$02 ; This is a large drop, so we skip the branch... 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIZC $E8B4:D0 02 BNE $E8B8 029149: A:00 X:04 Y:02 S:F1 P:nvUBdIZC $E8B6:69 07 ADC #$07 ; ...and add 8 (carry is set) to use a different array 029149: A:08 X:04 Y:02 S:F1 P:nvUBdIzc $E8B8:A8 TAY 029149: A:08 X:04 Y:08 S:F1 P:nvUBdIzc $E8B9:B9 70 E8 LDA $E870,Y @ $E878 = #$91 ; Item 0 in that array is a red jar 029149: A:91 X:04 Y:08 S:F1 P:NvUBdIzc $E8BC:9D 8E 04 STA $048E,X @ $0492 = #$00 029149: A:91 X:04 Y:08 S:F1 P:NvUBdIzc $E8BF:A6 10 LDX $0010 = #$04
If X is 1 entering this block of code, you get a small drop. If it's 2, you get a large drop. I think it's skipped entirely if the enemy's not supposed to drop something. I haven't looked into the code preceding it much.
As noted above, 3 bits from the RNG are used as an index into a drop array. In a standard NES ROM with a 16-byte header, you can find the small drop array at offset 1e880 and the large array at 1e888. Here they are:
Small = 9090 8a90 9090 9090 Large = 918c 918c 8c91 8c91 8a = 50-point bag 9c = 200-point bag 90 = Blue jar 91 = Red jar
I made a spreadsheet using the RNG table that powerofthepowerofthe posted (Editor's note: Here are RNG output tables created by powerofthepowerofthe). It seemed to work pretty well: I'd check for updates to $0492, and on the frame I saw the update, I could use the RNG value to check which drop I'd get.
Then I started fighting a bunch of bots in a weak encounter over and over and noticed that the drops weren't going into $0492 anymore. It seems the RNG is bigger than two bytes, and the "mystery value" decides both which address should receive the drop and which address should be read to decide the drop. When I kept killing enemies, the mystery value would change. I don't know anything about the Zelda 1 RNG, so maybe that's normal, but it might be necessary to look into the RNG algorithm a bit more to account for this behavior. If it is normal, then we just need to determine how the mystery value is set. If there's a Zelda 1 mystery value with known behavior, then fantastic.
The RNG does update on every frame, so I don't think this will help you manipulate anything unless there's some clump of good drops that you can target by playing at a specific speed. It does teach us that the P-bag probabilities are 1/8 and 1/2, though, unless the sequence for some of the RNG bytes is really wack. Maybe knowing that is enough.