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