I know this may sound strange, but :
could someone explain to me one time and for all the way 32x32, 64x64 etc write modes selectable in $2115 works?
SNES DMA write pattern
Moderator: ZSNES Mods
You might want to clear that up because I don't think anyone will get much sense out of that post.
If you mean writing to tile maps, then the Increment mode of 32 words will help alot. You can write to a column of tile map entries in succession because each row of entries happens ot be 64 bytes long. If you're in 64x64 mode you can just change the target tilemap.
If you're talking about 'address translation' then I don't have a clue. The concept is simple but I'm having alot of trouble finding a good scenario where it will come in handy. Someone please enlighten me
.
Also, development forum is the place for this. Any SNES development including ZSNES goes over there.
If you mean writing to tile maps, then the Increment mode of 32 words will help alot. You can write to a column of tile map entries in succession because each row of entries happens ot be 64 bytes long. If you're in 64x64 mode you can just change the target tilemap.
If you're talking about 'address translation' then I don't have a clue. The concept is simple but I'm having alot of trouble finding a good scenario where it will come in handy. Someone please enlighten me

Also, development forum is the place for this. Any SNES development including ZSNES goes over there.
Great. Sorry for the wrong posting, first post here and too lazy to check for the right forum to post. Mod's feel free to move !!!smkdan wrote:
Also, development forum is the place for this. Any SNES development including ZSNES goes over there.
Yes actually that's what I dont get. How does DMA map its writes to the VRAM addres space accordingli to the settings of $2115?smkdan wrote: If you mean writing to tile maps, then the Increment mode of 32 words will help alot. You can write to a column of tile map entries in succession because each row of entries happens ot be 64 bytes long. If you're in 64x64 mode you can just change the target tilemap.
If you're talking about 'address translation' then I don't have a clue. The concept is simple but I'm having alot of trouble finding a good scenario where it will come in handy. Someone please enlighten me.
for example : 32x32 means
a) write word at Offset $xxxxxx to VRAM $0000
b) write word at Offset $yyyyyy to VRAM $0020
c) write word at Offset $zzzzzz to VRAM $0040
.
.
.
and so on? How many times? 32? Or for size_of_the_DMA_tx times?
Also, if it writes 32 times in steps of 32 bytes, does it write the same value (aka takes it from the same source offset) 32 times?
sou you would have
a) write #$FFFF to VRAM $0000
b) write #$FFFF to VRAM $0020
c) write #$FFFF to VRAM $0040
.
.
.
?
Please enlighten me!
Re: SNES DMA write pattern
DMA has nothing to do with $2115. DMA just writes to registers $2118/$2119 that subsequently map where to write to VRAM at. There are two separate settings for $2115 writes: mapping and increment size. The code is more descriptive than anything I could say ...
VRAM reads are even more fun, but I'll spare you those details as you didn't ask :)
Code: Select all
//VMAIN
void mmio_w2115(uint8 value) {
regs.vram_incmode = !!(value & 0x80);
regs.vram_mapping = (value >> 2) & 3;
switch(value & 3) {
case 0: regs.vram_incsize = 1; break;
case 1: regs.vram_incsize = 32; break;
case 2: regs.vram_incsize = 128; break;
case 3: regs.vram_incsize = 128; break;
}
}
//VMDATAL
void mmio_w2118(uint8 value) {
uint16 addr = get_vram_address();
vram_mmio_write(addr, value);
if(regs.vram_incmode == 0) {
regs.vram_addr += regs.vram_incsize;
}
}
//VMDATAH
void mmio_w2119(uint8 value) {
uint16 addr = get_vram_address() + 1;
vram_mmio_write(addr, value);
if(regs.vram_incmode == 1) {
regs.vram_addr += regs.vram_incsize;
}
}
uint16 get_vram_address() {
uint16 addr = regs.vram_addr;
switch(regs.vram_mapping) {
//mere mortals dare not try and understand the below bit blender ...
case 0: break;
case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break;
case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break;
case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break;
}
return (addr << 1);
}
Re: SNES DMA write pattern
Thanks byuu! ^^byuu wrote:DMA has nothing to do with $2115. DMA just writes to registers $2118/$2119 that subsequently map where to write to VRAM at. There are two separate settings for $2115 writes: mapping and increment size. The code is more descriptive than anything I could say ...
VRAM reads are even more fun, but I'll spare you those details as you didn't askCode: Select all
//VMAIN void mmio_w2115(uint8 value) { regs.vram_incmode = !!(value & 0x80); regs.vram_mapping = (value >> 2) & 3; switch(value & 3) { case 0: regs.vram_incsize = 1; break; case 1: regs.vram_incsize = 32; break; case 2: regs.vram_incsize = 128; break; case 3: regs.vram_incsize = 128; break; } } //VMDATAL void mmio_w2118(uint8 value) { uint16 addr = get_vram_address(); vram_mmio_write(addr, value); if(regs.vram_incmode == 0) { regs.vram_addr += regs.vram_incsize; } } //VMDATAH void mmio_w2119(uint8 value) { uint16 addr = get_vram_address() + 1; vram_mmio_write(addr, value); if(regs.vram_incmode == 1) { regs.vram_addr += regs.vram_incsize; } } uint16 get_vram_address() { uint16 addr = regs.vram_addr; switch(regs.vram_mapping) { //mere mortals dare not try and understand the below bit blender ... case 0: break; case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break; case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break; case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break; } return (addr << 1); }
Thats exactly what I was looking for!
Nice to see your emulator is coming so well along !