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()

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