src/main.c

changeset 53
e1693c4b8a0c
parent 52
a350dfa92895
child 55
ba6b8e570062
child 76
2ef98ea1e944
     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) {