void piix_bus_master_write(uint16_t port, uint8_t val, void *priv) { int channel = (port & 8) ? 1 : 0; // pclog("PIIX Bus Master write %04X %02X %04x:%08x\n", port, val, CS, pc); switch (port & 7) { case 0: if ((val & 1) && !(piix_busmaster[channel].command & 1)) /*Start*/ { piix_busmaster[channel].ptr_cur = piix_busmaster[channel].ptr; piix_bus_master_next_addr(channel); piix_busmaster[channel].status |= 1; } if (!(val & 1) && (piix_busmaster[channel].command & 1)) /*Stop*/ piix_busmaster[channel].status &= ~1; piix_busmaster[channel].command = val; break; case 2: piix_busmaster[channel].status = (val & 0x60) | ((piix_busmaster[channel].status & ~val) & 6) | (piix_busmaster[channel].status & 1); break; case 4: piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffffff00) | val; break; case 5: piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xffff00ff) | (val << 8); break; case 6: piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0xff00ffff) | (val << 16); break; case 7: piix_busmaster[channel].ptr = (piix_busmaster[channel].ptr & 0x00ffffff) | (val << 24); break; } }
int piix_bus_master_sector_read(int channel, uint8_t *data) { int transferred = 0; if (!(piix_busmaster[channel].status & 1)) return 1; /*DMA disabled*/ while (transferred < 512) { if (piix_busmaster[channel].count < (512 - transferred) && piix_busmaster[channel].eot) fatal("DMA on channel %i - Read count less than 512! Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); mem_invalidate_range(piix_busmaster[channel].addr, piix_busmaster[channel].addr+511); if (piix_busmaster[channel].count < (512 - transferred)) { // pclog("Transferring smaller - %i bytes\n", piix_busmaster[channel].count); memcpy(&ram[piix_busmaster[channel].addr], data + transferred, piix_busmaster[channel].count); transferred += piix_busmaster[channel].count; piix_busmaster[channel].addr += piix_busmaster[channel].count; piix_busmaster[channel].addr %= (mem_size * 1024); piix_busmaster[channel].count = 0; } else { // pclog("Transferring larger - %i bytes\n", 512 - transferred); memcpy(&ram[piix_busmaster[channel].addr], data + transferred, 512 - transferred); piix_busmaster[channel].addr += (512 - transferred); piix_busmaster[channel].count -= (512 - transferred); transferred += (512 - transferred); } // pclog("DMA on channel %i - Addr %08X Count %04X EOT %i\n", channel, piix_busmaster[channel].addr, piix_busmaster[channel].count, piix_busmaster[channel].eot); if (!piix_busmaster[channel].count) { // pclog("DMA on channel %i - block over\n", channel); if (piix_busmaster[channel].eot) /*End of transfer?*/ { // pclog("DMA on channel %i - transfer over\n", channel); piix_busmaster[channel].status &= ~1; } else piix_bus_master_next_addr(channel); } } return 0; }