src/wd2010.h

Sat, 17 Nov 2012 22:15:23 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 17 Nov 2012 22:15:23 +0000
changeset 115
da3d10af0711
parent 112
a392eb8f9806
child 116
21521e62007f
permissions
-rw-r--r--

wd2010: use LOGS when logging unformatted strings

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@112 11 WD2010_REG_ERROR = 1, ///< Error register
philpem@112 12 WD2010_REG_WRITE_PRECOMP_CYLINDER = 1, ///< Write precompensation cylinder
philpem@112 13 ///< register
philpem@112 14 WD2010_REG_SECTOR_COUNT = 2, ///< Sector count register
philpem@112 15 WD2010_REG_SECTOR_NUMBER = 3, ///< Sector number register
philpem@112 16 WD2010_REG_CYLINDER_LOW = 4, ///< Low byte of cylinder
philpem@112 17 WD2010_REG_CYLINDER_HIGH = 5, ///< High byte of cylinder
philpem@112 18 WD2010_REG_SDH = 6, ///< Sector size, drive, and head
philpem@112 19 WD2010_REG_STATUS = 7, ///< Status register
philpem@112 20 WD2010_REG_COMMAND = 7, ///< Command register
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@112 45 // Sector number and count registers
philpem@112 46 int sector_number, sector_count;
philpem@112 47 // Last command has the multiple sector flag set?
philpem@112 48 bool multi_sector;
philpem@112 49 // Last command uses DRQ bit?
philpem@112 50 bool cmd_has_drq;
philpem@112 51 // Current write is a format?
philpem@112 52 bool formatting;
philpem@112 53 // Data buffer, current DRQ pointer and length
philpem@112 54 uint8_t *data;
philpem@112 55 size_t data_pos, data_len;
philpem@112 56 // Current disc image file
philpem@112 57 FILE *disc_image;
philpem@112 58 // LBA at which to start writing
philpem@112 59 int write_pos;
philpem@112 60 // Flag to allow delaying DRQ
philpem@112 61 bool drq;
philpem@112 62 } WD2010_CTX;
philpem@112 63
philpem@112 64 /**
philpem@112 65 * @brief Initialise a WD2010 context.
philpem@112 66 * @param ctx WD2010 context.
philpem@112 67 *
philpem@112 68 * This must be run once when the context is created.
philpem@112 69 */
philpem@112 70 int wd2010_init(WD2010_CTX *ctx, FILE *fp, int secsz, int spt, int heads);
philpem@112 71
philpem@112 72 /**
philpem@112 73 * @brief Reset a WD2010 context.
philpem@112 74 * @param ctx WD2010 context.
philpem@112 75 *
philpem@112 76 * This should be run if the WD2010 needs to be reset (MR/ line toggled).
philpem@112 77 */
philpem@112 78 void wd2010_reset(WD2010_CTX *ctx);
philpem@112 79
philpem@112 80 /**
philpem@112 81 * Deinitialise a WD2010 context.
philpem@112 82 * @param ctx WD2010 context.
philpem@112 83 */
philpem@112 84 void wd2010_done(WD2010_CTX *ctx);
philpem@112 85
philpem@112 86 /**
philpem@112 87 * @brief Read IRQ Rising Edge status.
philpem@112 88 * @param ctx WD2010 context.
philpem@112 89 */
philpem@112 90 bool wd2010_get_irq(WD2010_CTX *ctx);
philpem@112 91
philpem@112 92 /**
philpem@112 93 * @brief Read DRQ status.
philpem@112 94 * @param ctx WD2010 context.
philpem@112 95 */
philpem@112 96 bool wd2010_get_drq(WD2010_CTX *ctx);
philpem@112 97
philpem@112 98 /**
philpem@112 99 * @brief Read WD2010 register.
philpem@112 100 * @param ctx WD2010 context
philpem@112 101 * @param addr Register address (0, 1, 2, 3, 4, 5, 6, 7, or 8)
philpem@112 102 */
philpem@112 103 uint8_t wd2010_read_reg(WD2010_CTX *ctx, uint8_t addr);
philpem@112 104
philpem@112 105 /**
philpem@112 106 * @brief Write WD2010 register
philpem@112 107 * @param ctx WD2010 context
philpem@112 108 * @param addr Register address (0, 1, 2, 3, 4, 5, 6, 7, or 8)
philpem@112 109 * @param val Value to write
philpem@112 110 */
philpem@112 111 void wd2010_write_reg(WD2010_CTX *ctx, uint8_t addr, uint8_t val);
philpem@112 112
philpem@112 113 /**
philpem@112 114 * @brief Read a data byte from the data buffer
philpem@112 115 * @param ctx WD2010 context
philpem@112 116 */
philpem@112 117 uint8_t wd2010_read_data(WD2010_CTX *ctx);
philpem@112 118
philpem@112 119 /**
philpem@112 120 * @brief Write a value to the data buffer
philpem@112 121 * @param ctx WD2010 context
philpem@112 122 * @param val Value to write
philpem@112 123 */
philpem@112 124 void wd2010_write_data(WD2010_CTX *ctx, uint8_t val);
philpem@112 125
philpem@112 126 void wd2010_dma_miss(WD2010_CTX *ctx);
philpem@112 127 #endif