THE X FLAG the index registers’ width — M’s twin, for X and Y
The X status bit does for the index registers what M does for the accumulator: X=1 keeps X and Y 8-bit (6502), X=0 makes them 16-bit, so an index can now reach across a full 64KB bank instead of 256 bytes. The two width bits are independent — you can run a 16-bit accumulator with 8-bit indices or any combination — which is why 65816 code carefully tracks M and X, and why a mismatched assumption is the classic porting bug. Two bits, four register-width worlds.
THE TECHNIQUE X=1 → 8-bit X/Y, X=0 → 16-bit — independent of M
The demo masks an index by the X flag — 8-bit gives 0x34, 16-bit gives the full 0x1234, reaching a whole bank: live demo
HISTORY & CREDIT 65C816 status bit X
“Index registers are always the word size.” — the 65816 sizes them with their own bit, independent of the accumulator. cited
the bit · X in the status byte — index-register width. the reach · X=0 lets an index span 64KB (16-bit) instead of 256 bytes. the catch · M and X are independent; assuming the wrong one is the classic 65816 porting bug.
The index widened by its own bit — four register-width worlds from two flags. width flag
RECOMMEND FOR I-13 the index width, on the compiler
On the canonical compiler, an index of 0x1234 is 0x34 under X=1 and the full 0x1234 under X=0:
$ i13 run pm_xflag.i13 # index mask by X
RUN OK · 36 step(s) · peak stack 3 · call depth 1
x8 = 52 -- X=1: 8-bit
x16 = 4660 -- X=0: 16-bit (reaches a full bank)
index_switch = 1
Recommend as a NULL — M’s twin, same verdict. The X flag is width-as-configuration for the index registers (B44/B39), independent of M but structurally identical to dart 456. No new axis. NULL — it completes the two-bit width system that lets the permutation reuse the 6502’s addressing while widening its reach.