filename | src/gdrom/ide.h |
changeset | 1097:d4807997e450 |
prev | 858:368fc0dcd57c |
author | nkeynes |
date | Fri May 29 18:47:05 2015 +1000 (8 years ago) |
permissions | -rw-r--r-- |
last change | Fix test case |
file | annotate | diff | log | raw |
nkeynes@31 | 1 | /** |
nkeynes@561 | 2 | * $Id$ |
nkeynes@2 | 3 | * |
nkeynes@31 | 4 | * This file defines the interface and structures of the dreamcast's IDE |
nkeynes@31 | 5 | * port. Note that the register definitions are in asic.h, as the registers |
nkeynes@31 | 6 | * fall into the general ASIC ranges (and I don't want to use smaller pages |
nkeynes@31 | 7 | * at this stage). The registers here are exactly as per the ATA |
nkeynes@31 | 8 | * specifications, which makes things a little easier. |
nkeynes@2 | 9 | * |
nkeynes@31 | 10 | * Copyright (c) 2005 Nathan Keynes. |
nkeynes@31 | 11 | * |
nkeynes@31 | 12 | * This program is free software; you can redistribute it and/or modify |
nkeynes@31 | 13 | * it under the terms of the GNU General Public License as published by |
nkeynes@31 | 14 | * the Free Software Foundation; either version 2 of the License, or |
nkeynes@31 | 15 | * (at your option) any later version. |
nkeynes@31 | 16 | * |
nkeynes@31 | 17 | * This program is distributed in the hope that it will be useful, |
nkeynes@31 | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nkeynes@31 | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nkeynes@31 | 20 | * GNU General Public License for more details. |
nkeynes@2 | 21 | */ |
nkeynes@31 | 22 | |
nkeynes@736 | 23 | #ifndef lxdream_ide_H |
nkeynes@736 | 24 | #define lxdream_ide_H 1 |
nkeynes@2 | 25 | |
nkeynes@736 | 26 | #include "lxdream.h" |
nkeynes@736 | 27 | |
nkeynes@736 | 28 | #ifdef __cplusplus |
nkeynes@736 | 29 | extern "C" { |
nkeynes@736 | 30 | #endif |
nkeynes@2 | 31 | |
nkeynes@858 | 32 | #define GDROM_DRIVE_STATUS_LENGTH 10 |
nkeynes@493 | 33 | #define GDROM_SENSE_LENGTH 10 |
nkeynes@493 | 34 | #define GDROM_MODE_LENGTH 32 |
nkeynes@493 | 35 | |
nkeynes@1097 | 36 | #define IDE_DISC_READY 0x01 /* ored with above */ |
nkeynes@1097 | 37 | #define IDE_DISC_IDLE 0x02 /* ie spun-down */ |
nkeynes@1097 | 38 | #define IDE_DISC_NONE 0x06 /* No media in drive */ |
nkeynes@1097 | 39 | |
nkeynes@2 | 40 | struct ide_registers { |
nkeynes@152 | 41 | /* IDE interface registers */ |
nkeynes@2 | 42 | uint8_t status; /* A05F709C + A05F7018 Read-only */ |
nkeynes@2 | 43 | uint8_t control; /* A05F7018 Write-only 01110 */ |
nkeynes@2 | 44 | uint8_t error; /* A05F7084 Read-only 10001 */ |
nkeynes@2 | 45 | uint8_t feature; /* A05F7084 Write-only 10001 */ |
nkeynes@2 | 46 | uint8_t count; /* A05F7088 Read/Write 10010 */ |
nkeynes@2 | 47 | uint8_t disc; /* A05F708C Read-only 10011 */ |
nkeynes@2 | 48 | uint8_t lba0; /* A05F708C Write-only 10011 (NB: Presumed, TBV */ |
nkeynes@2 | 49 | uint8_t lba1; /* A05F7090 Read/Write 10100 */ |
nkeynes@2 | 50 | uint8_t lba2; /* A05F7094 Read/Write 10101 */ |
nkeynes@2 | 51 | uint8_t device; /* A05F7098 Read/Write 10110 */ |
nkeynes@2 | 52 | uint8_t command; /* A05F709C Write-only 10111 */ |
nkeynes@152 | 53 | |
nkeynes@152 | 54 | /* Internal IDE state */ |
nkeynes@138 | 55 | uint8_t intrq_pending; /* Flag to indicate if the INTRQ line is active */ |
nkeynes@245 | 56 | gboolean interface_enabled; |
nkeynes@254 | 57 | gboolean was_reset; /* Flag indicating that the device has just been reset */ |
nkeynes@493 | 58 | uint32_t state; |
nkeynes@493 | 59 | uint32_t last_packet_command; /* Identifies the command executing during a r/w cycle */ |
nkeynes@138 | 60 | |
nkeynes@152 | 61 | /* Sense response for the last executed packet command */ |
nkeynes@493 | 62 | unsigned char gdrom_sense[GDROM_SENSE_LENGTH]; |
nkeynes@493 | 63 | unsigned char gdrom_mode[GDROM_MODE_LENGTH]; |
nkeynes@152 | 64 | |
nkeynes@152 | 65 | /* offset in the buffer of the next word to read/write, or -1 |
nkeynes@152 | 66 | * if inactive. |
nkeynes@152 | 67 | */ |
nkeynes@493 | 68 | int32_t data_offset; |
nkeynes@493 | 69 | int32_t data_length; |
nkeynes@152 | 70 | |
nkeynes@245 | 71 | /* Status reporting information */ |
nkeynes@245 | 72 | uint8_t last_read_track; |
nkeynes@493 | 73 | uint32_t current_lba; |
nkeynes@493 | 74 | uint32_t current_mode; |
nkeynes@342 | 75 | uint32_t sectors_left; /* sectors left after current read */ |
nkeynes@2 | 76 | }; |
nkeynes@2 | 77 | |
nkeynes@152 | 78 | #define IDE_STATE_IDLE 0 |
nkeynes@152 | 79 | #define IDE_STATE_CMD_WRITE 1 |
nkeynes@152 | 80 | #define IDE_STATE_PIO_READ 2 |
nkeynes@152 | 81 | #define IDE_STATE_PIO_WRITE 3 |
nkeynes@152 | 82 | #define IDE_STATE_DMA_READ 4 |
nkeynes@152 | 83 | #define IDE_STATE_DMA_WRITE 5 |
nkeynes@152 | 84 | #define IDE_STATE_BUSY 6 |
nkeynes@152 | 85 | |
nkeynes@152 | 86 | /* Flag bits */ |
nkeynes@152 | 87 | #define IDE_STATUS_BSY 0x80 /* Busy */ |
nkeynes@152 | 88 | #define IDE_STATUS_DRDY 0x40 /* Device ready */ |
nkeynes@152 | 89 | #define IDE_STATUS_DMRD 0x20 /* DMA Request */ |
nkeynes@152 | 90 | #define IDE_STATUS_SERV 0x10 |
nkeynes@152 | 91 | #define IDE_STATUS_DRQ 0x08 |
nkeynes@152 | 92 | #define IDE_STATUS_CHK 0x01 /* Check condition (ie error) */ |
nkeynes@2 | 93 | |
nkeynes@149 | 94 | #define IDE_FEAT_DMA 0x01 |
nkeynes@149 | 95 | #define IDE_FEAT_OVL 0x02 |
nkeynes@149 | 96 | |
nkeynes@152 | 97 | #define IDE_COUNT_CD 0x01 /* Command (1)/Data (0) */ |
nkeynes@257 | 98 | #define IDE_COUNT_IO 0x02 /* Input (1)/Output (0) */ |
nkeynes@152 | 99 | #define IDE_COUNT_REL 0x04 /* Release device */ |
nkeynes@149 | 100 | |
nkeynes@149 | 101 | |
nkeynes@2 | 102 | #define IDE_CTL_RESET 0x04 |
nkeynes@2 | 103 | #define IDE_CTL_IRQEN 0x02 /* IRQ enabled when == 0 */ |
nkeynes@2 | 104 | |
nkeynes@240 | 105 | #define IDE_CMD_NOP 0x00 |
nkeynes@2 | 106 | #define IDE_CMD_RESET_DEVICE 0x08 |
nkeynes@2 | 107 | #define IDE_CMD_PACKET 0xA0 |
nkeynes@2 | 108 | #define IDE_CMD_IDENTIFY_PACKET_DEVICE 0xA1 |
nkeynes@2 | 109 | #define IDE_CMD_SERVICE 0xA2 |
nkeynes@2 | 110 | #define IDE_CMD_SET_FEATURE 0xEF |
nkeynes@2 | 111 | |
nkeynes@47 | 112 | #define IDE_FEAT_SET_TRANSFER_MODE 0x03 |
nkeynes@47 | 113 | #define IDE_XFER_PIO 0x00 |
nkeynes@47 | 114 | #define IDE_XFER_PIO_FLOW 0x08 |
nkeynes@47 | 115 | #define IDE_XFER_MULTI_DMA 0x20 |
nkeynes@47 | 116 | #define IDE_XFER_ULTRA_DMA 0x40 |
nkeynes@47 | 117 | |
nkeynes@2 | 118 | extern struct ide_registers idereg; |
nkeynes@2 | 119 | |
nkeynes@2 | 120 | /* Note: control can be written at any time - all other registers are writable |
nkeynes@2 | 121 | * only when ide_can_write_regs() is true |
nkeynes@2 | 122 | */ |
nkeynes@254 | 123 | #define ide_can_write_regs() ((idereg.status&0x80)==0) |
nkeynes@125 | 124 | #define IS_IDE_IRQ_ENABLED() ((idereg.control&0x02)==0) |
nkeynes@2 | 125 | |
nkeynes@2 | 126 | |
nkeynes@2 | 127 | uint16_t ide_read_data_pio(void); |
nkeynes@152 | 128 | void ide_write_data_pio( uint16_t value ); |
nkeynes@152 | 129 | uint32_t ide_read_data_dma( uint32_t addr, uint32_t length ); |
nkeynes@125 | 130 | uint8_t ide_read_status(void); |
nkeynes@342 | 131 | uint8_t ide_get_drive_status(void); |
nkeynes@493 | 132 | void ide_write_buffer( unsigned char *data, uint32_t length ); |
nkeynes@2 | 133 | |
nkeynes@2 | 134 | void ide_write_command( uint8_t command ); |
nkeynes@2 | 135 | void ide_write_control( uint8_t value ); |
nkeynes@152 | 136 | |
nkeynes@152 | 137 | void ide_dma_read_req( uint32_t addr, uint32_t length ); |
nkeynes@736 | 138 | |
nkeynes@736 | 139 | #ifdef __cplusplus |
nkeynes@736 | 140 | } |
nkeynes@2 | 141 | #endif |
nkeynes@736 | 142 | |
nkeynes@736 | 143 | #endif /* !lxdream_ide_H */ |
.