src/wd279x.h

Mon, 14 Jan 2013 09:48:21 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 14 Jan 2013 09:48:21 +0000
changeset 119
101fe02456ce
parent 111
4c85846b09cd
permissions
-rw-r--r--

Handle memory more gracefully

Fixed in this cset:

* Return an 'empty space' value if the memory wraps around

* Allow the 'empty bus' value to be changed via an ifdef

* Properly handle situations where expansion memory is turned off

     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 	// Track and sector registers
    29 	int						track_reg, sector_reg;
    30 	// Geometry of current disc
    31 	int						geom_secsz, geom_spt, geom_heads, geom_tracks;
    32 	// IRQ status
    33 	bool					irq;
    34 	// Status of last command
    35 	uint8_t					status;
    36 	// Last command uses DRQ bit?
    37 	bool					cmd_has_drq;
    38 	// The last value written to the data register
    39 	uint8_t					data_reg;
    40 	// Last step direction. -1 for "towards zero", 1 for "away from zero"
    41 	int						last_step_dir;
    42 	// Data buffer, current DRQ pointer and length
    43 	uint8_t					*data;
    44 	size_t					data_pos, data_len;
    45 	// Current disc image file
    46 	FILE					*disc_image;
    47 	// Write protect flag
    48 	int						writeable;
    49 	// LBA at which to start writing
    50 	int						write_pos;
    51 	// True if a format command is in progress
    52 	int						formatting;
    53 } WD2797_CTX;
    55 /**
    56  * @brief	Initialise a WD2797 context.
    57  * @param	ctx		WD2797 context.
    58  *
    59  * This must be run once when the context is created.
    60  */
    61 void wd2797_init(WD2797_CTX *ctx);
    63 /**
    64  * @brief	Reset a WD2797 context.
    65  * @param	ctx		WD2797 context.
    66  *
    67  * This should be run if the WD2797 needs to be reset (nRST line toggled).
    68  */
    69 void wd2797_reset(WD2797_CTX *ctx);
    71 /**
    72  * Deinitialise a WD2797 context.
    73  * @param	ctx		WD2797 context.
    74  */
    75 void wd2797_done(WD2797_CTX *ctx);
    77 /**
    78  * @brief	Read IRQ Rising Edge status. Clears Rising Edge status if it is set.
    79  * @note	No more IRQs will be sent until the Status Register is read, or a new command is written to the CR.
    80  * @param	ctx		WD2797 context.
    81  */
    82 bool wd2797_get_irq(WD2797_CTX *ctx);
    84 /**
    85  * @brief	Read DRQ status.
    86  * @param	ctx		WD2797 context.
    87  */
    88 bool wd2797_get_drq(WD2797_CTX *ctx);
    90 /**
    91  * @brief	Assign a disc image to the WD2797.
    92  * @param	ctx		WD2797 context.
    93  * @param	fp		Disc image file, already opened in "r+b" mode.
    94  * @param	secsz	Sector size: either 128, 256, 512 or 1024.
    95  * @param	spt		Sectors per track.
    96  * @param	heads	Number of heads (1 or 2).
    97  * @return	Error code; WD279X_E_OK if everything worked OK.
    98  */
    99 WD2797_ERR wd2797_load(WD2797_CTX *ctx, FILE *fp, int secsz, int spt, int heads, int writeable);
   101 /**
   102  * @brief	Deassign the current image file.
   103  * @param	ctx		WD2797 context.
   104  */
   105 void wd2797_unload(WD2797_CTX *ctx);
   107 /**
   108  * @brief	Read WD279x register.
   109  * @param	ctx		WD2797 context
   110  * @param	addr	Register address (0, 1, 2 or 3)
   111  */
   112 uint8_t wd2797_read_reg(WD2797_CTX *ctx, uint8_t addr);
   114 /**
   115  * @brief	Write WD279X register
   116  * @param	ctx		WD2797 context
   117  * @param	addr	Register address (0, 1, 2 or 3)
   118  * @param	val		Value to write
   119  */
   120 void wd2797_write_reg(WD2797_CTX *ctx, uint8_t addr, uint8_t val);
   122 void wd2797_dma_miss(WD2797_CTX *ctx);
   123 #endif