src/wd279x.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 111
4c85846b09cd
permissions
-rw-r--r--

wd2010: use LOGS when logging unformatted strings

philpem@48 1 #ifndef _WD279X_H
philpem@48 2 #define _WD279X_H
philpem@48 3
philpem@48 4 #include <stdbool.h>
philpem@48 5 #include <stddef.h>
philpem@48 6 #include <stdint.h>
philpem@48 7 #include <stdio.h>
philpem@48 8
philpem@49 9 /// WD279x registers
philpem@49 10 typedef enum {
philpem@49 11 WD2797_REG_STATUS = 0, ///< Status register
philpem@49 12 WD2797_REG_COMMAND = 0, ///< Command register
philpem@49 13 WD2797_REG_TRACK = 1, ///< Track register
philpem@49 14 WD2797_REG_SECTOR = 2, ///< Sector register
philpem@49 15 WD2797_REG_DATA = 3 ///< Data register
philpem@49 16 } WD2797_REG;
philpem@49 17
philpem@49 18 /// WD279x emulator error codes
philpem@49 19 typedef enum {
philpem@49 20 WD2797_ERR_OK = 0, ///< Operation succeeded
philpem@49 21 WD2797_ERR_BAD_GEOM = -1, ///< Bad geometry, or image file too small
philpem@49 22 WD2797_ERR_NO_MEMORY = -2 ///< Out of memory
philpem@49 23 } WD2797_ERR;
philpem@48 24
philpem@48 25 typedef struct {
philpem@48 26 // Current track, head and sector
philpem@48 27 int track, head, sector;
philpem@111 28 // Track and sector registers
philpem@111 29 int track_reg, sector_reg;
philpem@48 30 // Geometry of current disc
philpem@48 31 int geom_secsz, geom_spt, geom_heads, geom_tracks;
philpem@79 32 // IRQ status
philpem@79 33 bool irq;
philpem@48 34 // Status of last command
philpem@48 35 uint8_t status;
philpem@48 36 // Last command uses DRQ bit?
philpem@48 37 bool cmd_has_drq;
philpem@48 38 // The last value written to the data register
philpem@48 39 uint8_t data_reg;
philpem@48 40 // Last step direction. -1 for "towards zero", 1 for "away from zero"
philpem@48 41 int last_step_dir;
philpem@48 42 // Data buffer, current DRQ pointer and length
philpem@49 43 uint8_t *data;
philpem@48 44 size_t data_pos, data_len;
philpem@48 45 // Current disc image file
philpem@48 46 FILE *disc_image;
philpem@111 47 // Write protect flag
philpem@111 48 int writeable;
philpem@111 49 // LBA at which to start writing
philpem@111 50 int write_pos;
philpem@111 51 // True if a format command is in progress
philpem@111 52 int formatting;
philpem@49 53 } WD2797_CTX;
philpem@49 54
philpem@49 55 /**
philpem@49 56 * @brief Initialise a WD2797 context.
philpem@49 57 * @param ctx WD2797 context.
philpem@49 58 *
philpem@49 59 * This must be run once when the context is created.
philpem@49 60 */
philpem@49 61 void wd2797_init(WD2797_CTX *ctx);
philpem@49 62
philpem@49 63 /**
philpem@49 64 * @brief Reset a WD2797 context.
philpem@49 65 * @param ctx WD2797 context.
philpem@49 66 *
philpem@49 67 * This should be run if the WD2797 needs to be reset (nRST line toggled).
philpem@49 68 */
philpem@49 69 void wd2797_reset(WD2797_CTX *ctx);
philpem@49 70
philpem@49 71 /**
philpem@49 72 * Deinitialise a WD2797 context.
philpem@49 73 * @param ctx WD2797 context.
philpem@49 74 */
philpem@49 75 void wd2797_done(WD2797_CTX *ctx);
philpem@49 76
philpem@49 77 /**
philpem@49 78 * @brief Read IRQ Rising Edge status. Clears Rising Edge status if it is set.
philpem@49 79 * @note No more IRQs will be sent until the Status Register is read, or a new command is written to the CR.
philpem@49 80 * @param ctx WD2797 context.
philpem@49 81 */
philpem@49 82 bool wd2797_get_irq(WD2797_CTX *ctx);
philpem@49 83
philpem@49 84 /**
philpem@49 85 * @brief Read DRQ status.
philpem@49 86 * @param ctx WD2797 context.
philpem@49 87 */
philpem@49 88 bool wd2797_get_drq(WD2797_CTX *ctx);
philpem@49 89
philpem@49 90 /**
philpem@49 91 * @brief Assign a disc image to the WD2797.
philpem@49 92 * @param ctx WD2797 context.
philpem@49 93 * @param fp Disc image file, already opened in "r+b" mode.
philpem@49 94 * @param secsz Sector size: either 128, 256, 512 or 1024.
philpem@49 95 * @param spt Sectors per track.
philpem@49 96 * @param heads Number of heads (1 or 2).
philpem@49 97 * @return Error code; WD279X_E_OK if everything worked OK.
philpem@49 98 */
philpem@111 99 WD2797_ERR wd2797_load(WD2797_CTX *ctx, FILE *fp, int secsz, int spt, int heads, int writeable);
philpem@49 100
philpem@49 101 /**
philpem@49 102 * @brief Deassign the current image file.
philpem@49 103 * @param ctx WD2797 context.
philpem@49 104 */
philpem@49 105 void wd2797_unload(WD2797_CTX *ctx);
philpem@49 106
philpem@49 107 /**
philpem@49 108 * @brief Read WD279x register.
philpem@49 109 * @param ctx WD2797 context
philpem@49 110 * @param addr Register address (0, 1, 2 or 3)
philpem@49 111 */
philpem@49 112 uint8_t wd2797_read_reg(WD2797_CTX *ctx, uint8_t addr);
philpem@49 113
philpem@49 114 /**
philpem@49 115 * @brief Write WD279X register
philpem@49 116 * @param ctx WD2797 context
philpem@49 117 * @param addr Register address (0, 1, 2 or 3)
philpem@49 118 * @param val Value to write
philpem@49 119 */
philpem@49 120 void wd2797_write_reg(WD2797_CTX *ctx, uint8_t addr, uint8_t val);
philpem@49 121
philpem@111 122 void wd2797_dma_miss(WD2797_CTX *ctx);
philpem@48 123 #endif