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