~fitzsim/Main_MiSTer

780bb6c0cc954783e0f6b0217ff4b14ccdd76de7 — Aitor Gómez 2 years ago d92cfb7
FDD support, based on AO486
2 files changed, 131 insertions(+), 43 deletions(-)

M support/pcxt/pcxt.cpp
M support/pcxt/pcxt.h
M support/pcxt/pcxt.cpp => support/pcxt/pcxt.cpp +130 -43
@@ 18,6 18,7 @@
#include "../../support.h"
#include "../../lib/serial_server/library/Library.h"
#include "../../lib/serial_server/library/FlatImage.h"
#include "../../ide.h"
#include "pcxt.h"

int verbose = 0;


@@ 30,16 31,45 @@ pthread_t uart_thread;
SerialAccess serial;
bool in_process;

#define FDD0_BASE   0xF200
#define FDD1_BASE   0xF300
#define CFG_VER     1

#define FDD_TYPE_NONE 0
#define FDD_TYPE_160  1
#define FDD_TYPE_180  2
#define FDD_TYPE_320  3
#define FDD_TYPE_360  4
#define FDD_TYPE_720  5
#define FDD_TYPE_1200 6
#define FDD_TYPE_1440 7
#define FDD_TYPE_1680 8
#define FDD_TYPE_2880 9

static char floppy_type[2] = { FDD_TYPE_NONE, FDD_TYPE_NONE };

static fileTYPE fdd0_image = {};
static fileTYPE fdd1_image = {};

#define IOWR(base, reg, value) x86_dma_set((base) + (reg), value)

typedef struct
{
	uint32_t ver;
	char img_name[2][1024];
	char img_name[3][1024];
} pcxt_config;

static pcxt_config config;

static void x86_dma_set(uint32_t address, uint32_t data)
{
	EnableIO();
	spi8(UIO_DMA_WRITE);
	spi32_w(address);
	spi_w((uint16_t)data);
	DisableIO();
}

void pcxt_init()
{	
	user_io_status_set("[0]", 1);


@@ 77,36 107,6 @@ void* OpenUART(void*) {
	int timeoutEnabled = 1;
	FILE* fd;
	long size;
	
	// FDD CHS Calculator

	unsigned long fdd_cyl = 0, fdd_sect = 0, fdd_head = 0;
	bool is_fdd = false;
	struct floppyInfo* fdd_fi;
	
	if (strlen(config.img_name[1]))
	{
		fd = fopen(config.img_name[1], "r");
		if (fd)
		{
			is_fdd = true;
			fseek(fd, 0L, SEEK_END);
			size = ftell(fd);

			if ((fdd_fi = FindFloppyInfoBySize(size)))
			{
				fdd_sect = fdd_fi->sectors;
				fdd_head = fdd_fi->heads;
				fdd_cyl = fdd_fi->cylinders;
			}
			else
			{
				fdd_sect = 63;
				fdd_head = 16;
				fdd_cyl = size / (16 * 63);
			}
		}
	}

	// HDD CHS Calculator



@@ 114,9 114,9 @@ void* OpenUART(void*) {
	bool is_hdd = false;
	struct hddInfo *hdd_fi;

	if (strlen(config.img_name[0]))
	if (strlen(config.img_name[2]))
	{
		fd = fopen(config.img_name[0], "r");
		fd = fopen(config.img_name[2], "r");
		if (fd)
		{
			is_hdd = true;


@@ 143,16 143,7 @@ void* OpenUART(void*) {

	if (is_hdd)
	{
		images[0] = new FlatImage(config.img_name[0], status & 2, 0, createFile, hdd_cyl, hdd_head, hdd_sect, useCHS);
		
		if (is_fdd)
		{
			images[1] = new FlatImage(config.img_name[1], status & 1, 1, createFile, fdd_cyl, fdd_head, fdd_sect, useCHS);
		}
	}
	else if (is_fdd)
	{
		images[0] = new FlatImage(config.img_name[1], status & 1, 0, createFile, fdd_cyl, fdd_head, fdd_sect, useCHS);
		images[0] = new FlatImage(config.img_name[2], 0, 0, createFile, hdd_cyl, hdd_head, hdd_sect, useCHS);		
	}

	// Mount Images


@@ 236,7 227,103 @@ void pcxt_load_images()
	in_process = true;
}

static void fdd_set(int num, char* filename)
{
	floppy_type[num] = FDD_TYPE_1440;

	fileTYPE* fdd_image = num ? &fdd1_image : &fdd0_image;

	int floppy = ide_img_mount(fdd_image, filename, 1);
	uint32_t size = fdd_image->size / 512;
	printf("floppy size: %d blks\n", size);
	if (floppy && size)
	{
		if (size >= 8000)
		{
			floppy = 0;
			FileClose(fdd_image);
			printf("Image size is too large for floppy. Closing...\n");
		}
		else if (size >= 5760) floppy_type[num] = FDD_TYPE_2880;
		else if (size >= 3360) floppy_type[num] = FDD_TYPE_1680;
		else if (size >= 2880) floppy_type[num] = FDD_TYPE_1440;
		else if (size >= 2400) floppy_type[num] = FDD_TYPE_1200;
		else if (size >= 1440) floppy_type[num] = FDD_TYPE_720;
		else if (size >= 720) floppy_type[num] = FDD_TYPE_360;
		else if (size >= 640) floppy_type[num] = FDD_TYPE_320;
		else if (size >= 360) floppy_type[num] = FDD_TYPE_180;
		else floppy_type[num] = FDD_TYPE_160;
	}
	else
	{
		floppy = 0;
	}

	/*
	0x00.[0]:      media present
	0x01.[0]:      media writeprotect
	0x02.[7:0]:    media cylinders
	0x03.[7:0]:    media sectors per track
	0x04.[31:0]:   media total sector count
	0x05.[1:0]:    media heads
	0x06.[31:0]:   media sd base
	0x07.[15:0]:   media wait cycles: 200000 us / spt
	0x08.[15:0]:   media wait rate 0: 1000 us
	0x09.[15:0]:   media wait rate 1: 1666 us
	0x0A.[15:0]:   media wait rate 2: 2000 us
	0x0B.[15:0]:   media wait rate 3: 500 us
	0x0C.[7:0]:    media type: 8'h20 none; 8'h00 old; 8'hC0 720k; 8'h80 1_44M; 8'h40 2_88M
	*/

	int floppy_spt = 0;
	int floppy_cylinders = 0;
	int floppy_heads = 0;

	switch (floppy_type[num])
	{
	case FDD_TYPE_160:  floppy_spt = 8;  floppy_cylinders = 40; floppy_heads = 1; break;
	case FDD_TYPE_180:  floppy_spt = 9;  floppy_cylinders = 40; floppy_heads = 1; break;
	case FDD_TYPE_320:  floppy_spt = 8;  floppy_cylinders = 40; floppy_heads = 2; break;
	case FDD_TYPE_360:  floppy_spt = 9;  floppy_cylinders = 40; floppy_heads = 2; break;
	case FDD_TYPE_720:  floppy_spt = 9;  floppy_cylinders = 80; floppy_heads = 2; break;
	case FDD_TYPE_1200: floppy_spt = 15; floppy_cylinders = 80; floppy_heads = 2; break;
	case FDD_TYPE_1440: floppy_spt = 18; floppy_cylinders = 80; floppy_heads = 2; break;
	case FDD_TYPE_1680: floppy_spt = 21; floppy_cylinders = 80; floppy_heads = 2; break;
	case FDD_TYPE_2880: floppy_spt = 36; floppy_cylinders = 80; floppy_heads = 2; break;
	}

	int floppy_total_sectors = floppy_spt * floppy_heads * floppy_cylinders;

	printf("floppy:\n");
	printf("  cylinders:     %d\n", floppy_cylinders);
	printf("  heads:         %d\n", floppy_heads);
	printf("  spt:           %d\n", floppy_spt);
	printf("  total_sectors: %d\n\n", floppy_total_sectors);

	uint32_t subaddr = num << 7;

	IOWR(FDD0_BASE + subaddr, 0x0, 0); // Always eject floppy before insertion
	usleep(100000);

	IOWR(FDD0_BASE + subaddr, 0x0, floppy ? 1 : 0);
	IOWR(FDD0_BASE + subaddr, 0x1, (floppy && (fdd_image->mode & O_RDWR)) ? 0 : 1);
	IOWR(FDD0_BASE + subaddr, 0x2, floppy_cylinders);
	IOWR(FDD0_BASE + subaddr, 0x3, floppy_spt);
	IOWR(FDD0_BASE + subaddr, 0x4, floppy_total_sectors);
	IOWR(FDD0_BASE + subaddr, 0x5, floppy_heads);
	IOWR(FDD0_BASE + subaddr, 0x6, 0); // base LBA
	IOWR(FDD0_BASE + subaddr, 0xC, 0);
}

void pcxt_set_image(int num, char* filename)
{
	memset(config.img_name[num], 0, sizeof(config.img_name[0]));
	strcpy(config.img_name[num], filename);
	if (num < 2) fdd_set(num, filename);
	else hdd_set(num, filename);
}

void hdd_set(int num, char* filename)
{	
	const char* imghome = "/media/fat";


M support/pcxt/pcxt.h => support/pcxt/pcxt.h +1 -0
@@ 12,6 12,7 @@ unsigned long GetTime_Timeout(void);
void pcxt_unmount_images();
void pcxt_load_images();
void pcxt_set_image(int num, char* selPath);
void hdd_set(int num, char* selPath);
void pcxt_config_load();
void pcxt_config_save();
const char* pcxt_get_image_name(int num);