move edge-sensitive FDC IRQ to main()

Mon, 06 Dec 2010 08:27:21 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 06 Dec 2010 08:27:21 +0000
changeset 76
2ef98ea1e944
parent 75
976dfa068839
child 77
e7898cbae0c6
child 78
c149c13aff1c

move edge-sensitive FDC IRQ to main()

src/main.c file | annotate | diff | revisions
src/memory.c file | annotate | diff | revisions
src/wd279x.c file | annotate | diff | revisions
src/wd279x.h file | annotate | diff | revisions
     1.1 diff -r 976dfa068839 -r 2ef98ea1e944 src/main.c
     1.2 --- a/src/main.c	Mon Dec 06 08:27:05 2010 +0000
     1.3 +++ b/src/main.c	Mon Dec 06 08:27:21 2010 +0000
     1.4 @@ -196,12 +196,13 @@
     1.5  	 * The 3B1 CPU runs at 10MHz, with DMA running at 1MHz and video refreshing at
     1.6  	 * around 60Hz (???), with a 60Hz periodic interrupt.
     1.7  	 */
     1.8 -	const uint32_t TIMESLOT_FREQUENCY = 240;	// Hz
     1.9 +	const uint32_t TIMESLOT_FREQUENCY = 1000;//240;	// Hz
    1.10  	const uint32_t MILLISECS_PER_TIMESLOT = 1e3 / TIMESLOT_FREQUENCY;
    1.11  	const uint32_t CLOCKS_PER_60HZ = (10e6 / 60);
    1.12  	uint32_t next_timeslot = SDL_GetTicks() + MILLISECS_PER_TIMESLOT;
    1.13  	uint32_t clock_cycles = 0;
    1.14  	bool exitEmu = false;
    1.15 +	bool lastirq_fdc = false;
    1.16  	for (;;) {
    1.17  		// Run the CPU for however many cycles we need to. CPU core clock is
    1.18  		// 10MHz, and we're running at 240Hz/timeslot. Thus: 10e6/240 or
    1.19 @@ -209,12 +210,10 @@
    1.20  		clock_cycles += m68k_execute(10e6/TIMESLOT_FREQUENCY);
    1.21  
    1.22  		// Run the DMA engine
    1.23 -		//
    1.24 -		if (state.dmaen) { //((state.dma_count < 0x3fff) && state.dmaen) {
    1.25 +		if (state.dmaen) {
    1.26  			printf("DMA: copy addr=%08X count=%08X idmarw=%d dmarw=%d\n", state.dma_address, state.dma_count, state.idmarw, state.dma_reading);
    1.27  			if (state.dmaenb) {
    1.28  				state.dmaenb = false;
    1.29 -//				state.dma_address++;
    1.30  				state.dma_count++;
    1.31  			}
    1.32  			// DMA ready to go -- so do it.
    1.33 @@ -227,7 +226,7 @@
    1.34  
    1.35  				// Evidently we have more words to copy. Copy them.
    1.36  				if (!wd2797_get_drq(&state.fdc_ctx)) {
    1.37 -					printf("\tDMABAIL: no data! dmac=%04X dmaa=%04X\n", state.dma_count, state.dma_address);
    1.38 +//					printf("\tDMABAIL: no data! dmac=%04X dmaa=%04X\n", state.dma_count, state.dma_address);
    1.39  					// Bail out, no data available. Try again later.
    1.40  					// TODO: handle HDD controller too
    1.41  					break;
    1.42 @@ -258,15 +257,20 @@
    1.43  
    1.44  			// Turn off DMA engine if we finished this cycle
    1.45  			if (state.dma_count >= 0x4000) {
    1.46 -				printf("\tDMATRAN: transfer complete! dmaa=%06X, dmac=%04X\n", state.dma_address, state.dma_count);
    1.47 +//				printf("\tDMATRAN: transfer complete! dmaa=%06X, dmac=%04X\n", state.dma_address, state.dma_count);
    1.48  				state.dma_count = 0;
    1.49  				state.dmaen = false;
    1.50  			}
    1.51  		}
    1.52  
    1.53  		// Any interrupts?
    1.54 -		if (wd2797_get_irq(&state.fdc_ctx)) {
    1.55 -			m68k_set_irq(2);
    1.56 +		if (!lastirq_fdc) {
    1.57 +			if (wd2797_get_irq(&state.fdc_ctx)) {
    1.58 +				lastirq_fdc = true;
    1.59 +				m68k_set_irq(2);
    1.60 +			} else {
    1.61 +				lastirq_fdc = false;
    1.62 +			}
    1.63  		} else {
    1.64  			m68k_set_irq(0);
    1.65  		}
     2.1 diff -r 976dfa068839 -r 2ef98ea1e944 src/memory.c
     2.2 --- a/src/memory.c	Mon Dec 06 08:27:05 2010 +0000
     2.3 +++ b/src/memory.c	Mon Dec 06 08:27:21 2010 +0000
     2.4 @@ -244,7 +244,7 @@
     2.5  				break;
     2.6  			case 0x070000:				// Line Printer Status Register
     2.7  				data = 0x00120012;	// no parity error, no line printer error, no irqs from FDD or HDD
     2.8 -				data |= (state.fdc_ctx.irql) ? 0x00080008 : 0;	// FIXME! HACKHACKHACK! shouldn't peek inside FDC structs like this
     2.9 +				data |= wd2797_get_irq(&state.fdc_ctx) ? 0x00080008 : 0;
    2.10  				break;
    2.11  			case 0x080000:				// Real Time Clock
    2.12  				break;
    2.13 @@ -414,7 +414,7 @@
    2.14  				break;
    2.15  			case 0x070000:				// Line Printer Status Register
    2.16  				data = 0x0012;	// no parity error, no line printer error, no irqs from FDD or HDD
    2.17 -				data |= (state.fdc_ctx.irql) ? 0x0008 : 0;	// FIXME! HACKHACKHACK! shouldn't peek inside FDC structs like this
    2.18 +				data |= wd2797_get_irq(&state.fdc_ctx) ? 0x0008 : 0;
    2.19  				break;
    2.20  			case 0x080000:				// Real Time Clock
    2.21  				break;
    2.22 @@ -590,13 +590,13 @@
    2.23  				// TODO: how to handle this in 8bit mode?
    2.24  				break;
    2.25  			case 0x070000:				// Line Printer Status Register
    2.26 -				printf("\tLPSR RD8 fdc irql=%d, irqe=%d\n", state.fdc_ctx.irql, state.fdc_ctx.irqe);
    2.27  				if (address & 1) {
    2.28  					data = 0x12;	// no parity error, no line printer error, no irqs from FDD or HDD
    2.29 -					data |= (state.fdc_ctx.irql) ? 0x08 : 0;	// FIXME! HACKHACKHACK! shouldn't peek inside FDC structs like this
    2.30 +					data |= wd2797_get_irq(&state.fdc_ctx) ? 0x08 : 0;
    2.31  				} else {
    2.32  					data = 0;
    2.33  				}
    2.34 +				handled = true;
    2.35  				break;
    2.36  			case 0x080000:				// Real Time Clock
    2.37  				break;
     3.1 diff -r 976dfa068839 -r 2ef98ea1e944 src/wd279x.c
     3.2 --- a/src/wd279x.c	Mon Dec 06 08:27:05 2010 +0000
     3.3 +++ b/src/wd279x.c	Mon Dec 06 08:27:21 2010 +0000
     3.4 @@ -32,19 +32,20 @@
     3.5  	ctx->track = ctx->head = ctx->sector = 0;
     3.6  
     3.7  	// no IRQ pending
     3.8 -	ctx->irql = ctx->irqe = false;
     3.9 +	ctx->irq = false;
    3.10  
    3.11  	// no data available
    3.12  	ctx->data_pos = ctx->data_len = 0;
    3.13  	ctx->data = NULL;
    3.14  
    3.15 -	// Status register clear, not busy
    3.16 +	// Status register clear, not busy; type1 command
    3.17  	ctx->status = 0;
    3.18 +	ctx->cmd_has_drq = false;
    3.19  
    3.20  	// Clear data register
    3.21  	ctx->data_reg = 0;
    3.22  
    3.23 -	// Last step direction
    3.24 +	// Last step direction = "towards zero"
    3.25  	ctx->last_step_dir = -1;
    3.26  
    3.27  	// No disc image loaded
    3.28 @@ -59,7 +60,7 @@
    3.29  	ctx->track = ctx->head = ctx->sector = 0;
    3.30  
    3.31  	// no IRQ pending
    3.32 -	ctx->irql = ctx->irqe = false;
    3.33 +	ctx->irq = false;
    3.34  
    3.35  	// no data available
    3.36  	ctx->data_pos = ctx->data_len = 0;
    3.37 @@ -90,13 +91,7 @@
    3.38  
    3.39  bool wd2797_get_irq(WD2797_CTX *ctx)
    3.40  {
    3.41 -	// If an IRQ is pending, clear it and return true, otherwise return false
    3.42 -	if (ctx->irqe) {
    3.43 -		ctx->irqe = false;
    3.44 -		return true;
    3.45 -	} else {
    3.46 -		return false;
    3.47 -	}
    3.48 +	return ctx->irq;
    3.49  }
    3.50  
    3.51  
    3.52 @@ -164,8 +159,7 @@
    3.53  	switch (addr & 0x03) {
    3.54  		case WD2797_REG_STATUS:		// Status register
    3.55  			// Read from status register clears IRQ
    3.56 -			ctx->irql = false;
    3.57 -			ctx->irqe = false;
    3.58 +			ctx->irq = false;
    3.59  
    3.60  			// Get current status flags (set by last command)
    3.61  			// DRQ bit
    3.62 @@ -192,9 +186,8 @@
    3.63  			if (ctx->data_pos < ctx->data_len) {
    3.64  				// set IRQ if this is the last data byte
    3.65  				if (ctx->data_pos == (ctx->data_len-1)) {
    3.66 -					// Set IRQ only if IRQL has been cleared (no pending IRQs)
    3.67 -					ctx->irqe = ctx->irql ? ctx->irqe : true;
    3.68 -					ctx->irql = true;
    3.69 +					// Set IRQ
    3.70 +					ctx->irq = true;
    3.71  				}
    3.72  				// return data byte and increment pointer
    3.73  				return ctx->data[ctx->data_pos++];
    3.74 @@ -223,7 +216,7 @@
    3.75  	switch (addr) {
    3.76  		case WD2797_REG_COMMAND:	// Command register
    3.77  			// write to command register clears interrupt request
    3.78 -			ctx->irql = false;
    3.79 +			ctx->irq = false;
    3.80  
    3.81  			// Is the drive ready?
    3.82  			if (ctx->disc_image == NULL) {
    3.83 @@ -314,9 +307,8 @@
    3.84  				// S0 = Busy. We just exec'd the command, thus we're not busy.
    3.85  				// 		TODO: Set a timer for seeks, and ONLY clear BUSY when that timer expires. Need periodics for that.
    3.86  				
    3.87 -				// Set IRQ only if IRQL has been cleared (no pending IRQs)
    3.88 -				ctx->irqe = ctx->irql ? ctx->irqe : true;
    3.89 -				ctx->irql = true;
    3.90 +				// Set IRQ
    3.91 +				ctx->irq = true;
    3.92  				return;
    3.93  			}
    3.94  
    3.95 @@ -339,9 +331,8 @@
    3.96  					// Set Write Protect bit and bail.
    3.97  					ctx->status = 0x40;
    3.98  
    3.99 -					// Set IRQ only if IRQL has been cleared (no pending IRQs)
   3.100 -					ctx->irqe = ctx->irql ? ctx->irqe : true;
   3.101 -					ctx->irql = true;
   3.102 +					// Set IRQ
   3.103 +					ctx->irq = true;
   3.104  
   3.105  					return;
   3.106  				}
   3.107 @@ -463,9 +454,8 @@
   3.108  					// TODO!
   3.109  					ctx->status = 0;
   3.110  					ctx->data_pos = ctx->data_len = 0;
   3.111 -					// Set IRQ only if IRQL has been cleared (no pending IRQs)
   3.112 -					ctx->irqe = ctx->irql ? ctx->irqe : true;
   3.113 -					ctx->irql = true;
   3.114 +					// Set IRQ
   3.115 +					ctx->irq = true;
   3.116  					break;
   3.117  			}
   3.118  			break;
   3.119 @@ -487,9 +477,8 @@
   3.120  			if (ctx->data_pos < ctx->data_len) {
   3.121  				// set IRQ if this is the last data byte
   3.122  				if (ctx->data_pos == (ctx->data_len-1)) {
   3.123 -					// Set IRQ only if IRQL has been cleared (no pending IRQs)
   3.124 -					ctx->irqe = ctx->irql ? ctx->irqe : true;
   3.125 -					ctx->irql = true;
   3.126 +					// Set IRQ
   3.127 +					ctx->irq = true;
   3.128  				}
   3.129  
   3.130  				// store data byte and increment pointer
     4.1 diff -r 976dfa068839 -r 2ef98ea1e944 src/wd279x.h
     4.2 --- a/src/wd279x.h	Mon Dec 06 08:27:05 2010 +0000
     4.3 +++ b/src/wd279x.h	Mon Dec 06 08:27:21 2010 +0000
     4.4 @@ -27,11 +27,8 @@
     4.5  	int						track, head, sector;
     4.6  	// Geometry of current disc
     4.7  	int						geom_secsz, geom_spt, geom_heads, geom_tracks;
     4.8 -	// IRQ status, level and edge sensitive.
     4.9 -	// Edge sensitive is cleared when host polls the IRQ status.
    4.10 -	// Level sensitive is cleared when emulated CPU polls the status reg or writes a new cmnd.
    4.11 -	// No EDGE sensitive interrupts will be issued unless the LEVEL SENSITIVE IRQ is clear.
    4.12 -	bool					irql, irqe;
    4.13 +	// IRQ status
    4.14 +	bool					irq;
    4.15  	// Status of last command
    4.16  	uint8_t					status;
    4.17  	// Last command uses DRQ bit?