add preliminary WD279x emulation to core

Sun, 05 Dec 2010 16:20:00 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 05 Dec 2010 16:20:00 +0000
changeset 52
a350dfa92895
parent 51
e5a92d7beecf
child 53
e1693c4b8a0c

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