src/wd2010.h

Mon, 14 Jan 2013 09:50:37 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 14 Jan 2013 09:50:37 +0000
changeset 120
df40e6668a46
parent 116
21521e62007f
permissions
-rw-r--r--

Max out system memory by default

Set the system memory to 2MiB base, 2MiB ext. This is a fully loaded 3B1
motherboard with a RAM expansion board. 512KiB base/no ext is the minimum
which can be specified (e.g. kernel memory map area only) but does not leave
any room for userspace. The kernel doesn't like that and doesn't handle it
gracefully...!

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