Wait, why does XO-CHIP not give you space for code?
Right. It's a product of the instruction encoding. The "jump", "jump0", "call" and "i:=NNN" CHIP-8 instructions only have space for a 12-bit immediate address. XO-CHIP expands the RAM available, and provides "i:=long NNNN", which can point to a 16-bit immediate address (and which is 4 bytes long instead of 2). Since jump/jump0/call don't have a "wide" flavor, you can't as easily place code outside the low 4k.
In practice this is still enough for quite elaborate games. It does, however, mean that XO-CHIP programmers should be more aware of where they're locating code and data in the address space.
Low ram is best used for code, high ram can be used for graphics, sound, or working memory. If you're running out of "code ram" for an elaborate game, you could write a small interpreter that executes bytecode from "data ram", at the cost of some speed. My game Business is Contagious used this strategy for most of the game logic, since only a few parts of the UI code were at all performance-sensitive.