Skip to content

Transpiler: oam_spr compound expressions with static field operands #237

@jonathanpeppers

Description

@jonathanpeppers

Follow-up from PR #211 (crypto.c sample port) review.

oam_spr calls with compound expressions that use static fields as operands don't work correctly:

// Fails — static field in compound arg
G.spr = oam_spr((byte)(G.temp0 - 4), (byte)(G.temp1 - 8), 0xC0, 0x03, G.spr);

Root cause

In IL2NESWriter.OamSprites.cs, the backward scan for EmitOamSprDecsp4 identifies ldsfld as a value producer (increments depth), but when it appears as an operand in a binary op (e.g., sub), the compound emission path (EmitOamSprDecsp4) assumes the operand is a local variable (Locals[arg.compoundLocalIdx]), not a static field.

The compoundLocalIdx is populated from Ldloc instructions, not Ldsfld. So a pattern like ldsfld G.temp0; ldc 4; sub; conv.u1 doesn't get captured as a compound expression.

Current workaround

Store the static field in a local first:

byte adj_x = (byte)(G.temp0 - 4);
byte adj_y = (byte)(G.temp1 - 8);
G.spr = oam_spr(adj_x, adj_y, 0xC0, 0x03, G.spr);

Implementation

Extend the compound expression tracking in OamSprites.cs to handle ldsfld alongside ldloc:

  1. Add a compoundStaticFieldName (or similar) to the arg info struct
  2. When the backward scan encounters ldsfld followed by a binary op, capture the field name/address
  3. In emission, use LDA Absolute, fieldAddr instead of LDA ZeroPage, localAddr

Context

Blocking the crypto sample (PR #211). See review: #211 (review)

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions