1.1 --- a/src/main.c Sun Dec 05 16:20:00 2010 +0000 1.2 +++ b/src/main.c Mon Dec 06 01:26:37 2010 +0000 1.3 @@ -208,7 +208,68 @@ 1.4 // 41667 cycles per timeslot. 1.5 clock_cycles += m68k_execute(10e6/TIMESLOT_FREQUENCY); 1.6 1.7 - // TODO: run DMA here 1.8 + // Run the DMA engine 1.9 + // 1.10 + if (state.dmaen) { //((state.dma_count < 0x3fff) && state.dmaen) { 1.11 + printf("DMA: copy addr=%08X count=%08X idmarw=%d dmarw=%d\n", state.dma_address, state.dma_count, state.idmarw, state.dma_reading); 1.12 + if (state.dmaenb) { 1.13 + state.dmaenb = false; 1.14 +// state.dma_address++; 1.15 + state.dma_count++; 1.16 + } 1.17 + // DMA ready to go -- so do it. 1.18 + size_t num = 0; 1.19 + while (state.dma_count < 0x4000) { 1.20 + uint16_t d = 0; 1.21 + 1.22 + // num tells us how many words we've copied. If this is greater than the per-timeslot DMA maximum, bail out! 1.23 + if (num > (1e6/TIMESLOT_FREQUENCY)) break; 1.24 + 1.25 + // Evidently we have more words to copy. Copy them. 1.26 + if (!wd2797_get_drq(&state.fdc_ctx)) { 1.27 + printf("\tDMABAIL: no data! dmac=%04X dmaa=%04X\n", state.dma_count, state.dma_address); 1.28 + // Bail out, no data available. Try again later. 1.29 + // TODO: handle HDD controller too 1.30 + break; 1.31 + } 1.32 + 1.33 + if (!state.dma_reading) { 1.34 + // Data available. Get it from the FDC. 1.35 + d = wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.36 + d <<= 8; 1.37 + d += wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.38 + 1.39 + // TODO: FIXME: if we get a pagefault, it NEEDS to be tagged as 'peripheral sourced'... this is a HACK! 1.40 + m68k_write_memory_16(state.dma_address << 1, d); 1.41 + } else { 1.42 + // Data write to FDC 1.43 + // TODO: FIXME: if we get a pagefault, it NEEDS to be tagged as 'peripheral sourced'... this is a HACK! 1.44 + d = m68k_read_memory_16(state.dma_address << 1); 1.45 + 1.46 + wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d >> 8)); 1.47 + wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d & 0xff)); 1.48 + } 1.49 + 1.50 + // Increment DMA address 1.51 + state.dma_address++; 1.52 + // Increment number of words transferred 1.53 + num++; state.dma_count++; 1.54 + } 1.55 + 1.56 + // Turn off DMA engine if we finished this cycle 1.57 + if (state.dma_count >= 0x4000) { 1.58 + printf("\tDMATRAN: transfer complete! dmaa=%06X, dmac=%04X\n", state.dma_address, state.dma_count); 1.59 + state.dma_count = 0; 1.60 + state.dmaen = false; 1.61 + } 1.62 + } 1.63 + 1.64 + // Any interrupts? 1.65 + if (wd2797_get_irq(&state.fdc_ctx)) { 1.66 + m68k_set_irq(2); 1.67 + } else { 1.68 + m68k_set_irq(0); 1.69 + } 1.70 1.71 // Is it time to run the 60Hz periodic interrupt yet? 1.72 if (clock_cycles > CLOCKS_PER_60HZ) {