1.1 diff -r 4c85846b09cd -r a392eb8f9806 src/main.c 1.2 --- a/src/main.c Sat Nov 17 19:13:08 2012 +0000 1.3 +++ b/src/main.c Sat Nov 17 19:18:29 2012 +0000 1.4 @@ -39,6 +39,23 @@ 1.5 } 1.6 } 1.7 1.8 +static int load_hd() 1.9 +{ 1.10 + 1.11 + state.hdc_disc0 = fopen("hd.img", "r+b"); 1.12 + if (!state.hdc_disc0){ 1.13 + fprintf(stderr, "ERROR loading disc image 'hd.img'.\n"); 1.14 + state.hdc_disc0 = NULL; 1.15 + return (0); 1.16 + }else{ 1.17 + wd2010_init(&state.hdc_ctx, state.hdc_disc0, 512, 16, 8); 1.18 + fprintf(stderr, "Disc image loaded.\n"); 1.19 + return (1); 1.20 + } 1.21 +} 1.22 + 1.23 + 1.24 + 1.25 /** 1.26 * @brief Set the pixel at (x, y) to the given value 1.27 * @note The surface must be locked before calling this! 1.28 @@ -229,6 +246,8 @@ 1.29 // Load a disc image 1.30 load_fd(); 1.31 1.32 + load_hd(); 1.33 + 1.34 /*** 1.35 * The 3B1 CPU runs at 10MHz, with DMA running at 1MHz and video refreshing at 1.36 * around 60Hz (???), with a 60Hz periodic interrupt. 1.37 @@ -240,7 +259,8 @@ 1.38 uint32_t next_timeslot = SDL_GetTicks() + MILLISECS_PER_TIMESLOT; 1.39 uint32_t clock_cycles = 0, tmp; 1.40 bool exitEmu = false; 1.41 - bool lastirq_fdc = false; 1.42 + 1.43 + /*bool lastirq_fdc = false;*/ 1.44 for (;;) { 1.45 // Run the CPU for however many cycles we need to. CPU core clock is 1.46 // 10MHz, and we're running at 240Hz/timeslot. Thus: 10e6/240 or 1.47 @@ -254,77 +274,48 @@ 1.48 size_t num = 0; 1.49 while (state.dma_count < 0x4000) { 1.50 uint16_t d = 0; 1.51 - 1.52 // num tells us how many words we've copied. If this is greater than the per-timeslot DMA maximum, bail out! 1.53 if (num > (1e6/TIMESLOT_FREQUENCY)) break; 1.54 1.55 // Evidently we have more words to copy. Copy them. 1.56 - if (!wd2797_get_drq(&state.fdc_ctx)) { 1.57 - // Bail out, no data available. Try again later. 1.58 - // TODO: handle HDD controller too 1.59 + if (state.fd_selected){ 1.60 + if (!wd2797_get_drq(&state.fdc_ctx)) { 1.61 + // Bail out, no data available. Try again later. 1.62 + break; 1.63 + } 1.64 + }else if (state.hd_selected){ 1.65 + if (!wd2010_get_drq(&state.hdc_ctx)) { 1.66 + // Bail out, no data available. Try again later. 1.67 + break; 1.68 + } 1.69 + }else{ 1.70 + printf("ERROR: DMA attempt with no drive selected!\n"); 1.71 + } 1.72 + if (!access_check_dma(state.dma_reading)) { 1.73 break; 1.74 } 1.75 - 1.76 - // Check memory access permissions 1.77 - // TODO: enforce these!!!! use ACCESS_CHECK_* for guidance. 1.78 - bool access_ok; 1.79 - switch (checkMemoryAccess(state.dma_address, !state.dma_reading)) { 1.80 - case MEM_PAGEFAULT: 1.81 - // Page fault 1.82 - state.genstat = 0x8BFF 1.83 - | (state.dma_reading ? 0x4000 : 0) 1.84 - | (state.pie ? 0x0400 : 0); 1.85 - access_ok = false; 1.86 - break; 1.87 - 1.88 - case MEM_UIE: 1.89 - // User access to memory above 4MB 1.90 - // FIXME? Shouldn't be possible with DMA... assert this? 1.91 - state.genstat = 0x9AFF 1.92 - | (state.dma_reading ? 0x4000 : 0) 1.93 - | (state.pie ? 0x0400 : 0); 1.94 - access_ok = false; 1.95 - break; 1.96 - 1.97 - case MEM_KERNEL: 1.98 - case MEM_PAGE_NO_WE: 1.99 - // Kernel access or page not write enabled 1.100 - access_ok = false; 1.101 - break; 1.102 - 1.103 - case MEM_ALLOWED: 1.104 - access_ok = true; 1.105 - break; 1.106 - } 1.107 - if (!access_ok) { 1.108 - state.bsr0 = 0x3C00; 1.109 - state.bsr0 |= (state.dma_address >> 16); 1.110 - state.bsr1 = state.dma_address & 0xffff; 1.111 - if (state.ee) m68k_pulse_bus_error(); 1.112 - printf("BUS ERROR FROM DMA: genstat=%04X, bsr0=%04X, bsr1=%04X\n", state.genstat, state.bsr0, state.bsr1); 1.113 - 1.114 - // TODO: FIXME: if we get a pagefault, it NEEDS to be tagged as 'peripheral sourced'... this is a HACK! 1.115 - printf("REALLY BIG FSCKING HUGE ERROR: DMA Memory Access caused a FAULT!\n"); 1.116 - exit(-1); 1.117 - } 1.118 - 1.119 + uint32_t newAddr; 1.120 // Map logical address to a physical RAM address 1.121 - uint32_t newAddr = mapAddr(state.dma_address, !state.dma_reading); 1.122 + newAddr = mapAddr(state.dma_address, !state.dma_reading); 1.123 1.124 if (!state.dma_reading) { 1.125 - // Data available. Get it from the FDC. TODO: handle HDD too 1.126 - d = wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.127 - d <<= 8; 1.128 - d += wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.129 - 1.130 + // Data available. Get it from the FDC or HDC. 1.131 + if (state.fd_selected) { 1.132 + d = wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.133 + d <<= 8; 1.134 + d += wd2797_read_reg(&state.fdc_ctx, WD2797_REG_DATA); 1.135 + }else if (state.hd_selected) { 1.136 + d = wd2010_read_data(&state.hdc_ctx); 1.137 + d <<= 8; 1.138 + d += wd2010_read_data(&state.hdc_ctx); 1.139 + } 1.140 if (newAddr <= 0x1FFFFF) { 1.141 WR16(state.base_ram, newAddr, state.base_ram_size - 1, d); 1.142 } else if (newAddr >= 0x200000) { 1.143 WR16(state.exp_ram, newAddr - 0x200000, state.exp_ram_size - 1, d); 1.144 } 1.145 - m68k_write_memory_16(state.dma_address, d); 1.146 } else { 1.147 - // Data write to FDC. TODO: handle HDD too. 1.148 + // Data write to FDC or HDC. 1.149 1.150 // Get the data from RAM 1.151 if (newAddr <= 0x1fffff) { 1.152 @@ -336,9 +327,14 @@ 1.153 d = 0xffff; 1.154 } 1.155 1.156 - // Send the data to the FDD 1.157 - wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d >> 8)); 1.158 - wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d & 0xff)); 1.159 + // Send the data to the FDD or HDD 1.160 + if (state.fd_selected){ 1.161 + wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d >> 8)); 1.162 + wd2797_write_reg(&state.fdc_ctx, WD2797_REG_DATA, (d & 0xff)); 1.163 + }else if (state.hd_selected){ 1.164 + wd2010_write_data(&state.hdc_ctx, (d >> 8)); 1.165 + wd2010_write_data(&state.hdc_ctx, (d & 0xff)); 1.166 + } 1.167 } 1.168 1.169 // Increment DMA address 1.170 @@ -350,9 +346,11 @@ 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 = 0; 1.175 - state.dmaen = false; 1.176 + state.dma_count = 0x3fff; 1.177 + /*state.dmaen = false;*/ 1.178 } 1.179 + }else if (wd2010_get_drq(&state.hdc_ctx)){ 1.180 + wd2010_dma_miss(&state.hdc_ctx); 1.181 }else if (wd2797_get_drq(&state.fdc_ctx)){ 1.182 wd2797_dma_miss(&state.fdc_ctx); 1.183 } 1.184 @@ -364,8 +362,9 @@ 1.185 lastirq_fdc = true; 1.186 m68k_set_irq(2); 1.187 } 1.188 + } 1.189 */ 1.190 - if (wd2797_get_irq(&state.fdc_ctx)){ 1.191 + if (wd2797_get_irq(&state.fdc_ctx) || wd2010_get_irq(&state.hdc_ctx)) { 1.192 m68k_set_irq(2); 1.193 }else if (keyboard_get_irq(&state.kbd)) { 1.194 m68k_set_irq(3);