Mon, 06 Dec 2010 08:27:21 +0000
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?