Skip to content

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions