Sega Master System / Mark III / Game Gear|
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew
Memory Mapping Basic TutorialPosted: Sun Apr 21, 2019 5:27 pm
Last edited by IllusionOfMana on Tue May 07, 2019 2:43 am; edited 1 time in total
I dont know if this has been covered yet however its not really something covered very clearly on the dev side of SMS Power.
Ill try my best to cover it here.
Important Info Before Starting:
1. This tutorial only covers programs written with the WLA-DX compiler and may not provide the same results when applied to a different IDE.
2. This tutorial covers memory mapping based on Sega's Memory Mapping Chip or MMC. If you're using another method to map Large Format ROMs to the z80 CPU please refer to that mappers documentation or to the custom memory latches schematic you plan on using.
The z80 8-bit CPU has a view-able memory map of 64 KB.
By default this map is separated into 4 smaller 16 KB windows called slots.
Breakdown of Slots:
A slot can be thought of as a sort of independent viewing window for a 16KB section of memory within the entire memory space. These windows can be offset in order to view different parts of memory at any given time, with 4 slots you can view 4 different windows of memory unrelated to each other. Slots can even be swapped out to view separate memory banks.
Breakdown of Banks:
Memory banks are separate chunks of memory typically with an even offset to one another. Each bank can typically be any size the developer wishes between 1 Byte and 64 KBytes. For easy results its best to set each bank to 16 KB so it sits within a slot of the z80s memory map.
Slot 0 should always stay locked, by this I mean you should NEVER attempt to swap it with another as it contains the boot information. Its best to keep the meat of your code here from my experience.
Slot 3 is mapped to RAM, even though its 16KB in size only the first 8KB is unique, the back 8KB is a mirror of the first 8KB, this can be useful for some quick read tricks.
lets look at 3 important bits of code used in the WLA-z80 spec.
First the memory setup.
slot 0 $0000 ; rom bank 0 (0-16 kb). ;prog rom
slot 1 $4000 ; rom bank 1 (16-32 kb). ;sprite rom
slot 2 $8000 ;tile graphics/sound rom
slot 3 $c000 ;ram
;start rom bank mapping
Starting with .memorymap this keyword tells the interpreter that you are defining the z80s slot map and default slot. Think of the default slot as a boot drive on a computer and is the first part of the program the computer looks at before anything else. The defaultslot macro followed by the slot number defines which slot will be the default on boot, Its best to always keep this slot set to 0.
the slotsize macro describes itself and defines the size of each slot. slot size can be smaller than 16KB but its not recommended. Also the total size of all 4 slots cannot exceed 64KB.
the slot macro followed by its ID number and offset are also pretty self explanatory. When setting up each slot starting with slot 0 you can define the offset in z80 memory space where each slot begins, keep in mind the size of your slot so that you can set the offset of the next slot appropriately. This helps keep slots from overlapping each other on the memory map.
.endme will tell the interpreter that you're done defining the z80s memory map
starting with the .rombankmap keyword this tells the interpreter that you're about to define the entire memory map both within and outside of the z80s viewspace.
The bankstotal macro followed by a user defined value will tell the interpreter how many memory banks you have in total.
the banksize macro followed by a value defines the size of each bank. to keep it simple its best to set each bank to 16KB so that they fit within the default slot size of the z80. In some cases this may not be optimal but you can accomplish a lot with just this method.
finally banks macro and its value sets how many banks are being used, I typically keep this at the same value as the bankstotal macro as I currently dont know of any uses where it needs to be different.
the .endro keyword tells the interpreter you're done defining the bank map.
ld a, \1
ld ($FFFE), a
ld a, \1
ld ($FFFF), a
These macros are very important, you dont need to know how they work you just need to know that they tell the z80 to swap either slot 1 or slot 2 of the z80s memory map with a new bank based on the offset given. Its best to define these at the very beginning of your first script.
here is how thats used:
where CutSceneTiles is a label you should define at the start of a bank. Here is how you would set up that label to be read as the start of a new bank being loaded.
.bank 7 slot 2
At the start of the CutSceneTiles: code section we use the .bank macro to tell the interpreter that code beyond this will reside in bank 7 and is meant to be loaded at the global offset of slot 2. the .org macro followed by its value defines the local offset the following code has within the slot its loaded. by default its best to just load each bank at the beginning of the slot.
I hope this helps break down how the memory system works on the z80 and more specifically the SMS platform. If there are any errors please let me know. Also if you feel that something could be explained better let me know or feel free to add your input.
||Posted: Thu May 02, 2019 8:50 pm|
you're correct, but you're referring to the way the SEGA mapper works, and there are some different ones (some even use 8K banks).
Also, when placing assets in banks, I suggest using WLA-DX' superfree keyword to avoid manual placement.
||Posted: Tue May 07, 2019 2:28 am|
Thanks! I'll get around to editing my tutorial as well as adding information about the use of WLA-DX's superfree keyword.