Path: blob/master/libsnes/bsnes/snes/chip/sa1/dma/dma.cpp
2 views
#ifdef SA1_CPP12//====================3//direct data transfer4//====================56void SA1::dma_normal() {7while(mmio.dtc--) {8uint8 data = regs.mdr;9uint32 dsa = mmio.dsa++;10uint32 dda = mmio.dda++;1112//source and destination cannot be the same13if(mmio.sd == DMA::SourceBWRAM && mmio.dd == DMA::DestBWRAM) continue;14if(mmio.sd == DMA::SourceIRAM && mmio.dd == DMA::DestIRAM ) continue;1516switch(mmio.sd) {17case DMA::SourceROM: {18if((dsa & 0x408000) == 0x008000 || (dsa & 0xc00000) == 0xc00000) {19data = bus_read(dsa);20}21} break;2223case DMA::SourceBWRAM: {24if((dsa & 0x40e000) == 0x006000 || (dsa & 0xf00000) == 0x400000) {25data = bus_read(dsa);26}27} break;2829case DMA::SourceIRAM: {30data = iram.read(dsa & 0x07ff);31} break;32}3334switch(mmio.dd) {35case DMA::DestBWRAM: {36if((dda & 0x40e000) == 0x006000 || (dda & 0xf00000) == 0x400000) {37bus_write(dda, data);38}39} break;4041case DMA::DestIRAM: {42iram.write(dda & 0x07ff, data);43} break;44}45}4647mmio.dma_irqfl = true;48if(mmio.dma_irqen) mmio.dma_irqcl = 0;49}5051//((byte & 6) << 3) + (byte & 1) explanation:52//transforms a byte index (0-7) into a planar index:53//result[] = { 0, 1, 16, 17, 32, 33, 48, 49 };54//works for 2bpp, 4bpp and 8bpp modes5556//===========================57//type-1 character conversion58//===========================5960void SA1::dma_cc1() {61cpubwram.dma = true;62mmio.chdma_irqfl = true;63if(mmio.chdma_irqen) {64mmio.chdma_irqcl = 0;65cpu.regs.irq = 1;66}67}6869uint8 SA1::dma_cc1_read(unsigned addr) {70//16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp)71unsigned charmask = (1 << (6 - mmio.dmacb)) - 1;7273if((addr & charmask) == 0) {74//buffer next character to I-RAM75unsigned bpp = 2 << (2 - mmio.dmacb);76unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb;77unsigned bwmask = cartridge.ram.size() - 1;78unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb);79unsigned ty = (tile >> mmio.dmasize);80unsigned tx = tile & ((1 << mmio.dmasize) - 1);81unsigned bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp;8283for(unsigned y = 0; y < 8; y++) {84uint64 data = 0;85for(unsigned byte = 0; byte < bpp; byte++) {86data |= (uint64)cartridge.ram.read((bwaddr + byte) & bwmask) << (byte << 3);87}88bwaddr += bpl;8990uint8 out[] = { 0, 0, 0, 0, 0, 0, 0, 0 };91for(unsigned x = 0; x < 8; x++) {92out[0] |= (data & 1) << (7 - x); data >>= 1;93out[1] |= (data & 1) << (7 - x); data >>= 1;94if(mmio.dmacb == 2) continue;95out[2] |= (data & 1) << (7 - x); data >>= 1;96out[3] |= (data & 1) << (7 - x); data >>= 1;97if(mmio.dmacb == 1) continue;98out[4] |= (data & 1) << (7 - x); data >>= 1;99out[5] |= (data & 1) << (7 - x); data >>= 1;100out[6] |= (data & 1) << (7 - x); data >>= 1;101out[7] |= (data & 1) << (7 - x); data >>= 1;102}103104for(unsigned byte = 0; byte < bpp; byte++) {105unsigned p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1);106iram.write(p & 0x07ff, out[byte]);107}108}109}110111return iram.read((mmio.dda + (addr & charmask)) & 0x07ff);112}113114//===========================115//type-2 character conversion116//===========================117118void SA1::dma_cc2() {119//select register file index (0-7 or 8-15)120const uint8 *brf = &mmio.brf[(dma.line & 1) << 3];121unsigned bpp = 2 << (2 - mmio.dmacb);122unsigned addr = mmio.dda & 0x07ff;123addr &= ~((1 << (7 - mmio.dmacb)) - 1);124addr += (dma.line & 8) * bpp;125addr += (dma.line & 7) * 2;126127for(unsigned byte = 0; byte < bpp; byte++) {128uint8 output = 0;129for(unsigned bit = 0; bit < 8; bit++) {130output |= ((brf[bit] >> byte) & 1) << (7 - bit);131}132iram.write(addr + ((byte & 6) << 3) + (byte & 1), output);133}134135dma.line = (dma.line + 1) & 15;136}137138#endif139140141