DMA: remove a few debug messages and rewrite memory error handling

Tue, 28 Dec 2010 18:59:15 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Tue, 28 Dec 2010 18:59:15 +0000
changeset 67
d6358bf2f5c2
parent 66
8ca92162fa89
child 68
58318104858b

DMA: remove a few debug messages and rewrite memory error handling

src/main.c file | annotate | diff | revisions
     1.1 --- a/src/main.c	Tue Dec 28 18:58:51 2010 +0000
     1.2 +++ b/src/main.c	Tue Dec 28 18:59:15 2010 +0000
     1.3 @@ -219,7 +219,6 @@
     1.4  		// Run the DMA engine
     1.5  		//
     1.6  		if (state.dmaen) { //((state.dma_count < 0x3fff) && state.dmaen) {
     1.7 -			printf("DMA: copy addr=%08X count=%08X idmarw=%d dmarw=%d\n", state.dma_address, state.dma_count, state.idmarw, state.dma_reading);
     1.8  			// DMA ready to go -- so do it.
     1.9  			size_t num = 0;
    1.10  			while (state.dma_count < 0x4000) {
    1.11 @@ -230,25 +229,60 @@
    1.12  
    1.13  				// Evidently we have more words to copy. Copy them.
    1.14  				if (!wd2797_get_drq(&state.fdc_ctx)) {
    1.15 -					printf("\tDMABAIL: no data! dmac=%04X dmaa=%04X\n", state.dma_count, state.dma_address);
    1.16  					// Bail out, no data available. Try again later.
    1.17  					// TODO: handle HDD controller too
    1.18  					break;
    1.19  				}
    1.20  
    1.21 +				// Check memory access permissions
    1.22 +				// TODO: enforce these!!!! use ACCESS_CHECK_* for guidance.
    1.23 +				bool access_ok;
    1.24 +				switch (checkMemoryAccess(state.dma_address, !state.dma_reading)) {
    1.25 +					case MEM_PAGEFAULT:
    1.26 +					case MEM_PAGE_NO_WE:
    1.27 +					case MEM_KERNEL:
    1.28 +					case MEM_UIE:
    1.29 +						access_ok = false;
    1.30 +						break;
    1.31 +					case MEM_ALLOWED:
    1.32 +						access_ok = true;
    1.33 +						break;
    1.34 +				}
    1.35 +				if (!access_ok) {
    1.36 +					// TODO!
    1.37 +					// TODO: FIXME: if we get a pagefault, it NEEDS to be tagged as 'peripheral sourced'... this is a HACK!
    1.38 +					printf("REALLY BIG FSCKING HUGE ERROR: DMA Memory Access caused a FAULT!\n");
    1.39 +				}
    1.40 +
    1.41 +				// Map logical address to a physical RAM address
    1.42 +				uint32_t newAddr = mapAddr(state.dma_address, !state.dma_reading);
    1.43 +
    1.44  				if (!state.dma_reading) {
    1.45 -					// Data available. Get it from the FDC.
    1.46 +					// Data available. Get it from the FDC. TODO: handle HDD too
    1.47  					d = wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA);
    1.48  					d <<= 8;
    1.49  					d += wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA);
    1.50  
    1.51 -					// TODO: FIXME: if we get a pagefault, it NEEDS to be tagged as 'peripheral sourced'... this is a HACK!
    1.52 +					if (newAddr <= 0x1FFFFF) {
    1.53 +						WR16(state.base_ram, newAddr, state.base_ram_size - 1, d);
    1.54 +					} else if (newAddr >= 0x200000) {
    1.55 +						WR16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, d);
    1.56 +					}
    1.57  					m68k_write_memory_16(state.dma_address, d);
    1.58  				} else {
    1.59 -					// Data write to FDC
    1.60 -					// TODO: FIXME: if we get a pagefault, it NEEDS to be tagged as 'peripheral sourced'... this is a HACK!
    1.61 -					d = m68k_read_memory_16(state.dma_address);
    1.62 +					// Data write to FDC. TODO: handle HDD too.
    1.63  
    1.64 +					// Get the data from RAM
    1.65 +					if (newAddr <= 0x1fffff) {
    1.66 +						d = RD16(state.base_ram, newAddr, state.base_ram_size - 1);
    1.67 +					} else {
    1.68 +						if (newAddr <= (state.exp_ram_size + 0x200000 - 1))
    1.69 +							d = RD16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1);
    1.70 +						else
    1.71 +							d = 0xffff;
    1.72 +					}
    1.73 +
    1.74 +					// Send the data to the FDD
    1.75  					wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d >> 8));
    1.76  					wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d & 0xff));
    1.77  				}
    1.78 @@ -261,8 +295,7 @@
    1.79  
    1.80  			// Turn off DMA engine if we finished this cycle
    1.81  			if (state.dma_count >= 0x4000) {
    1.82 -				printf("\tDMATRAN: transfer complete! dmaa=%06X, dmac=%04X\n", state.dma_address, state.dma_count);
    1.83 -				// FIXME? apparently this isn't required...?
    1.84 +				// FIXME? apparently this isn't required... or is it?
    1.85  //				state.dma_count = 0;
    1.86  				state.dmaen = false;
    1.87  			}