Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/8bitworkshop-samples.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@
- **Missing Features:**
- Direct APU register macros (`APU_PULSE_DECAY`, `APU_PULSE_SWEEP`, `APU_TRIANGLE_LENGTH`, `APU_NOISE_DECAY`, `APU_ENABLE`)
- `APU.status` — direct hardware register reading
- `typedef struct` — no struct support
- `sprintf()` — no string formatting
- Global arrays of structs, `const` struct arrays
- **Implemented:** `typedef struct` now maps to C# `struct` with `byte`/`ushort` fields, fixed-size arrays via `fixed byte buf[N]` (Option A, requires `unsafe`) or `[InlineArray(N)]` (Option B). See `StructsTests` for examples.

### ppuhello.c
- **Description:** Directly programs PPU registers (`PPU.control`, `PPU.mask`, `PPU.vram.address`, `PPU.vram.data`) to display text — no neslib used.
Expand Down Expand Up @@ -212,7 +212,7 @@
- **Status:** 🔴 Complex
- **Missing Features:**
- Extremely large codebase (100+ KB) with dozens of functions
- `typedef struct` and struct instances — no struct support
- `typedef struct` and struct instances — basic struct field access works (including `fixed`-buffer and `[InlineArray(N)]` fields), but pointers to structs are not yet supported
- Extensive use of pointers, arrays of structs, bitfields
- `static` variables, `const` arrays
- Multiple user-defined functions with complex control flow
Expand Down Expand Up @@ -294,7 +294,7 @@
|-----------------|-----------------|
| User-defined functions with parameters | 25+ samples (byte params and return values now supported; ushort/string params pending) |
| Global/static arrays | 15+ samples |
| `typedef struct` / struct support | 8 samples (basic field access now supported; arrays of structs, pointers to structs pending) |
| `typedef struct` / struct support | 8 samples (basic field access, `fixed`-buffer and `[InlineArray(N)]` fields supported; pointers to structs pending) |
| Direct APU/PPU register access | 5 samples (apu.c already covered by built-in `apu_init()`) |
| Mapper support (MMC3, UxROM) | 3 samples |
| CC65-specific libraries (conio, joystick) | 2 samples |
Expand Down Expand Up @@ -329,6 +329,7 @@
| Global/static variables (`stsfld`/`ldsfld`) — user-defined static fields at $0325+ | climber, shoot2, siegegame (game state) |
| `sbyte` (signed char) — negative constants, `conv.i1`/`conv.i2` as no-ops | climber, shoot2, siegegame |
| Arrays of structs — `newarr` struct, `ldelema`, `stfld`/`ldfld` with AbsoluteX | climber, shoot2, siegegame |
| `fixed`-buffer (`fixed byte buf[N]`) and `[InlineArray(N)]` fields in structs — buffer-indexed reads/writes via `ldflda` + `stind.i1`/`ldind.u1` | StructsTests (`FixedBufferConstantIndex`, `FixedBufferRuntimeIndex`, `InlineArrayConstantIndex`, `InlineArrayRuntimeIndex`) |
| `Array.Fill` / `Array.Copy` — inline 6502 fill/copy loops | climber, siegegame |
| ca65 assembler — full expression evaluator (&&, \|\|, !), conditional assembly, all addressing modes | fami (FamiTone2 linking) |
| Extern assembly linking — `static extern` → `JSR _func`, `.s` files assembled and linked | fami (FamiTone2, music data, SFX data) |
Expand Down
16 changes: 16 additions & 0 deletions src/dotnes.tasks/Utilities/IL2NESWriter.ILDispatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,12 @@ public void Write(ILInstruction instruction, int operand)
// native integer sizeof values and will always push 1 here.
WriteLdc(1);
break;
case ILOpCode.Initobj:
// initobj on a struct local: pop the ldloca.s address. The transpiler
// does not zero-initialise the underlying zero-page bytes because user
// code is expected to write all fields before reading them.
_pendingStructLocal = null;
break;
default:
throw new TranspileException(GetUnsupportedOpcodeMessage(instruction.OpCode), MethodName);
}
Expand Down Expand Up @@ -3409,6 +3415,16 @@ or nameof(NESLib.set_vram_update))
case ILOpCode.Ldfld:
HandleLdfld(operand);
break;
case ILOpCode.Ldflda:
HandleLdflda(operand);
break;
case ILOpCode.Initobj:
// initobj on a struct local: pop the ldloca.s address. The transpiler
// does not zero-initialise the underlying zero-page bytes because user
// code is expected to write all fields before reading them (matching the
// existing behaviour for `Point p;` without an explicit `= default`).
_pendingStructLocal = null;
break;
case ILOpCode.Newobj:
if (operand == "Array2D.Byte.Ctor")
{
Expand Down
Loading
Loading