1 // license:BSD-3-Clause 2 // copyright-holders:Carl,Olivier Galibert 3 #ifndef MAME_MACHINE_I8271_H 4 #define MAME_MACHINE_I8271_H 5 6 #pragma once 7 8 #include "fdc_pll.h" 9 #include "imagedev/floppy.h" 10 11 class floppy_image_device; 12 13 14 /*************************************************************************** 15 MACROS 16 ***************************************************************************/ 17 18 class i8271_device : public device_t 19 { 20 public: 21 i8271_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 22 intrq_wr_callback()23 auto intrq_wr_callback() { return intrq_cb.bind(); } drq_wr_callback()24 auto drq_wr_callback() { return drq_cb.bind(); } hdl_wr_callback()25 auto hdl_wr_callback() { return hdl_cb.bind(); } opt_wr_callback()26 auto opt_wr_callback() { return opt_cb.bind(); } 27 28 uint8_t read(offs_t offset); 29 void write(offs_t offset, uint8_t data); 30 uint8_t data_r(); 31 void data_w(uint8_t data); 32 33 void ready_w(bool val); 34 35 void set_rate(int rate); // rate in bps, to be used when the fdc is externally frequency-controlled 36 37 void set_ready_line_connected(bool ready); 38 void set_select_lines_connected(bool select); 39 void set_floppies(floppy_connector* f0, floppy_connector* f1); 40 void soft_reset(); 41 42 void map(address_map &map); 43 44 protected: 45 virtual void device_start() override; 46 virtual void device_reset() override; 47 virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; 48 49 private: 50 enum { 51 PHASE_IDLE, PHASE_CMD, PHASE_EXEC, PHASE_RESULT 52 }; 53 54 enum { 55 RR_DEL = 0x20, 56 RR_CT = 0x18, 57 RR_CC = 0x06, 58 59 SR_BSY = 0x80, 60 SR_CF = 0x40, 61 SR_PF = 0x20, 62 SR_RF = 0x10, 63 SR_IRQ = 0x08, 64 SR_DRQ = 0x04 65 }; 66 67 enum { 68 ERR_NONE = 0x00, 69 ERR_SMEQ = 0x02, 70 ERR_SMNE = 0x04, 71 ERR_CLK = 0x08, 72 ERR_DMA = 0x0a, 73 ERR_ICRC = 0x0c, 74 ERR_DCRC = 0x0e, 75 ERR_NR = 0x10, 76 ERR_WP = 0x12, 77 ERR_T0NF = 0x14, 78 ERR_WF = 0x16, 79 ERR_NF = 0x18 80 }; 81 82 enum { 83 // General "doing nothing" state 84 IDLE, 85 86 // Main states 87 RECALIBRATE, 88 SEEK, 89 READ_DATA, 90 WRITE_DATA, 91 FORMAT_TRACK, 92 READ_ID, 93 SCAN_DATA, 94 VERIFY_DATA, 95 96 // Sub-states 97 COMMAND_DONE, 98 99 SEEK_MOVE, 100 SEEK_WAIT_STEP_SIGNAL_TIME, 101 SEEK_WAIT_STEP_SIGNAL_TIME_DONE, 102 SEEK_WAIT_STEP_TIME, 103 SEEK_WAIT_STEP_TIME_DONE, 104 SEEK_DONE, 105 106 HEAD_LOAD_DONE, 107 108 WAIT_INDEX, 109 WAIT_INDEX_DONE, 110 111 SCAN_ID, 112 SCAN_ID_FAILED, 113 114 SECTOR_READ, 115 SECTOR_WRITTEN, 116 TC_DONE, 117 118 TRACK_DONE, 119 120 // Live states 121 SEARCH_ADDRESS_MARK_HEADER, 122 READ_ID_BLOCK, 123 SEARCH_ADDRESS_MARK_DATA, 124 SEARCH_ADDRESS_MARK_DATA_FAILED, 125 READ_SECTOR_DATA, 126 READ_SECTOR_DATA_BYTE, 127 SCAN_SECTOR_DATA_BYTE, 128 VERIFY_SECTOR_DATA_BYTE, 129 130 WRITE_SECTOR_SKIP_GAP2, 131 WRITE_SECTOR_SKIP_GAP2_BYTE, 132 WRITE_SECTOR_DATA, 133 WRITE_SECTOR_DATA_BYTE, 134 135 WRITE_TRACK_PRE_SECTORS, 136 WRITE_TRACK_PRE_SECTORS_BYTE, 137 138 WRITE_TRACK_SECTOR, 139 WRITE_TRACK_SECTOR_BYTE, 140 141 WRITE_TRACK_POST_SECTORS, 142 WRITE_TRACK_POST_SECTORS_BYTE 143 }; 144 145 struct pll_t { 146 attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust; 147 148 attotime write_start_time; 149 attotime write_buffer[32]; 150 int write_position; 151 int freq_hist; 152 153 void set_clock(const attotime &period); 154 void reset(const attotime &when); 155 int get_next_bit(attotime &tm, floppy_image_device *floppy, const attotime &limit); 156 bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit); 157 void start_writing(const attotime &tm); 158 void commit(floppy_image_device *floppy, const attotime &tm); 159 void stop_writing(floppy_image_device *floppy, const attotime &tm); 160 }; 161 162 struct floppy_info { 163 enum { IRQ_NONE, IRQ_POLLED, IRQ_SEEK, IRQ_DONE }; 164 emu_timer *tm; 165 floppy_image_device *dev; 166 int id; 167 int main_state, sub_state; 168 int dir, counter; 169 uint8_t pcn, badtrack[2]; 170 bool live, index, ready; 171 }; 172 173 struct live_info { 174 enum { PT_NONE, PT_CRC_1, PT_CRC_2 }; 175 176 attotime tm; 177 int state, next_state; 178 floppy_info *fi; 179 uint16_t shift_reg; 180 uint16_t crc; 181 int bit_counter, byte_counter, previous_type; 182 bool data_separator_phase, data_bit_context; 183 uint8_t data_reg; 184 uint8_t idbuf[6]; 185 fdc_pll_t pll; 186 }; 187 188 bool ready_connected, select_connected; 189 190 bool external_ready; 191 192 int mode; 193 int main_phase; 194 195 live_info cur_live, checkpoint_live; 196 devcb_write_line intrq_cb, drq_cb, hdl_cb, opt_cb; 197 bool irq, drq, scan_done, scan_match; 198 floppy_info flopi[2]; 199 200 int command_pos, sectors_read, scan_len; 201 uint8_t command[6], dma_data, oport; 202 uint8_t rr, scan_sec, moder; 203 uint8_t precomp, perpmode, scan_cnt[2]; 204 uint8_t srate, hset, icnt, hload; 205 int sector_size; 206 int cur_rate; 207 int idle_icnt; 208 209 static std::string tts(attotime t); 210 std::string ttsn(); 211 212 enum { 213 C_FORMAT_TRACK, 214 C_READ_DATA_SINGLE, 215 C_READ_DATA_MULTI, 216 C_VERIFY_DATA_SINGLE, 217 C_VERIFY_DATA_MULTI, 218 C_WRITE_DATA_SINGLE, 219 C_WRITE_DATA_MULTI, 220 C_READ_ID, 221 C_SEEK, 222 C_READ_DRIVE_STATUS, 223 C_SPECIFY, 224 C_SCAN, 225 C_WRITE_SPECIAL_REGISTER, 226 C_READ_SPECIAL_REGISTER, 227 228 C_INVALID, 229 C_INCOMPLETE 230 }; 231 232 uint8_t sr_r(); 233 uint8_t rr_r(); reset_w(uint8_t data)234 void reset_w(uint8_t data) { if(data == 1) soft_reset(); } 235 void cmd_w(uint8_t data); 236 void param_w(uint8_t data); 237 238 void delay_cycles(emu_timer *tm, int cycles); 239 void set_drq(bool state); 240 void set_irq(bool state); 241 bool get_ready(int fid); 242 243 int calc_sector_size(uint8_t size); 244 245 int check_command(); 246 void start_command(int cmd); 247 void command_end(floppy_info &fi, bool data_completion); 248 249 void recalibrate_start(floppy_info &fi); 250 void seek_start(floppy_info &fi); 251 void seek_continue(floppy_info &fi); 252 253 void read_data_start(floppy_info &fi); 254 void read_data_continue(floppy_info &fi); 255 256 void write_data_start(floppy_info &fi); 257 void write_data_continue(floppy_info &fi); 258 259 void format_track_start(floppy_info &fi); 260 void format_track_continue(floppy_info &fi); 261 262 void read_id_start(floppy_info &fi); 263 void read_id_continue(floppy_info &fi); 264 265 void scan_start(floppy_info &fi); 266 void verify_data_start(floppy_info &fi); 267 268 void general_continue(floppy_info &fi); 269 void index_callback(floppy_image_device *floppy, int state); 270 bool sector_matches() const; 271 272 void live_start(floppy_info &fi, int live_state); 273 void live_abort(); 274 void checkpoint(); 275 void rollback(); 276 void live_delay(int state); 277 void live_sync(); 278 void live_run(attotime limit = attotime::never); 279 void live_write_raw(uint16_t raw); 280 void live_write_fm(uint8_t fm); 281 282 bool read_one_bit(const attotime &limit); 283 bool write_one_bit(const attotime &limit); 284 bool set_output(uint8_t data); 285 bool get_input(uint8_t *data); 286 }; 287 288 DECLARE_DEVICE_TYPE(I8271, i8271_device) 289 290 #endif // MAME_MACHINE_I8271_H 291