Skip to content

bios_frame_skip is a u16 at an odd address — that var and everything after it land a byte off #149

@dogruis

Description

@dogruis

Was digging through the bios-RAM layout and tripped over this. bios_frame_skip in runtime/libngdevkit/bios-ram.c is declared u16, but its slot is an odd address:

u8  bios_compulsion_timer_over = 0;  /// 0x10fee0
u16 bios_frame_skip = 0;             /// 0x10fee1
u8  bios_int1_skip = 0;              /// 0x10fee3
u8  bios_int1_frame_counter = 0;     /// 0x10fee4

A u16 wants 2-byte alignment, so the compiler quietly shoves it to 0x10fee2 and leaves a pad byte at 0x10fee1. The whole block counts on each global landing exactly where the comment says — that's what all the _bios_unknownNN padding is for — so that one pad byte drags frame_skip and everything after it up by a byte.

Repro (GCC 11.4.0):

m68k-neogeo-elf-gcc -std=c99 -Iinclude -c runtime/libngdevkit/bios-ram.c -o /tmp/bios-ram.o
m68k-neogeo-elf-nm -n /tmp/bios-ram.o | grep -i -e compulsion_timer_over -e frame_skip -e int1 -e 4p_requested
000001f2 B bios_compulsion_timer_over
000001f4 B bios_frame_skip
000001f6 B bios_int1_skip
000001f7 B bios_int1_frame_counter
0000020b B bios_4p_requested

Those are .bss offsets; ngdevkit.ld puts the section at BIOSRAM = 0x10fcee, so the real address is 0x10fcee + offset. compulsion_timer_over0x10fee0, which matches its comment so the base checks out — but frame_skip jumps to 0x1f40x10fee2 when it should be 0x10fee1. The skipped 0x1f3 is the pad byte. Knock-on: int1_skip0x10fee4, int1_frame_counter0x10fee5, 4p_requested0x10fef9, all one byte past their documented spots, and the one place frame_skip is read (if (bios_frame_skip) in credits.c) is looking at 0x10fee2 instead of 0x10fee1.

frame_skip is only ever that yes/no test, so dropping it to u8 kills the pad and lines everyone back up. The bit I don't want to guess on: with u8, int1_skip lands at 0x10fee2 — is the documented 0x10fee3 right (so 0x10fee2 is a real byte that needs its own explicit pad), or should it just slide down to 0x10fee2? You know the actual map better than me.
I was studying padding in C and assembly as an exercise and came across this to understand the size of my structs and the number of words I was writing to VRAM during VBLANK in my actual game. But when it comes to assembly I am not confident enough yet with m68k, last time I used assembly (8086 instruction set) was almost 20 years ago in uni.

I want to frame this more as a question for my own understanding and learning process unless it's a real bug

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions