1.1 diff -r b63a3999e2e7 -r d61e13d6e2a5 src/main.c 1.2 --- a/src/main.c Fri Apr 18 01:34:20 2014 -0600 1.3 +++ b/src/main.c Sat Apr 19 02:19:39 2014 -0600 1.4 @@ -253,127 +253,129 @@ 1.5 * around 60Hz (???), with a 60Hz periodic interrupt. 1.6 */ 1.7 const uint32_t SYSTEM_CLOCK = 10e6; // Hz 1.8 - const uint32_t TIMESLOT_FREQUENCY = 1000;//240; // Hz 1.9 + const uint32_t TIMESLOT_FREQUENCY = 100;//240; // Hz 1.10 const uint32_t MILLISECS_PER_TIMESLOT = 1e3 / TIMESLOT_FREQUENCY; 1.11 const uint32_t CLOCKS_PER_60HZ = (SYSTEM_CLOCK / 60); 1.12 + const uint32_t NUM_CPU_TIMESLOTS = 500; 1.13 uint32_t next_timeslot = SDL_GetTicks() + MILLISECS_PER_TIMESLOT; 1.14 uint32_t clock_cycles = 0, tmp; 1.15 bool exitEmu = false; 1.16 1.17 /*bool lastirq_fdc = false;*/ 1.18 for (;;) { 1.19 - // Run the CPU for however many cycles we need to. CPU core clock is 1.20 - // 10MHz, and we're running at 240Hz/timeslot. Thus: 10e6/240 or 1.21 - // 41667 cycles per timeslot. 1.22 - tmp = m68k_execute(SYSTEM_CLOCK/TIMESLOT_FREQUENCY); 1.23 - clock_cycles += tmp; 1.24 + for (i = 0; i < NUM_CPU_TIMESLOTS; i++){ 1.25 + // Run the CPU for however many cycles we need to. CPU core clock is 1.26 + // 10MHz, and we're running at 240Hz/timeslot. Thus: 10e6/240 or 1.27 + // 41667 cycles per timeslot. 1.28 + tmp = m68k_execute(SYSTEM_CLOCK/TIMESLOT_FREQUENCY / NUM_CPU_TIMESLOTS); 1.29 + clock_cycles += tmp; 1.30 1.31 - // Run the DMA engine 1.32 - if (state.dmaen) { 1.33 - // DMA ready to go -- so do it. 1.34 - size_t num = 0; 1.35 - while (state.dma_count < 0x4000) { 1.36 - uint16_t d = 0; 1.37 - // num tells us how many words we've copied. If this is greater than the per-timeslot DMA maximum, bail out! 1.38 - if (num > (1e6/TIMESLOT_FREQUENCY)) break; 1.39 - 1.40 - // Evidently we have more words to copy. Copy them. 1.41 - if (state.fd_selected){ 1.42 - if (!wd2797_get_drq(&state.fdc_ctx)) { 1.43 - // Bail out, no data available. Try again later. 1.44 - break; 1.45 + // Run the DMA engine 1.46 + if (state.dmaen) { 1.47 + // DMA ready to go -- so do it. 1.48 + size_t num = 0; 1.49 + while (state.dma_count < 0x4000) { 1.50 + uint16_t d = 0; 1.51 + // num tells us how many words we've copied. If this is greater than the per-timeslot DMA maximum, bail out! 1.52 + if (num > (1e6/TIMESLOT_FREQUENCY)) break; 1.53 + 1.54 + // Evidently we have more words to copy. Copy them. 1.55 + if (state.fd_selected){ 1.56 + if (!wd2797_get_drq(&state.fdc_ctx)) { 1.57 + // Bail out, no data available. Try again later. 1.58 + break; 1.59 + } 1.60 + }else if (state.hd_selected){ 1.61 + if (!wd2010_get_drq(&state.hdc_ctx)) { 1.62 + // Bail out, no data available. Try again later. 1.63 + break; 1.64 + } 1.65 + }else{ 1.66 + printf("ERROR: DMA attempt with no drive selected!\n"); 1.67 } 1.68 - }else if (state.hd_selected){ 1.69 - if (!wd2010_get_drq(&state.hdc_ctx)) { 1.70 - // Bail out, no data available. Try again later. 1.71 + if (!access_check_dma(state.dma_reading)) { 1.72 break; 1.73 } 1.74 - }else{ 1.75 - printf("ERROR: DMA attempt with no drive selected!\n"); 1.76 - } 1.77 - if (!access_check_dma(state.dma_reading)) { 1.78 - break; 1.79 - } 1.80 - uint32_t newAddr; 1.81 - // Map logical address to a physical RAM address 1.82 - newAddr = mapAddr(state.dma_address, !state.dma_reading); 1.83 + uint32_t newAddr; 1.84 + // Map logical address to a physical RAM address 1.85 + newAddr = mapAddr(state.dma_address, !state.dma_reading); 1.86 + 1.87 + if (!state.dma_reading) { 1.88 + // Data available. Get it from the FDC or HDC. 1.89 + if (state.fd_selected) { 1.90 + d = wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.91 + d <<= 8; 1.92 + d += wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.93 + }else if (state.hd_selected) { 1.94 + d = wd2010_read_data(&state.hdc_ctx); 1.95 + d <<= 8; 1.96 + d += wd2010_read_data(&state.hdc_ctx); 1.97 + } 1.98 + if (newAddr <= 0x1FFFFF) { 1.99 + WR16(state.base_ram, newAddr, state.base_ram_size - 1, d); 1.100 + } else if (newAddr >= 0x200000) { 1.101 + WR16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, d); 1.102 + } 1.103 + } else { 1.104 + // Data write to FDC or HDC. 1.105 1.106 - if (!state.dma_reading) { 1.107 - // Data available. Get it from the FDC or HDC. 1.108 - if (state.fd_selected) { 1.109 - d = wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.110 - d <<= 8; 1.111 - d += wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.112 - }else if (state.hd_selected) { 1.113 - d = wd2010_read_data(&state.hdc_ctx); 1.114 - d <<= 8; 1.115 - d += wd2010_read_data(&state.hdc_ctx); 1.116 - } 1.117 - if (newAddr <= 0x1FFFFF) { 1.118 - WR16(state.base_ram, newAddr, state.base_ram_size - 1, d); 1.119 - } else if (newAddr >= 0x200000) { 1.120 - WR16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, d); 1.121 - } 1.122 - } else { 1.123 - // Data write to FDC or HDC. 1.124 - 1.125 - // Get the data from RAM 1.126 - if (newAddr <= 0x1fffff) { 1.127 - d = RD16(state.base_ram, newAddr, state.base_ram_size - 1); 1.128 - } else { 1.129 - if (newAddr <= (state.exp_ram_size + 0x200000 - 1)) 1.130 - d = RD16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1); 1.131 - else 1.132 - d = 0xffff; 1.133 + // Get the data from RAM 1.134 + if (newAddr <= 0x1fffff) { 1.135 + d = RD16(state.base_ram, newAddr, state.base_ram_size - 1); 1.136 + } else { 1.137 + if (newAddr <= (state.exp_ram_size + 0x200000 - 1)) 1.138 + d = RD16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1); 1.139 + else 1.140 + d = 0xffff; 1.141 + } 1.142 + 1.143 + // Send the data to the FDD or HDD 1.144 + if (state.fd_selected){ 1.145 + wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d >> 8)); 1.146 + wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d & 0xff)); 1.147 + }else if (state.hd_selected){ 1.148 + wd2010_write_data(&state.hdc_ctx, (d >> 8)); 1.149 + wd2010_write_data(&state.hdc_ctx, (d & 0xff)); 1.150 + } 1.151 } 1.152 1.153 - // Send the data to the FDD or HDD 1.154 - if (state.fd_selected){ 1.155 - wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d >> 8)); 1.156 - wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d & 0xff)); 1.157 - }else if (state.hd_selected){ 1.158 - wd2010_write_data(&state.hdc_ctx, (d >> 8)); 1.159 - wd2010_write_data(&state.hdc_ctx, (d & 0xff)); 1.160 - } 1.161 + // Increment DMA address 1.162 + state.dma_address+=2; 1.163 + // Increment number of words transferred 1.164 + num++; state.dma_count++; 1.165 } 1.166 1.167 - // Increment DMA address 1.168 - state.dma_address+=2; 1.169 - // Increment number of words transferred 1.170 - num++; state.dma_count++; 1.171 + // Turn off DMA engine if we finished this cycle 1.172 + if (state.dma_count >= 0x4000) { 1.173 + // FIXME? apparently this isn't required... or is it? 1.174 + state.dma_count = 0x3fff; 1.175 + /*state.dmaen = false;*/ 1.176 + } 1.177 + }else if (wd2010_get_drq(&state.hdc_ctx)){ 1.178 + wd2010_dma_miss(&state.hdc_ctx); 1.179 + }else if (wd2797_get_drq(&state.fdc_ctx)){ 1.180 + wd2797_dma_miss(&state.fdc_ctx); 1.181 } 1.182 1.183 - // Turn off DMA engine if we finished this cycle 1.184 - if (state.dma_count >= 0x4000) { 1.185 - // FIXME? apparently this isn't required... or is it? 1.186 - state.dma_count = 0x3fff; 1.187 - /*state.dmaen = false;*/ 1.188 + 1.189 + // Any interrupts? --> TODO: masking 1.190 +/* if (!lastirq_fdc) { 1.191 + if (wd2797_get_irq(&state.fdc_ctx)) { 1.192 + lastirq_fdc = true; 1.193 + m68k_set_irq(2); 1.194 + } 1.195 } 1.196 - }else if (wd2010_get_drq(&state.hdc_ctx)){ 1.197 - wd2010_dma_miss(&state.hdc_ctx); 1.198 - }else if (wd2797_get_drq(&state.fdc_ctx)){ 1.199 - wd2797_dma_miss(&state.fdc_ctx); 1.200 - } 1.201 - 1.202 - 1.203 - // Any interrupts? --> TODO: masking 1.204 -/* if (!lastirq_fdc) { 1.205 - if (wd2797_get_irq(&state.fdc_ctx)) { 1.206 - lastirq_fdc = true; 1.207 +*/ 1.208 + if (wd2797_get_irq(&state.fdc_ctx) || wd2010_get_irq(&state.hdc_ctx)) { 1.209 m68k_set_irq(2); 1.210 + }else if (keyboard_get_irq(&state.kbd)) { 1.211 + m68k_set_irq(3); 1.212 + } else { 1.213 +// if (!state.timer_asserted){ 1.214 + m68k_set_irq(0); 1.215 +// } 1.216 } 1.217 } 1.218 -*/ 1.219 - if (wd2797_get_irq(&state.fdc_ctx) || wd2010_get_irq(&state.hdc_ctx)) { 1.220 - m68k_set_irq(2); 1.221 - }else if (keyboard_get_irq(&state.kbd)) { 1.222 - m68k_set_irq(3); 1.223 - } else { 1.224 -// if (!state.timer_asserted){ 1.225 - m68k_set_irq(0); 1.226 -// } 1.227 - } 1.228 - 1.229 // Is it time to run the 60Hz periodic interrupt yet? 1.230 if (clock_cycles > CLOCKS_PER_60HZ) { 1.231 // Refresh the screen