Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libsnes/bsnes/snes/chip/sa1/dma/dma.cpp
2 views
1
#ifdef SA1_CPP
2
3
//====================
4
//direct data transfer
5
//====================
6
7
void SA1::dma_normal() {
8
while(mmio.dtc--) {
9
uint8 data = regs.mdr;
10
uint32 dsa = mmio.dsa++;
11
uint32 dda = mmio.dda++;
12
13
//source and destination cannot be the same
14
if(mmio.sd == DMA::SourceBWRAM && mmio.dd == DMA::DestBWRAM) continue;
15
if(mmio.sd == DMA::SourceIRAM && mmio.dd == DMA::DestIRAM ) continue;
16
17
switch(mmio.sd) {
18
case DMA::SourceROM: {
19
if((dsa & 0x408000) == 0x008000 || (dsa & 0xc00000) == 0xc00000) {
20
data = bus_read(dsa);
21
}
22
} break;
23
24
case DMA::SourceBWRAM: {
25
if((dsa & 0x40e000) == 0x006000 || (dsa & 0xf00000) == 0x400000) {
26
data = bus_read(dsa);
27
}
28
} break;
29
30
case DMA::SourceIRAM: {
31
data = iram.read(dsa & 0x07ff);
32
} break;
33
}
34
35
switch(mmio.dd) {
36
case DMA::DestBWRAM: {
37
if((dda & 0x40e000) == 0x006000 || (dda & 0xf00000) == 0x400000) {
38
bus_write(dda, data);
39
}
40
} break;
41
42
case DMA::DestIRAM: {
43
iram.write(dda & 0x07ff, data);
44
} break;
45
}
46
}
47
48
mmio.dma_irqfl = true;
49
if(mmio.dma_irqen) mmio.dma_irqcl = 0;
50
}
51
52
//((byte & 6) << 3) + (byte & 1) explanation:
53
//transforms a byte index (0-7) into a planar index:
54
//result[] = { 0, 1, 16, 17, 32, 33, 48, 49 };
55
//works for 2bpp, 4bpp and 8bpp modes
56
57
//===========================
58
//type-1 character conversion
59
//===========================
60
61
void SA1::dma_cc1() {
62
cpubwram.dma = true;
63
mmio.chdma_irqfl = true;
64
if(mmio.chdma_irqen) {
65
mmio.chdma_irqcl = 0;
66
cpu.regs.irq = 1;
67
}
68
}
69
70
uint8 SA1::dma_cc1_read(unsigned addr) {
71
//16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp)
72
unsigned charmask = (1 << (6 - mmio.dmacb)) - 1;
73
74
if((addr & charmask) == 0) {
75
//buffer next character to I-RAM
76
unsigned bpp = 2 << (2 - mmio.dmacb);
77
unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb;
78
unsigned bwmask = cartridge.ram.size() - 1;
79
unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb);
80
unsigned ty = (tile >> mmio.dmasize);
81
unsigned tx = tile & ((1 << mmio.dmasize) - 1);
82
unsigned bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp;
83
84
for(unsigned y = 0; y < 8; y++) {
85
uint64 data = 0;
86
for(unsigned byte = 0; byte < bpp; byte++) {
87
data |= (uint64)cartridge.ram.read((bwaddr + byte) & bwmask) << (byte << 3);
88
}
89
bwaddr += bpl;
90
91
uint8 out[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
92
for(unsigned x = 0; x < 8; x++) {
93
out[0] |= (data & 1) << (7 - x); data >>= 1;
94
out[1] |= (data & 1) << (7 - x); data >>= 1;
95
if(mmio.dmacb == 2) continue;
96
out[2] |= (data & 1) << (7 - x); data >>= 1;
97
out[3] |= (data & 1) << (7 - x); data >>= 1;
98
if(mmio.dmacb == 1) continue;
99
out[4] |= (data & 1) << (7 - x); data >>= 1;
100
out[5] |= (data & 1) << (7 - x); data >>= 1;
101
out[6] |= (data & 1) << (7 - x); data >>= 1;
102
out[7] |= (data & 1) << (7 - x); data >>= 1;
103
}
104
105
for(unsigned byte = 0; byte < bpp; byte++) {
106
unsigned p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1);
107
iram.write(p & 0x07ff, out[byte]);
108
}
109
}
110
}
111
112
return iram.read((mmio.dda + (addr & charmask)) & 0x07ff);
113
}
114
115
//===========================
116
//type-2 character conversion
117
//===========================
118
119
void SA1::dma_cc2() {
120
//select register file index (0-7 or 8-15)
121
const uint8 *brf = &mmio.brf[(dma.line & 1) << 3];
122
unsigned bpp = 2 << (2 - mmio.dmacb);
123
unsigned addr = mmio.dda & 0x07ff;
124
addr &= ~((1 << (7 - mmio.dmacb)) - 1);
125
addr += (dma.line & 8) * bpp;
126
addr += (dma.line & 7) * 2;
127
128
for(unsigned byte = 0; byte < bpp; byte++) {
129
uint8 output = 0;
130
for(unsigned bit = 0; bit < 8; bit++) {
131
output |= ((brf[bit] >> byte) & 1) << (7 - bit);
132
}
133
iram.write(addr + ((byte & 6) << 3) + (byte & 1), output);
134
}
135
136
dma.line = (dma.line + 1) & 15;
137
}
138
139
#endif
140
141