src/wd2010.h

Sat, 17 Nov 2012 19:18:29 +0000

author
Philip Pemberton <philpem@philpem.me.uk>
date
Sat, 17 Nov 2012 19:18:29 +0000
changeset 112
a392eb8f9806
child 116
21521e62007f
permissions
-rw-r--r--

add HDD support + fixes

Patch-Author: Andrew Warkentin <andreww591!gmail>
Patch-Message-ID: <50A772FC.8020009@gmail.com>

I have added floppy write support, full hard disk emulation, and proper handling of DMA page faults to FreeBee. I also fixed the floppy step commands, changed the "force interrupt" floppy command to generate a type 1 status, and changed the DMA address counter to reset to 3fff when a transfer completes (which is what Unix seems to expect - without it, the kernel says that the floppy isn't ready). The floppy, hard disk, and DMA page fault tests all pass. Initializing hard disks and floppies also works (the geometry for both is still fixed by the size of the image, though, and format commands only appear to succeed, but they don't modify the image). Unix still doesn't run, though (it hangs after reading some sectors from the floppy).

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