Z80 bankswitching

From NeoGeo Development Wiki
Jump to: navigation, search

Having a 16-bit address bus, the Chipicon.png Z80 CPU allows access to 64KiB of memory at most. In NeoGeo cartridges, the Chipicon.png NEO-ZMC or Chipicon.png NEO-ZMC2 chips provide a way to access more memory for bigger M1 ROMs. Four different switchable zones ("windows") are available in the Z80 memory map.

The banks are configured by reading from some of the Z80's ports (see page for explanation).

Bank offsets numbering depend on the zone:

  • Zone 0 counts in 2KiB increments
  • zone 1 in 4KiB
  • zone 2 in 8KiB
  • zone 3 in 16KiB

The NeoGeo CD doesn't allow for Z80 bankswitching.

Example code

Initialization

This simply maps Z80 $0000~$F7FF to M1 ROM $0000~$F7FF linearly, with no gaps.

ld    a,$1E
in    a,($08)    ; Set zone 0 at $1E*$800 = $F000
ld    a,$0E
in    a,($09)    ; Set zone 1 at $E*$1000 = $E000
ld    a,$06
in    a,($0A)    ; Set zone 2 at $6*$2000 = $C000
ld    a,$02
in    a,($0B)    ; Set zone 3 at $2*$4000 = $8000

Bank selection

The King of Fighters '97 does this:

; 32KiB bank number in A
rlca
rlca
ld    e,a
ld    d,$00      ; DE = A * 4 (table entry size)
ld    hl,$289C   ; Table address, see below
add   hl,de
ld    a,(hl)
in    a,($08)    ; Set zone 0
inc   hl
ld    a,(hl)
in    a,($09)    ; Set zone 1
inc   hl
ld    a,(hl)
in    a,($0A)    ; Set zone 2
inc   hl
ld    a,(hl)
in    a,($0B)    ; Set zone 3

The table at $289C is used to set the 4 zones like an unique $7800-bytes long one in 32KiB increments, meaning that $800 bytes are wasted at the end of each range (mapped to Z80 RAM).

Data at $289C:

1E 0E 06 02  = F000,  E000,  C000,  8000   "Big bank 0": $8000~ $F7FF   ($F800~ $FFFF  is wasted)
2E 16 0A 04  = 17000, 16000, 14000, 10000  "Big bank 1": $10000~$177FF  ($177FF~$17FFF is wasted)
3E 1E 0E 06  = 1F000, 1E000, 1C000, 18000  "Big bank 2": $18000~$1F7FF  ($1F7FF~$1FFFF is wasted)
4E 26 12 08  = 27000, 26000, 24000, 20000  "Big bank 3": $20000~$277FF  ($277FF~$27FFF is wasted)
5E 2E 16 0A  = 2F000, 2E000, 2C000, 28000  "Big bank 4": $28000~$2F7FF  ($2F7FF~$2FFFF is wasted)
6E 36 1A 0C  = 37000, 36000, 34000, 30000  "Big bank 5": $30000~$377FF  ($377FF~$37FFF is wasted)
7E 3E 1E 0E  = 3F000, 3E000, 3C000, 38000  "Big bank 6": $38000~$3F7FF  ($3F7FF~$3FFFF is wasted)

Note that the game has a 128KiB M1 ROM, but the table is long enough to map up to 256KiB.

On reset

On cartridge systems, Chipicon.png NEO-ZMC (and NEO-ZMC2 ?) initializes all zones to 0 (verified on hardware). Many sound drivers start up by initializing the zones properly like indicated above.

On CD systems, Chipicon.png NEO-SUD (or the system ROM ?) seems to initialize all zones before the game starts.

Bank settings at boot on a cartridge system, confirmed using Z80 ICE:

Z80banks.png