Sun, 05 Dec 2010 16:20:00 +0000
add preliminary WD279x emulation to core
src/main.c | file | annotate | diff | revisions | |
src/memory.c | file | annotate | diff | revisions | |
src/state.c | file | annotate | diff | revisions | |
src/state.h | file | annotate | diff | revisions |
1.1 --- a/src/main.c Sun Dec 05 16:18:50 2010 +0000 1.2 +++ b/src/main.c Sun Dec 05 16:20:00 2010 +0000 1.3 @@ -188,6 +188,10 @@ 1.4 printf("Set %dx%d at %d bits-per-pixel mode\n\n", screen->w, screen->h, screen->format->BitsPerPixel); 1.5 SDL_WM_SetCaption("FreeBee 3B1 emulator", "FreeBee"); 1.6 1.7 + // Load a disc image 1.8 + FILE *disc = fopen("discim", "rb"); 1.9 + wd2797_load(&state.fdc_ctx, disc, 512, 10, 2); 1.10 + 1.11 /*** 1.12 * The 3B1 CPU runs at 10MHz, with DMA running at 1MHz and video refreshing at 1.13 * around 60Hz (???), with a 60Hz periodic interrupt. 1.14 @@ -237,5 +241,9 @@ 1.15 if (exitEmu) break; 1.16 } 1.17 1.18 + // Release the disc image 1.19 + wd2797_unload(&state.fdc_ctx); 1.20 + fclose(disc); 1.21 + 1.22 return 0; 1.23 }
2.1 --- a/src/memory.c Sun Dec 05 16:18:50 2010 +0000 2.2 +++ b/src/memory.c Sun Dec 05 16:20:00 2010 +0000 2.3 @@ -310,6 +310,9 @@ 2.4 case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 2.5 break; 2.6 case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 2.7 + data = wd2797_read_reg(&state.fdc_ctx, (address >> 1) & 3); 2.8 + printf("WD279X: rd %02X ==> %02X\n", (address >> 1) & 3, data); 2.9 + handled = true; 2.10 break; 2.11 case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 2.12 break; 2.13 @@ -472,6 +475,9 @@ 2.14 case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 2.15 break; 2.16 case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 2.17 + data = wd2797_read_reg(&state.fdc_ctx, (address >> 1) & 3); 2.18 + printf("WD279X: rd %02X ==> %02X\n", (address >> 1) & 3, data); 2.19 + handled = true; 2.20 break; 2.21 case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 2.22 break; 2.23 @@ -643,6 +649,9 @@ 2.24 case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 2.25 break; 2.26 case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 2.27 + data = wd2797_read_reg(&state.fdc_ctx, (address >> 1) & 3); 2.28 + printf("WD279X: rd %02X ==> %02X\n", (address >> 1) & 3, data); 2.29 + handled = true; 2.30 break; 2.31 case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 2.32 break; 2.33 @@ -762,6 +771,8 @@ 2.34 break; 2.35 case 0x0A0000: // Miscellaneous Control Register 2.36 // TODO: handle the ctrl bits properly 2.37 + // TODO: &0x8000 --> dismiss 60hz intr 2.38 + state.dma_reading = (value & 0x4000); 2.39 state.leds = (~value & 0xF00) >> 8; 2.40 printf("LEDs: %s %s %s %s\n", 2.41 (state.leds & 8) ? "R" : "-", 2.42 @@ -779,8 +790,22 @@ 2.43 handled = true; 2.44 break; 2.45 case 0x0D0000: // DMA Address Register 2.46 + if (address & 0x004000) { 2.47 + // A14 high -- set most significant bits 2.48 + state.dma_address = (state.dma_address & 0xff) | ((address & 0x3fff) << 7); 2.49 + } else { 2.50 + // A14 low -- set least significant bits 2.51 + state.dma_address = (state.dma_address & 0x3fff00) | (address & 0xff); 2.52 + } 2.53 break; 2.54 case 0x0E0000: // Disk Control Register 2.55 + // B7 = FDD controller reset 2.56 + if ((value & 0x80) == 0) wd2797_reset(&state.fdc_ctx); 2.57 + // B6 = drive 0 select -- TODO 2.58 + // B5 = motor enable -- TODO 2.59 + // B4 = HDD controller reset -- TODO 2.60 + // B3 = HDD0 select -- TODO 2.61 + // B2,1,0 = HDD0 head select 2.62 break; 2.63 case 0x0F0000: // Line Printer Data Register 2.64 break; 2.65 @@ -810,6 +835,9 @@ 2.66 case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 2.67 break; 2.68 case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 2.69 + wd2797_write_reg(&state.fdc_ctx, (address >> 1) & 3, value); 2.70 + printf("WD279X: wr %02X ==> %02X\n\t", (address >> 1) & 3, value); 2.71 + //handled = true; 2.72 break; 2.73 case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 2.74 break; 2.75 @@ -936,6 +964,8 @@ 2.76 break; 2.77 case 0x0A0000: // Miscellaneous Control Register 2.78 // TODO: handle the ctrl bits properly 2.79 + // TODO: &0x8000 --> dismiss 60hz intr 2.80 + state.dma_reading = (value & 0x4000); 2.81 state.leds = (~value & 0xF00) >> 8; 2.82 printf("LEDs: %s %s %s %s\n", 2.83 (state.leds & 8) ? "R" : "-", 2.84 @@ -953,8 +983,22 @@ 2.85 handled = true; 2.86 break; 2.87 case 0x0D0000: // DMA Address Register 2.88 + if (address & 0x004000) { 2.89 + // A14 high -- set most significant bits 2.90 + state.dma_address = (state.dma_address & 0xff) | ((address & 0x3fff) << 7); 2.91 + } else { 2.92 + // A14 low -- set least significant bits 2.93 + state.dma_address = (state.dma_address & 0x3fff00) | (address & 0xff); 2.94 + } 2.95 break; 2.96 case 0x0E0000: // Disk Control Register 2.97 + // B7 = FDD controller reset 2.98 + if ((value & 0x80) == 0) wd2797_reset(&state.fdc_ctx); 2.99 + // B6 = drive 0 select -- TODO 2.100 + // B5 = motor enable -- TODO 2.101 + // B4 = HDD controller reset -- TODO 2.102 + // B3 = HDD0 select -- TODO 2.103 + // B2,1,0 = HDD0 head select 2.104 break; 2.105 case 0x0F0000: // Line Printer Data Register 2.106 break; 2.107 @@ -983,6 +1027,9 @@ 2.108 case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 2.109 break; 2.110 case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 2.111 + wd2797_write_reg(&state.fdc_ctx, (address >> 1) & 3, value); 2.112 + printf("WD279X: wr %02X ==> %02X\n\t", (address >> 1) & 3, value); 2.113 + //handled = true; 2.114 break; 2.115 case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 2.116 break; 2.117 @@ -1109,10 +1156,14 @@ 2.118 break; 2.119 case 0x0A0000: // Miscellaneous Control Register 2.120 // TODO: handle the ctrl bits properly 2.121 - if ((address & 1) == 0) 2.122 - ;// CTL bits 2.123 - else 2.124 + if ((address & 1) == 0) { 2.125 + // low byte 2.126 + } else { 2.127 + // hight byte 2.128 + // TODO: &0x8000 --> dismiss 60hz intr 2.129 + state.dma_reading = (value & 0x40); 2.130 state.leds = (~value & 0xF); 2.131 + } 2.132 printf("LEDs: %s %s %s %s\n", 2.133 (state.leds & 8) ? "R" : "-", 2.134 (state.leds & 4) ? "G" : "-", 2.135 @@ -1129,8 +1180,22 @@ 2.136 handled = true; 2.137 break; 2.138 case 0x0D0000: // DMA Address Register 2.139 + if (address & 0x004000) { 2.140 + // A14 high -- set most significant bits 2.141 + state.dma_address = (state.dma_address & 0xff) | ((address & 0x3fff) << 7); 2.142 + } else { 2.143 + // A14 low -- set least significant bits 2.144 + state.dma_address = (state.dma_address & 0x3fff00) | (address & 0xff); 2.145 + } 2.146 break; 2.147 case 0x0E0000: // Disk Control Register 2.148 + // B7 = FDD controller reset 2.149 + if ((value & 0x80) == 0) wd2797_reset(&state.fdc_ctx); 2.150 + // B6 = drive 0 select -- TODO 2.151 + // B5 = motor enable -- TODO 2.152 + // B4 = HDD controller reset -- TODO 2.153 + // B3 = HDD0 select -- TODO 2.154 + // B2,1,0 = HDD0 head select 2.155 break; 2.156 case 0x0F0000: // Line Printer Data Register 2.157 break; 2.158 @@ -1159,6 +1224,9 @@ 2.159 case 0x000000: // [ef][08]xxxx ==> WD1010 hard disc controller 2.160 break; 2.161 case 0x010000: // [ef][19]xxxx ==> WD2797 floppy disc controller 2.162 + wd2797_write_reg(&state.fdc_ctx, (address >> 1) & 3, value); 2.163 + printf("WD279X: wr %02X ==> %02X\n\t", (address >> 1) & 3, value); 2.164 + //handled = true; 2.165 break; 2.166 case 0x020000: // [ef][2a]xxxx ==> Miscellaneous Control Register 2 2.167 break;
3.1 --- a/src/state.c Sun Dec 05 16:18:50 2010 +0000 3.2 +++ b/src/state.c Sun Dec 05 16:20:00 2010 +0000 3.3 @@ -2,6 +2,7 @@ 3.4 #include <stddef.h> 3.5 #include <malloc.h> 3.6 #include <stdio.h> 3.7 +#include "wd279x.h" 3.8 #include "state.h" 3.9 3.10 int state_init(size_t ramsize) 3.11 @@ -60,6 +61,9 @@ 3.12 fclose(r14c); 3.13 fclose(r15c); 3.14 3.15 + // Initialise the disc controller 3.16 + wd2797_init(&state.fdc_ctx); 3.17 + 3.18 return 0; 3.19 } 3.20 3.21 @@ -69,6 +73,9 @@ 3.22 free(state.ram); 3.23 state.ram = NULL; 3.24 } 3.25 + 3.26 + // Deinitialise the disc controller 3.27 + wd2797_done(&state.fdc_ctx); 3.28 } 3.29 3.30
4.1 --- a/src/state.h Sun Dec 05 16:18:50 2010 +0000 4.2 +++ b/src/state.h Sun Dec 05 16:20:00 2010 +0000 4.3 @@ -4,6 +4,7 @@ 4.4 #include <stddef.h> 4.5 #include <stdint.h> 4.6 #include <stdbool.h> 4.7 +#include "wd279x.h" 4.8 4.9 // Maximum size of the Boot PROMs. Must be a binary power of two. 4.10 #define ROM_SIZE 32768 4.11 @@ -17,30 +18,37 @@ 4.12 // Boot PROM can be up to 32Kbytes total size 4.13 uint8_t rom[ROM_SIZE]; ///< Boot PROM data buffer 4.14 4.15 - // Main system RAM 4.16 + //// Main system RAM 4.17 uint8_t *ram; ///< RAM data buffer 4.18 size_t ram_size; ///< Size of RAM buffer in bytes 4.19 4.20 - // Video RAM 4.21 - uint8_t vram[0x8000]; ///< Video RAM 4.22 + /// Video RAM 4.23 + uint8_t vram[0x8000]; 4.24 4.25 - // Map RAM 4.26 - uint8_t map[0x800]; ///< Map RAM 4.27 + /// Map RAM 4.28 + uint8_t map[0x800]; 4.29 4.30 - // Registers 4.31 + //// Registers 4.32 uint16_t genstat; ///< General Status Register 4.33 uint16_t bsr0; ///< Bus Status Register 0 4.34 uint16_t bsr1; ///< Bus Status Register 1 4.35 4.36 - // MISCELLANEOUS CONTROL REGISTER 4.37 + //// MISCELLANEOUS CONTROL REGISTER 4.38 + bool dma_reading; ///< True if Disc DMA reads from the controller, false otherwise 4.39 uint8_t leds; ///< LED status, 1=on, in order red3/green2/yellow1/red0 from bit3 to bit0 4.40 4.41 - // GENERAL CONTROL REGISTER 4.42 + //// GENERAL CONTROL REGISTER 4.43 /// GENCON.ROMLMAP -- false ORs the address with 0x800000, forcing the 4.44 /// 68010 to access ROM instead of RAM when booting. TRM page 2-36. 4.45 bool romlmap; 4.46 /// GENCON.PIE -- Parity Error Check Enable 4.47 bool pie; 4.48 + 4.49 + /// DMA Address Register 4.50 + uint32_t dma_address; 4.51 + 4.52 + /// Floppy disc controller context 4.53 + WD2797_CTX fdc_ctx; 4.54 } S_state; 4.55 4.56 // Global emulator state. Yes, I know global variables are evil, please don't