Write to the SPI range of ports */
| 203 | |
| 204 | /* Write to the SPI range of ports */ |
| 205 | static void spi_write(uint16_t addr, uint8_t byte, bool poke) { |
| 206 | (void)poke; |
| 207 | uint32_t shift = (addr & 3) << 3, value = (uint32_t)byte << shift, mask = ~(0xFFu << shift); |
| 208 | bool stateChanged = false; |
| 209 | switch (addr >> 2) { |
| 210 | case 0x00 >> 2: // CR0 |
| 211 | value &= 0xFFFF; |
| 212 | spi.cr0 &= mask; |
| 213 | spi.cr0 |= value; |
| 214 | break; |
| 215 | case 0x04 >> 2: // CR1 |
| 216 | value &= 0x7FFFFF; |
| 217 | spi.cr1 &= mask; |
| 218 | spi.cr1 |= value; |
| 219 | break; |
| 220 | case 0x08 >> 2: // CR2 |
| 221 | if (value & 1 << 2) { |
| 222 | spi.rfvi = spi.rfve = 0; |
| 223 | stateChanged = true; |
| 224 | } |
| 225 | if (value & 1 << 3) { |
| 226 | spi.tfvi = spi.tfve = 0; |
| 227 | stateChanged = true; |
| 228 | } |
| 229 | if ((spi.cr2 ^ value) & ~mask & (1 << 8 | 1 << 7 | 1 << 0)) { |
| 230 | stateChanged = true; |
| 231 | } |
| 232 | value &= 0xF83; |
| 233 | spi.cr2 &= mask; |
| 234 | spi.cr2 |= value; |
| 235 | break; |
| 236 | case 0x10 >> 2: // INTCTRL |
| 237 | value &= 0x1FFBF; |
| 238 | spi.intCtrl &= mask; |
| 239 | spi.intCtrl |= value; |
| 240 | spi.intStatus &= ~(1 << 3 | 1 << 2); |
| 241 | spi.intStatus |= spi_get_threshold_status(); |
| 242 | intrpt_set(INT_SPI, spi.intCtrl & spi.intStatus); |
| 243 | break; |
| 244 | case 0x18 >> 2: // DATA |
| 245 | spi.dtr &= mask; |
| 246 | spi.dtr |= value; |
| 247 | if (!shift && spi.tfve != SPI_TXFIFO_DEPTH) { |
| 248 | spi.txFifo[(spi.tfvi + spi.tfve++) & (SPI_TXFIFO_DEPTH - 1)] = spi.dtr; |
| 249 | stateChanged = true; |
| 250 | } |
| 251 | break; |
| 252 | } |
| 253 | if (stateChanged) { |
| 254 | spi_update(); |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | static const eZ80portrange_t pspi = { |
| 259 | .read = spi_read, |
nothing calls this directly
no test coverage detected