src/wd2010.h

changeset 112
a392eb8f9806
child 116
21521e62007f
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/wd2010.h	Sat Nov 17 19:18:29 2012 +0000
     1.3 @@ -0,0 +1,127 @@
     1.4 +#ifndef _WD2010_H
     1.5 +#define _WD2010_H
     1.6 +
     1.7 +#include <stdbool.h>
     1.8 +#include <stddef.h>
     1.9 +#include <stdint.h>
    1.10 +#include <stdio.h>
    1.11 +
    1.12 +/// WD2010 registers
    1.13 +typedef enum {
    1.14 +	WD2010_REG_ERROR                   = 1, ///< Error register
    1.15 +	WD2010_REG_WRITE_PRECOMP_CYLINDER  = 1, ///< Write precompensation cylinder
    1.16 +                                             ///< register
    1.17 +	WD2010_REG_SECTOR_COUNT            = 2, ///< Sector count register
    1.18 +	WD2010_REG_SECTOR_NUMBER           = 3, ///< Sector number register
    1.19 +	WD2010_REG_CYLINDER_LOW            = 4, ///< Low byte of cylinder
    1.20 +	WD2010_REG_CYLINDER_HIGH           = 5, ///< High byte of cylinder
    1.21 +	WD2010_REG_SDH                     = 6, ///< Sector size, drive, and head
    1.22 +	WD2010_REG_STATUS                   = 7, ///< Status register
    1.23 +	WD2010_REG_COMMAND                  = 7, ///< Command register
    1.24 +} WD2010_REG;
    1.25 +
    1.26 +/// WD2010 emulator error codes
    1.27 +typedef enum {
    1.28 +	WD2010_ERR_OK			= 0,		///< Operation succeeded
    1.29 +	WD2010_ERR_BAD_GEOM		= -1,		///< Bad geometry, or image file too small
    1.30 +	WD2010_ERR_NO_MEMORY	= -2		///< Out of memory
    1.31 +} WD2010_ERR;
    1.32 +
    1.33 +typedef struct {
    1.34 +	// Current track, head and sector
    1.35 +	int						track, head, sector;
    1.36 +	// Geometry of current disc
    1.37 +	int						geom_secsz, geom_spt, geom_heads, geom_tracks;
    1.38 +	// IRQ status
    1.39 +	bool					irq;
    1.40 +	// Status of last command
    1.41 +	uint8_t					status;
    1.42 +	// Error resgister
    1.43 +	uint8_t					error_reg;
    1.44 +	// Cylinder number registers
    1.45 +	uint8_t					cylinder_high_reg, cylinder_low_reg;
    1.46 +	// SDH register (sets sector size, drive number, and head number)
    1.47 +	uint8_t					sdh;
    1.48 +	// Sector number and count registers
    1.49 +	int						sector_number, sector_count;
    1.50 +	// Last command has the multiple sector flag set?
    1.51 +	bool					multi_sector;
    1.52 +	// Last command uses DRQ bit?
    1.53 +	bool					cmd_has_drq;
    1.54 +	// Current write is a format?
    1.55 +	bool					formatting;
    1.56 +	// Data buffer, current DRQ pointer and length
    1.57 +	uint8_t					*data;
    1.58 +	size_t					data_pos, data_len;
    1.59 +	// Current disc image file
    1.60 +	FILE					*disc_image;
    1.61 +	// LBA at which to start writing
    1.62 +	int						write_pos;
    1.63 +	// Flag to allow delaying DRQ
    1.64 +	bool					drq;
    1.65 +} WD2010_CTX;
    1.66 +
    1.67 +/**
    1.68 + * @brief	Initialise a WD2010 context.
    1.69 + * @param	ctx		WD2010 context.
    1.70 + *
    1.71 + * This must be run once when the context is created.
    1.72 + */
    1.73 +int wd2010_init(WD2010_CTX *ctx, FILE *fp, int secsz, int spt, int heads);
    1.74 +
    1.75 +/**
    1.76 + * @brief	Reset a WD2010 context.
    1.77 + * @param	ctx		WD2010 context.
    1.78 + *
    1.79 + * This should be run if the WD2010 needs to be reset (MR/ line toggled).
    1.80 + */
    1.81 +void wd2010_reset(WD2010_CTX *ctx);
    1.82 +
    1.83 +/**
    1.84 + * Deinitialise a WD2010 context.
    1.85 + * @param	ctx		WD2010 context.
    1.86 + */
    1.87 +void wd2010_done(WD2010_CTX *ctx);
    1.88 +
    1.89 +/**
    1.90 + * @brief	Read IRQ Rising Edge status.
    1.91 + * @param	ctx		WD2010 context.
    1.92 + */
    1.93 +bool wd2010_get_irq(WD2010_CTX *ctx);
    1.94 +
    1.95 +/**
    1.96 + * @brief	Read DRQ status.
    1.97 + * @param	ctx		WD2010 context.
    1.98 + */
    1.99 +bool wd2010_get_drq(WD2010_CTX *ctx);
   1.100 +
   1.101 +/**
   1.102 + * @brief	Read WD2010 register.
   1.103 + * @param	ctx		WD2010 context
   1.104 + * @param	addr	Register address (0, 1, 2, 3, 4, 5, 6, 7, or 8)
   1.105 + */
   1.106 +uint8_t wd2010_read_reg(WD2010_CTX *ctx, uint8_t addr);
   1.107 +
   1.108 +/**
   1.109 + * @brief	Write WD2010 register
   1.110 + * @param	ctx		WD2010 context
   1.111 + * @param	addr	Register address (0, 1, 2, 3, 4, 5, 6, 7, or 8)
   1.112 + * @param	val		Value to write
   1.113 + */
   1.114 +void wd2010_write_reg(WD2010_CTX *ctx, uint8_t addr, uint8_t val);
   1.115 +
   1.116 +/**
   1.117 + * @brief   Read a data byte from the data buffer
   1.118 + * @param	ctx		WD2010 context
   1.119 + */
   1.120 +uint8_t wd2010_read_data(WD2010_CTX *ctx);
   1.121 +
   1.122 +/**
   1.123 + * @brief   Write a value to the data buffer
   1.124 + * @param	ctx		WD2010 context
   1.125 + * @param   val     Value to write
   1.126 + */
   1.127 +void wd2010_write_data(WD2010_CTX *ctx, uint8_t val);
   1.128 +
   1.129 +void wd2010_dma_miss(WD2010_CTX *ctx);
   1.130 +#endif