src/wd2010.h

Thu, 11 Apr 2013 09:37:11 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Thu, 11 Apr 2013 09:37:11 +0100
changeset 138
d744db15cdf7
parent 116
21521e62007f
permissions
-rw-r--r--

Check return value of fread()

     1 #ifndef _WD2010_H
     2 #define _WD2010_H
     4 #include <stdbool.h>
     5 #include <stddef.h>
     6 #include <stdint.h>
     7 #include <stdio.h>
     9 /// WD2010 registers
    10 typedef enum {
    11 	WD2010_REG_ERROR					= 1, ///< Error register
    12 	WD2010_REG_WRITE_PRECOMP_CYLINDER	= 1, ///< Write precompensation cylinder register
    13 	WD2010_REG_SECTOR_COUNT				= 2, ///< Sector count register
    14 	WD2010_REG_SECTOR_NUMBER			= 3, ///< Sector number register
    15 	WD2010_REG_CYLINDER_LOW				= 4, ///< Low byte of cylinder
    16 	WD2010_REG_CYLINDER_HIGH			= 5, ///< High byte of cylinder
    17 	WD2010_REG_SDH						= 6, ///< Sector size, drive, and head
    18 	WD2010_REG_STATUS					= 7, ///< Status register
    19 	WD2010_REG_COMMAND					= 7, ///< Command register
    20 	UNIXPC_REG_MCR2						= 255	///< UNIX-PC MCR2 register (special!)
    21 } WD2010_REG;
    23 /// WD2010 emulator error codes
    24 typedef enum {
    25 	WD2010_ERR_OK			= 0,		///< Operation succeeded
    26 	WD2010_ERR_BAD_GEOM		= -1,		///< Bad geometry, or image file too small
    27 	WD2010_ERR_NO_MEMORY	= -2		///< Out of memory
    28 } WD2010_ERR;
    30 typedef struct {
    31 	// Current track, head and sector
    32 	int						track, head, sector;
    33 	// Geometry of current disc
    34 	int						geom_secsz, geom_spt, geom_heads, geom_tracks;
    35 	// IRQ status
    36 	bool					irq;
    37 	// Status of last command
    38 	uint8_t					status;
    39 	// Error resgister
    40 	uint8_t					error_reg;
    41 	// Cylinder number registers
    42 	uint8_t					cylinder_high_reg, cylinder_low_reg;
    43 	// SDH register (sets sector size, drive number, and head number)
    44 	uint8_t					sdh;
    45 	// MCR2 register (LSB is HDSEL3 - head select bit 3)
    46 	bool					mcr2_hdsel3, mcr2_ddrive1;
    47 	// Sector number and count registers
    48 	int						sector_number, sector_count;
    49 	// Last command has the multiple sector flag set?
    50 	bool					multi_sector;
    51 	// Last command uses DRQ bit?
    52 	bool					cmd_has_drq;
    53 	// Current write is a format?
    54 	bool					formatting;
    55 	// Data buffer, current DRQ pointer and length
    56 	uint8_t					*data;
    57 	size_t					data_pos, data_len;
    58 	// Current disc image file
    59 	FILE					*disc_image;
    60 	// LBA at which to start writing
    61 	int						write_pos;
    62 	// Flag to allow delaying DRQ
    63 	bool					drq;
    64 } WD2010_CTX;
    66 /**
    67  * @brief	Initialise a WD2010 context.
    68  * @param	ctx		WD2010 context.
    69  *
    70  * This must be run once when the context is created.
    71  */
    72 int wd2010_init(WD2010_CTX *ctx, FILE *fp, int secsz, int spt, int heads);
    74 /**
    75  * @brief	Reset a WD2010 context.
    76  * @param	ctx		WD2010 context.
    77  *
    78  * This should be run if the WD2010 needs to be reset (MR/ line toggled).
    79  */
    80 void wd2010_reset(WD2010_CTX *ctx);
    82 /**
    83  * Deinitialise a WD2010 context.
    84  * @param	ctx		WD2010 context.
    85  */
    86 void wd2010_done(WD2010_CTX *ctx);
    88 /**
    89  * @brief	Read IRQ Rising Edge status.
    90  * @param	ctx		WD2010 context.
    91  */
    92 bool wd2010_get_irq(WD2010_CTX *ctx);
    94 /**
    95  * @brief	Read DRQ status.
    96  * @param	ctx		WD2010 context.
    97  */
    98 bool wd2010_get_drq(WD2010_CTX *ctx);
   100 /**
   101  * @brief	Read WD2010 register.
   102  * @param	ctx		WD2010 context
   103  * @param	addr	Register address (0, 1, 2, 3, 4, 5, 6, 7, or 8)
   104  */
   105 uint8_t wd2010_read_reg(WD2010_CTX *ctx, uint8_t addr);
   107 /**
   108  * @brief	Write WD2010 register
   109  * @param	ctx		WD2010 context
   110  * @param	addr	Register address (0, 1, 2, 3, 4, 5, 6, 7, or 8)
   111  * @param	val		Value to write
   112  */
   113 void wd2010_write_reg(WD2010_CTX *ctx, uint8_t addr, uint8_t val);
   115 /**
   116  * @brief   Read a data byte from the data buffer
   117  * @param	ctx		WD2010 context
   118  */
   119 uint8_t wd2010_read_data(WD2010_CTX *ctx);
   121 /**
   122  * @brief   Write a value to the data buffer
   123  * @param	ctx		WD2010 context
   124  * @param   val     Value to write
   125  */
   126 void wd2010_write_data(WD2010_CTX *ctx, uint8_t val);
   128 void wd2010_dma_miss(WD2010_CTX *ctx);
   129 #endif