/*
 *  disk.cpp - Generic disk driver
 *
 *  Basilisk II (C) 1997-2008 Christian Bauer
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 *  SEE ALSO
 *    Inside Macintosh: Devices, chapter 1 "Device Manager"
 *    Technote DV 05: "Drive Queue Elements"
 *    Technote DV 23: "Driver Education"
 *    Technote FL 24: "Don't Look at ioPosOffset for Devices"
 */

#include "sysdeps.h"

#include <string.h>
#include <vector>

#ifndef NO_STD_NAMESPACE
using std::vector;
#endif

#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "sys.h"
#include "prefs.h"
#include "disk.h"

#define DEBUG 0
#include "debug.h"


// .Disk Disk/drive icon
const uint8 DiskIcon[258] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe,
	0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01,
	0x80, 0x00, 0x00, 0x01, 0x8c, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x01,
	0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

	0, 0
};


// Struct for each drive
struct disk_drive_info {
	disk_drive_info() : num(0), fh(NULL), start_byte(0), read_only(false), status(0) {}
	disk_drive_info(void *fh_, bool ro) : num(0), fh(fh_), read_only(ro), status(0) {}

	void close_fh(void) { Sys_close(fh); }

	int num;			// Drive number
	void *fh;			// File handle
	loff_t start_byte;	// Start of HFS partition on disk
	uint32 num_blocks;	// Size in 512-byte blocks
	bool to_be_mounted;	// Flag: drive must be mounted in accRun
	bool read_only;		// Flag: force write protection
	uint32 status;		// Mac address of drive status record
};

// List of drives handled by this driver
typedef vector<disk_drive_info> drive_vec;
static drive_vec drives;

// Icon address (Mac address space, set by PatchROM())
uint32 DiskIconAddr;

// Flag: Control(accRun) has been called, interrupt routine is now active
static bool acc_run_called = false;


/*
 *  Get pointer to drive info or drives.end() if not found
 */

static drive_vec::iterator get_drive_info(int num)
{
	drive_vec::iterator info, end = drives.end();
	for (info = drives.begin(); info != end; ++info) {
		if (info->num == num)
			return info;
	}
	return info;
}


/*
 *  Find HFS partition, set info->start_byte and info->num_blocks
 *  (0 = no partition map or HFS partition found, assume flat disk image)
 */

static void find_hfs_partition(disk_drive_info &info)
{
	info.start_byte = 0;
	info.num_blocks = 0;
	uint8 *map = new uint8[512];

	// Search first 64 blocks for HFS partition
	for (int i=0; i<64; i++) {
		if (Sys_read(info.fh, map, i * 512, 512) != 512)
			break;

		// Not a partition map block? Then look at next block
		uint16 sig = (map[0] << 8) | map[1];
		if (sig != 0x504d)
			continue;

		// Partition map block found, Apple HFS partition?
		if (strcmp((char *)(map + 48), "Apple_HFS") == 0) {
			info.start_byte = (loff_t)((map[8] << 24) | (map[9] << 16) | (map[10] << 8) | map[11]) << 9;
			info.num_blocks = (map[12] << 24) | (map[13] << 16) | (map[14] << 8) | map[15];
			D(bug(" HFS partition found at %d, %d blocks\n", info.start_byte, info.num_blocks));
			break;
		}
	}
	delete[] map;
}


/*
 *  Initialization
 */

void DiskInit(void)
{
	// No drives specified in prefs? Then add defaults
	if (PrefsFindString("disk", 0) == NULL)
		SysAddDiskPrefs();

	// Add drives specified in preferences
	int index = 0;
	const char *str;
	while ((str = PrefsFindString("disk", index++)) != NULL) {
		bool read_only = false;
		if (str[0] == '*') {
			read_only = true;
			str++;
		}
		void *fh = Sys_open(str, read_only);
		if (fh)
			drives.push_back(disk_drive_info(fh, SysIsReadOnly(fh)));
	}
}


/*
 *  Deinitialization
 */

void DiskExit(void)
{
	drive_vec::iterator info, end = drives.end();
	for (info = drives.begin(); info != end; ++info)
		info->close_fh();
	drives.clear();
}


/*
 *  Disk was inserted, flag for mounting
 */

bool DiskMountVolume(void *fh)
{
	drive_vec::iterator info = drives.begin(), end = drives.end();
	while (info != end && info->fh != fh)
		++info;
	if (info != end) {
		if (SysIsDiskInserted(info->fh)) {
			info->read_only = SysIsReadOnly(info->fh);
			WriteMacInt8(info->status + dsDiskInPlace, 1);	// Inserted removable disk
			WriteMacInt8(info->status + dsWriteProt, info->read_only ? 0xff : 0);
			find_hfs_partition(*info);
			if (info->start_byte == 0)
				info->num_blocks = uint32(SysGetFileSize(info->fh) / 512);
			WriteMacInt16(info->status + dsDriveSize, info->num_blocks & 0xffff);
			WriteMacInt16(info->status + dsDriveS1, info->num_blocks >> 16);
			info->to_be_mounted = true;
		}
		return true;
	} else
		return false;
}


/*
 *  Mount volumes for which the to_be_mounted flag is set
 *  (called during interrupt time)
 */

static void mount_mountable_volumes(void)
{
	drive_vec::iterator info, end = drives.end();
	for (info = drives.begin(); info != end; ++info) {

		// Disk in drive?
		if (!ReadMacInt8(info->status + dsDiskInPlace)) {

			// No, check if disk was inserted
			if (SysIsDiskInserted(info->fh))
				DiskMountVolume(info->fh);
		}

		// Mount disk if flagged
		if (info->to_be_mounted) {
			D(bug(" mounting drive %d\n", info->num));
			M68kRegisters r;
			r.d[0] = info->num;
			r.a[0] = 7;	// diskEvent
			Execute68kTrap(0xa02f, &r);		// PostEvent()
			info->to_be_mounted = false;
		}
	}
}


/*
 *  Driver Open() routine
 */

int16 DiskOpen(uint32 pb, uint32 dce)
{
	D(bug("DiskOpen\n"));

	// Set up DCE
	WriteMacInt32(dce + dCtlPosition, 0);
	acc_run_called = false;

	// Install drives
	drive_vec::iterator info, end = drives.end();
	for (info = drives.begin(); info != end; ++info) {

		info->num = FindFreeDriveNumber(1);
		info->to_be_mounted = false;

		if (info->fh) {

			// Allocate drive status record
			M68kRegisters r;
			r.d[0] = SIZEOF_DrvSts;
			Execute68kTrap(0xa71e, &r);		// NewPtrSysClear()
			if (r.a[0] == 0)
				continue;
			info->status = r.a[0];
			D(bug(" DrvSts at %08lx\n", info->status));

			// Set up drive status
			WriteMacInt16(info->status + dsQType, hard20);
			WriteMacInt8(info->status + dsInstalled, 1);
			bool disk_in_place = false;
			if (SysIsFixedDisk(info->fh)) {
				WriteMacInt8(info->status + dsDiskInPlace, 8);	// Fixed disk
				disk_in_place = true;
			} else if (SysIsDiskInserted(info->fh)) {
				WriteMacInt8(info->status + dsDiskInPlace, 1);	// Inserted removable disk
				disk_in_place = true;
			}
			if (disk_in_place) {
				D(bug(" disk inserted\n"));
				WriteMacInt8(info->status + dsWriteProt, info->read_only ? 0x80 : 0);
				find_hfs_partition(*info);
				if (info->start_byte == 0)
					info->num_blocks = uint32(SysGetFileSize(info->fh) / 512);
				info->to_be_mounted = true;
			}
			D(bug(" %d blocks\n", info->num_blocks));
			WriteMacInt16(info->status + dsDriveSize, info->num_blocks & 0xffff);
			WriteMacInt16(info->status + dsDriveS1, info->num_blocks >> 16);

			// Add drive to drive queue
			D(bug(" adding drive %d\n", info->num));
			r.d[0] = (info->num << 16) | (DiskRefNum & 0xffff);
			r.a[0] = info->status + dsQLink;
			Execute68kTrap(0xa04e, &r);	// AddDrive()
		}
	}
	return noErr;
}


/*
 *  Driver Prime() routine
 */

int16 DiskPrime(uint32 pb, uint32 dce)
{
	WriteMacInt32(pb + ioActCount, 0);

	// Drive valid and disk inserted?
	drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
	if (info == drives.end())
		return nsDrvErr;
	if (!ReadMacInt8(info->status + dsDiskInPlace))
		return offLinErr;

	// Get parameters
	void *buffer = Mac2HostAddr(ReadMacInt32(pb + ioBuffer));
	size_t length = ReadMacInt32(pb + ioReqCount);
	loff_t position = ReadMacInt32(dce + dCtlPosition);
	if (ReadMacInt16(pb + ioPosMode) & 0x100)	// 64 bit positioning
		position = ((loff_t)ReadMacInt32(pb + ioWPosOffset) << 32) | ReadMacInt32(pb + ioWPosOffset + 4);
	if ((length & 0x1ff) || (position & 0x1ff))
		return paramErr;

	size_t actual = 0;
	if ((ReadMacInt16(pb + ioTrap) & 0xff) == aRdCmd) {

		// Read
		actual = Sys_read(info->fh, buffer, position + info->start_byte, length);
		if (actual != length)
			return readErr;

	} else {

		// Write
		if (info->read_only)
			return wPrErr;
		actual = Sys_write(info->fh, buffer, position + info->start_byte, length);
		if (actual != length)
			return writErr;
	}

	// Update ParamBlock and DCE
	WriteMacInt32(pb + ioActCount, actual);
	WriteMacInt32(dce + dCtlPosition, ReadMacInt32(dce + dCtlPosition) + actual);
	return noErr;
}


/*
 *  Driver Control() routine
 */

int16 DiskControl(uint32 pb, uint32 dce)
{
	uint16 code = ReadMacInt16(pb + csCode);
	D(bug("DiskControl %d\n", code));

	// General codes
	switch (code) {
		case 1:		// KillIO
			return noErr;

		case 65: {	// Periodic action (accRun, "insert" disks on startup)
			mount_mountable_volumes();
			WriteMacInt16(dce + dCtlFlags, ReadMacInt16(dce + dCtlFlags) & ~0x2000);	// Disable periodic action
			acc_run_called = true;
			return noErr;
		}
	}

	// Drive valid?
	drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
	if (info == drives.end())
		return nsDrvErr;

	// Drive-specific codes
	switch (code) {
		case 5:		// Verify disk
			if (ReadMacInt8(info->status + dsDiskInPlace) > 0)
				return noErr;
			else
				return offLinErr;

		case 6:		// Format disk
			if (info->read_only)
				return wPrErr;
			else if (ReadMacInt8(info->status + dsDiskInPlace) > 0)
				return noErr;
			else
				return offLinErr;

		case 7:		// Eject disk
			if (ReadMacInt8(info->status + dsDiskInPlace) == 8) {
				// Fixed disk, re-insert
				M68kRegisters r;
				r.d[0] = info->num;
				r.a[0] = 7;	// diskEvent
				Execute68kTrap(0xa02f, &r);		// PostEvent()
			} else if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
				SysEject(info->fh);
				WriteMacInt8(info->status + dsDiskInPlace, 0);
			}
			return noErr;

		case 21:	// Get drive icon
		case 22:	// Get disk icon
			WriteMacInt32(pb + csParam, DiskIconAddr);
			return noErr;

		case 23:	// Get drive info
			if (ReadMacInt8(info->status + dsDiskInPlace) == 8)
				WriteMacInt32(pb + csParam, 0x0601);	// Unspecified fixed SCSI disk
			else
				WriteMacInt32(pb + csParam, 0x0201);	// Unspecified SCSI disk
			return noErr;

		case 24:	// Get partition size
			if (ReadMacInt8(info->status + dsDiskInPlace) > 0) {
				WriteMacInt32(pb + csParam, info->num_blocks);
				return noErr;
			} else
				return offLinErr;

		default:
			printf("WARNING: Unknown DiskControl(%d)\n", code);
			return controlErr;
	}
}


/*
 *  Driver Status() routine
 */

int16 DiskStatus(uint32 pb, uint32 dce)
{
	drive_vec::iterator info = get_drive_info(ReadMacInt16(pb + ioVRefNum));
	uint16 code = ReadMacInt16(pb + csCode);
	D(bug("DiskStatus %d\n", code));

	// General codes (we can get these even if the drive was invalid)
	switch (code) {
		case 43: {	// Driver gestalt
			uint32 sel = ReadMacInt32(pb + csParam);
			D(bug(" driver gestalt %c%c%c%c\n", sel >> 24, sel >> 16,  sel >> 8, sel));
			switch (sel) {
				case FOURCC('v','e','r','s'):	// Version
					WriteMacInt32(pb + csParam + 4, 0x01008000);
					break;
				case FOURCC('d','e','v','t'):	// Device type
					if (info != drives.end()) {
						if (ReadMacInt8(info->status + dsDiskInPlace) == 8)
							WriteMacInt32(pb + csParam + 4, FOURCC('d','i','s','k'));
						else
							WriteMacInt32(pb + csParam + 4, FOURCC('r','d','s','k'));
					} else
						WriteMacInt32(pb + csParam + 4, FOURCC('d','i','s','k'));
					break;
				case FOURCC('i','n','t','f'):	// Interface type
					WriteMacInt32(pb + csParam + 4, EMULATOR_ID_4);
					break;
				case FOURCC('s','y','n','c'):	// Only synchronous operation?
					WriteMacInt32(pb + csParam + 4, 0x01000000);
					break;
				case FOURCC('b','o','o','t'):	// Boot ID
					if (info != drives.end())
						WriteMacInt16(pb + csParam + 4, info->num);
					else
						WriteMacInt16(pb + csParam + 4, 0);
					WriteMacInt16(pb + csParam + 6, (uint16)DiskRefNum);
					break;
				case FOURCC('w','i','d','e'):	// 64-bit access supported?
					WriteMacInt16(pb + csParam + 4, 0x0100);
					break;
				case FOURCC('p','u','r','g'):	// Purge flags
					WriteMacInt32(pb + csParam + 4, 0);
					break;
				case FOURCC('e','j','e','c'):	// Eject flags
					WriteMacInt32(pb + csParam + 4, 0x00030003);	// Don't eject on shutdown/restart
					break;
				case FOURCC('f','l','u','s'):	// Flush flags
					WriteMacInt16(pb + csParam + 4, 0);
					break;
				case FOURCC('v','m','o','p'):	// Virtual memory attributes
					WriteMacInt32(pb + csParam + 4, 0);	// Drive not available for VM
					break;
				default:
					return statusErr;
			}
			return noErr;
		}
	}

	// Drive valid?
	if (info == drives.end())
		return nsDrvErr;

	// Drive-specific codes
	switch (code) {
		case 8:		// Get drive status
			Mac2Mac_memcpy(pb + csParam, info->status, 22);
			return noErr;

		case 44: // get startup partition status: http://developer.apple.com/documentation/Hardware/DeviceManagers/ata/ata_ref/ATA.21.html
			printf("WARNING: DiskStatus(44:'get startup partition status') Not Implemented\n");
			return statusErr;

		case 45: // get partition write protect status: http://developer.apple.com/documentation/Hardware/DeviceManagers/ata/ata_ref/ATA.23.html
			printf("WARNING: DiskStatus(45:'get partition write protect status') Not Implemented\n");
			return statusErr;

		case 46: // get partition mount status: http://developer.apple.com/documentation/Hardware/DeviceManagers/ata/ata_ref/ATA.22.html
			printf("WARNING: DiskStatus(46:'get partition mount status') Not Implemented\n");
			return statusErr;

		case 70: // get power mode status: http://developer.apple.com/documentation/Hardware/DeviceManagers/ata/ata_ref/ATA.24.html
			printf("WARNING: DiskStatus(70:'get power mode status') Not Implemented\n");
			return statusErr;

		default:
			printf("WARNING: Unknown DiskStatus(%d)\n", code);
			return statusErr;
	}
}


/*
 *  Driver interrupt routine (1Hz) - check for volumes to be mounted
 */

void DiskInterrupt(void)
{
	if (!acc_run_called)
		return;

	mount_mountable_volumes();
}
