
/*
 * Copyright 1987 Alan Kent
 *
 * Permission is granted to redistribute this code as long
 * as this message is retained in the code and the code is
 * not sold without written permission from the author.
 *
 * UUCP: {seismo,hplabs,mcvax,ukc,nttlab}!munnari!goanna.oz!ajk
 * ACSnet: ajk@goanna.oz
 * ARPA: munnari!goanna.oz!ajk@SEISMO.ARPA
 */

#include "exec/types.h"
#include "exec/memory.h"
#include "exec/resident.h"
#include "exec/libraries.h"
#include "exec/devices.h"
#include "exec/errors.h"
#include "exec/execbase.h"
#include "exec/interrupts.h"
#include "libraries/dosextens.h"

#include "harddisk.h"

#define HD_VERSION		1
#define HD_REVISION		1
#define HD_IDSTRING		"harddisk.device 1.2 (19 Apr 1987)\r\n"
#define HD_PRIORITY		1
#define HD_STACKSIZE	4000


#define PROCPTR(proc)	((struct Process*)(((char*)(proc))-sizeof(struct Task)))
#define CHANGE_COUNT	1


extern struct hd_FirstSector first;


/*#define DEBUG 1*/

#ifdef DEBUG
#define ERROR(str)	error(str)
#else
#define ERROR(str)	Exit(20L)
#endif


struct hd_msg {
	struct Message	hdm_Msg;
	struct hd_dev *	hdm_Device;
	struct hd_unit *hdm_Unit;
};


struct hd_unit {
	struct Unit	hdu_Unit;
	ULONG		hdu_Flags;
	UBYTE		hdu_UnitNum;
	UBYTE		pad;
	struct hd_msg hdu_Msg;
	struct Task *hdu_Task;
};


struct hd_dev {
	struct Device	hd_Dev;
	struct hd_unit	hd_Unit[ HD_NUMUNITS ];
	ULONG			hd_Flags;
	BPTR			hd_SegList;		/* I think its BPTR */
};


struct posn {
	LONG	block;
	LONG	cylinder;	/* -ve cylinder means not in use */
	LONG	surface;
	LONG	sector;
};




/* all the functions used */

extern void				ReplyMsg ();
extern struct Message *	GetMsg ();
extern APTR				AllocMem ();
extern void				FreeMem ();
extern APTR				OpenLibrary ();
extern LONG				AllocSignal ();
extern struct Task *	FindTask ();
extern struct Library *	MakeLibrary ();
extern struct MsgPort *	CreatePort ();
extern struct Process *	CreateProc ();
extern struct Message *	WaitPort ();



/* my functions */

extern LONG		aOpen ();
extern LONG		aClose ();
extern LONG		aExpunge ();
extern LONG		aNull ();
extern LONG		aBeginIO ();
extern LONG		aAbortIO ();
extern struct hd_dev*cOpen ();
extern BPTR		cClose ();
extern BPTR		cExpunge ();
extern void		cBeginIO ();
extern void		cAbortIO ();
extern int		init_cache ();
extern void		free_cache ();
extern BOOL		calc ();
extern UBYTE *	read_cache ();
extern void		write_cache ();
extern void		perform_io ();
extern int		find_empty_cache ();
extern void		flush_track ();
extern void		flush_all ();
extern void		clear_all ();
extern int		wd_open ();
extern void		wd_close ();
extern int		wd_format_track ();
extern int		wd_seek ();
extern int		wd_cmd ();
extern int		read_sector ();
extern int		write_sector ();
extern void		copy_sector ();
extern void		error ();
extern LONG		aLibInit ();
extern LONG		cLibInit ();
extern void		subprocess ();
extern LONG		HDHandler ();


/* globals */

extern struct DosLibrary *	DOSBase;
extern struct ExecBase *	SysBase;


extern struct posn		cur_posn;	/* set by read_sector and write_sector */

extern LONG				bad_error;	/* set by read_sector and write_sector */
extern struct posn		bad_posn;

extern char				dev_name[];
extern char				dev_id_string[];

extern LONG				proc_seg_list[];	/* well, pretty close */

extern struct Interrupt *HDInterrupt;

extern struct MsgPort *	port;
