• entries
222
608
• views
588391

# Turning Japanese

928 views

The Z80 CPU uses 16-bit addressing, which limits it to a 64KB address space. As well as fitting the program ROM into this space, we need to fit in the machine's 8KB RAM, limiting us even further.

To get around this limitation, the memory is broken down into a series of windows ("frames"), and you can change what is visible in some of these windows.

The memory range $C000..$DFFF can be used to address the 8KB RAM. This is mirrored from $E000..$FFFF; that is, reads and writes to $E000 work as if you were reading and writing to$C000.

There are three other windows; from $0000..$3FFF, $4000..$7FFF and $8000..$BFFF. By changing the contents of RAM (addresses $FFFC..$FFFF) you can adjust what is accessible from these memory ranges.

The lower 1KB cannot be paged out - this is because when the device boots the contents of RAM (and thus paging registers) are undefined, and you need something fixed in place to set up the machine correctly.

I had already implemented most of the above, with two omissions. The first was that certain cartridges contained their own additional RAM chips (accessible by setting flag bits in paging register $FFFC) that could be used as saved game area. Ys appears to use this area, and so didn't work without it. That was the garbled screenshot I posted earlier: The Flash now works too. The second omission was that Codemasters games use a different mapping system to the standard one. Fortunately it is significantly simpler; the 32KB from$0000..$7FFF is locked, and the 16KB from$8000..$BFFF is offset based on a value previously written to address$8000. ($C000..$FFFF is 8KB work RAM as usual).

The Excellent Dizzy Collection as seen at the top of this post doesn't entirely work; when you pick a game it resets. Some other emulators do this too. The Game Gear games Cosmic Spacehead and Micro Machines (1 and 2) work well, though.

After some fiddling around with the VDP emulation and interrupts, some more games work (but I'm not sure why they now work):

Other parts of the emulator have been improved. It can now be set to either domestic (Japanese) or export (everyone else) modes, which affects some games in a variety of ways - from translated text, to removing the Mark III bumper screen, to changing the title of the game.

For Game Gear games, detecting whether it's a Japanese machine or not is simple - test the 6th bit returned when you read port $00. If it's set, you've got an export machine. However, port$00 is Game Gear-specific - the Master System hardware has a peculiarity that is used to detect region. There are two ports for controllers, and each controller has up, down, left, right, TL, TR and TH lines. You can set the TR and TH lines to be inputs or outputs (and the output level if configured as output) by writing to the I/O control port. If you set them to outputs and try and read from them, on export hardware you get the values you are telling them to output. On Japanese machines, however, they return 0s regardless of the chosen output level.

A more fun addition is Game Genie support. A simple call to Emulator.AddGameGenieCode("3A0-21C-2A2"); and Sonic can stand here all day:

Of course, the technical information above is my interpretation of what I've gathered so far from various documents from far brainier chaps than I, and the fact that all I have is a broken emulator indicates that it is probably complete rubbish. [smile]

For the memory addressing on the Z80, I'm pretty sure the only real limitation is that the ROM has to start at address 0, everything else is machine specific.

Also how many different mappers are there on the GG? I always hated that damn bank switching which is why I stuck to the GB and GBA. The GB only has 7 mappers and the GBAs memory model is flat.

Quote:
 Original post by Scet Also how many different mappers are there on the GG?
I'm only aware of two mappers - the "Standard" mapper as documented in the official specs, and the Codemasters mapper. I seem to remember reading something about the "Korean" mapper...

Flash carts and pirate carts might use their own mappers, but I have no interest in supporting those.

One of Excellent Dizzy Collection versions (I think the SMS one) resets when you choose one of the games because it's incomplete; the other (GG version) works OK, I think. The crux of the matter, however, is that you've not noticed that the Codemasters mapper actually supports paging in all 3 slots, with no fixed initial 1KB - to load one of the games it swaps out the code throughout the address space, and then jumps to $0000, hence the resetting behaviour you're seeing. The paging register for$0000-$3fff is at$0000, $4000-$7fff at $4000, and the one you already have for$8000-$bfff at$8000. The three games in EDC were originally going to be released separately, hence why they weren't written in a way that would let them share code. The mapper is wired to the /RESET line on the cartridge port so it can reset itself to a sane state, so there's no need for a fixed region.

The "Korean" mapper is a frame-2-only version of the Codemasters mapper, which is nice because you already wrote that.

The Japanese SMS and Mark III actually don't implement the output capability for TR and TH at all, so what gets read back from them is undefined (depends on what's plugged in and what it's doing, whether you gets 1s or 0s). Since the controller ports are active-low, it's more likely it'd read back 1s than 0s. It doesn't really make any difference to your implementation.

It's always interesting seeing the guts of a lesser-explored console like the Game Gear.

I wonder how much hardware the "PlayPal" devices share with the GG.

Quote:
 Original post by MaximZhao One of Excellent Dizzy Collection versions (I think the SMS one) resets when you choose one of the games because it's incomplete; the other (GG version) works OK, I think. The crux of the matter, however, is that you've not noticed that the Codemasters mapper actually supports paging in all 3 slots, with no fixed initial 1KB - to load one of the games it swaps out the code throughout the address space, and then jumps to $0000, hence the resetting behaviour you're seeing. I assumed that's what it was trying to do, but thanks for the information regarding the registers. I've been using Charles MacDonald's documentation, which only mentions the single register at$8000. (I work on this offline, so no Wiki access sadly). Are there (m)any games using the Korean mapper?

I assume that $0000,$4000 and $8000 are write-only registers; and that the standard mapper writes do go to RAM thanks to the RAM mirroring? That said, Quote:  SMS Power! Wiki Overwriting the RAM mirror at another address will not affect mapping. Does this mean that writing to$DFFF doesn't affect mapping, whereas writing to \$FFFF would?

On a similar note, with the difference in mapping with 1Mb or smaller cartridges - is that a property of the mapper chip on the cartridge (so games > 1Mb would use a different mapper)?

Does the ROM BIOS (with a built-in game) use a standard-style mapper?

Quote:
 The Japanese SMS and Mark III actually don't implement the output capability for TR and TH at all, so what gets read back from them is undefined (depends on what's plugged in and what it's doing, whether you gets 1s or 0s). Since the controller ports are active-low, it's more likely it'd read back 1s than 0s. It doesn't really make any difference to your implementation.
That makes rather more sense, then, than returning incorrect values. I shall change my implementation in any case. [smile]

I'm still not sure how to reset the I/O control ports; I set TH/TR to inputs and output levels low, and that seems to work...

## Create an account

Register a new account