src/wd279x.h

Sun, 05 Dec 2010 16:20:00 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sun, 05 Dec 2010 16:20:00 +0000
changeset 52
a350dfa92895
parent 49
545798274dad
child 76
2ef98ea1e944
permissions
-rw-r--r--

add preliminary WD279x emulation to core

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