src/mess/machine/c1551.c
| r7314 | r7315 | |
| 11 | 11 | |
| 12 | 12 | TODO: |
| 13 | 13 | |
| 14 | | - 74 drive not ready |
| 15 | | - move M6510T port handling to cpu core |
| 14 | - byte latched is wrong |
| 15 | - 23 data block checksum error |
| 16 | - activity LED |
| 16 | 17 | |
| 17 | 18 | */ |
| 18 | 19 | |
| r7314 | r7315 | |
| 34 | 35 | #define M6523_0_TAG "u3" |
| 35 | 36 | #define M6523_1_TAG "ci_u2" |
| 36 | 37 | |
| 38 | #define SYNC \ |
| 39 | !(c1551->mode && ((c1551->data & G64_SYNC_MARK) == G64_SYNC_MARK)) |
| 40 | |
| 37 | 41 | /*************************************************************************** |
| 38 | 42 | TYPE DEFINITIONS |
| 39 | 43 | ***************************************************************************/ |
| r7314 | r7315 | |
| 59 | 63 | int bit_pos; /* current bit position within track buffer byte */ |
| 60 | 64 | int bit_count; /* current data byte bit counter */ |
| 61 | 65 | UINT16 data; /* data shift register */ |
| 62 | | UINT8 yb; /* GCR data byte to write */ |
| 66 | UINT8 yb; /* GCR data byte */ |
| 63 | 67 | |
| 64 | 68 | /* signals */ |
| 65 | 69 | int ds; /* density select */ |
| r7314 | r7315 | |
| 67 | 71 | int byte; /* byte ready */ |
| 68 | 72 | int mode; /* mode (0 = write, 1 = read) */ |
| 69 | 73 | |
| 70 | | /* interrupts */ |
| 71 | | int irq; /* NE555 interrupt */ |
| 72 | | |
| 73 | 74 | /* devices */ |
| 74 | 75 | running_device *cpu; |
| 75 | 76 | running_device *tpi0; |
| r7314 | r7315 | |
| 111 | 112 | { |
| 112 | 113 | c1551_t *c1551 = get_safe_token(timer->owner); |
| 113 | 114 | |
| 114 | | c1551->irq = !c1551->irq; |
| 115 | | |
| 116 | | cpu_set_input_line(c1551->cpu, M6502_IRQ_LINE, c1551->irq); |
| 115 | cpu_set_input_line(c1551->cpu, M6502_IRQ_LINE, ASSERT_LINE); |
| 116 | cpu_set_input_line(c1551->cpu, M6502_IRQ_LINE, CLEAR_LINE); |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | /*------------------------------------------------- |
| r7314 | r7315 | |
| 144 | 144 | } |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | | if ((c1551->data & G64_SYNC_MARK) == G64_SYNC_MARK) |
| 147 | if (!SYNC) |
| 148 | 148 | { |
| 149 | 149 | /* SYNC detected */ |
| 150 | 150 | c1551->bit_count = 0; |
| r7314 | r7315 | |
| 156 | 156 | c1551->bit_count = 0; |
| 157 | 157 | byte = 1; |
| 158 | 158 | |
| 159 | | if (!(c1551->data & 0xff)) |
| 159 | c1551->yb = c1551->data & 0xff; |
| 160 | |
| 161 | if (!c1551->yb) |
| 160 | 162 | { |
| 161 | 163 | /* simulate weak bits with randomness */ |
| 162 | | c1551->data = (c1551->data & 0xff00) | (mame_rand(machine) & 0xff); |
| 164 | c1551->yb = mame_rand(machine) & 0xff; |
| 163 | 165 | } |
| 164 | 166 | } |
| 165 | 167 | |
| r7314 | r7315 | |
| 201 | 203 | } |
| 202 | 204 | } |
| 203 | 205 | |
| 204 | | static void step_motor(c1551_t *c1551, int stp) |
| 206 | static void step_motor(c1551_t *c1551, int mtr, int stp) |
| 205 | 207 | { |
| 206 | | if (c1551->stp != stp) |
| 208 | if (mtr && (c1551->stp != stp)) |
| 207 | 209 | { |
| 208 | 210 | int tracks = 0; |
| 209 | 211 | |
| r7314 | r7315 | |
| 228 | 230 | } |
| 229 | 231 | } |
| 230 | 232 | |
| 231 | | static READ8_DEVICE_HANDLER( c1551_port_r ) |
| 233 | static UINT8 c1551_port_r( running_device *device, UINT8 direction ) |
| 232 | 234 | { |
| 233 | 235 | /* |
| 234 | 236 | |
| r7314 | r7315 | |
| 252 | 254 | data |= !floppy_wpt_r(c1551->image) << 4; |
| 253 | 255 | |
| 254 | 256 | /* byte latched */ |
| 255 | | data |= !(c1551->soe && c1551->byte) << 7; |
| 257 | data |= (c1551->soe & c1551->byte) << 7; |
| 256 | 258 | |
| 257 | 259 | return data; |
| 258 | 260 | } |
| r7314 | r7315 | |
| 261 | 263 | c1551_port_w - M6510T port write |
| 262 | 264 | -------------------------------------------------*/ |
| 263 | 265 | |
| 264 | | static WRITE8_DEVICE_HANDLER( c1551_port_w ) |
| 266 | static void c1551_port_w( running_device *device, UINT8 direction, UINT8 data ) |
| 265 | 267 | { |
| 266 | 268 | /* |
| 267 | 269 | |
| r7314 | r7315 | |
| 280 | 282 | |
| 281 | 283 | c1551_t *c1551 = get_safe_token(device->owner); |
| 282 | 284 | |
| 283 | | /* stepper motor */ |
| 284 | | int stp = data & 0x03; |
| 285 | | step_motor(c1551, stp); |
| 286 | | |
| 287 | 285 | /* spindle motor */ |
| 288 | 286 | int mtr = BIT(data, 2); |
| 289 | 287 | spindle_motor(c1551, mtr); |
| 290 | 288 | |
| 289 | /* stepper motor */ |
| 290 | int stp = data & 0x03; |
| 291 | step_motor(c1551, mtr, stp); |
| 292 | |
| 291 | 293 | /* TODO activity LED */ |
| 292 | 294 | |
| 293 | 295 | /* density select */ |
| r7314 | r7315 | |
| 300 | 302 | } |
| 301 | 303 | } |
| 302 | 304 | |
| 305 | static const m6502_interface m6510t_intf = |
| 306 | { |
| 307 | NULL, /* read_indexed_func */ |
| 308 | NULL, /* write_indexed_func */ |
| 309 | c1551_port_r, /* port_read_func */ |
| 310 | c1551_port_w /* port_write_func */ |
| 311 | }; |
| 312 | |
| 303 | 313 | /*------------------------------------------------- |
| 304 | 314 | ADDRESS_MAP( c1551_map ) |
| 305 | 315 | -------------------------------------------------*/ |
| 306 | 316 | |
| 307 | 317 | static ADDRESS_MAP_START( c1551_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 308 | | AM_RANGE(0x0001, 0x0001) AM_DEVREADWRITE(M6510T_TAG, c1551_port_r, c1551_port_w) |
| 309 | | AM_RANGE(0x0002, 0x07ff) AM_MIRROR(0x0800) AM_RAM |
| 318 | AM_RANGE(0x0000, 0x07ff) AM_MIRROR(0x0800) AM_RAM |
| 310 | 319 | AM_RANGE(0x4000, 0x4007) AM_MIRROR(0x3ff8) AM_DEVREADWRITE(M6523_0_TAG, tpi6525_r, tpi6525_w) |
| 311 | 320 | AM_RANGE(0xc000, 0xffff) AM_ROM AM_REGION("c1551", 0) |
| 312 | 321 | ADDRESS_MAP_END |
| r7314 | r7315 | |
| 378 | 387 | |
| 379 | 388 | c1551_t *c1551 = get_safe_token(device->owner); |
| 380 | 389 | |
| 381 | | return c1551->data & 0xff; |
| 390 | return c1551->yb; |
| 382 | 391 | } |
| 383 | 392 | |
| 384 | 393 | static WRITE8_DEVICE_HANDLER( tpi0_pb_w ) |
| r7314 | r7315 | |
| 427 | 436 | data |= c1551->address << 5; |
| 428 | 437 | |
| 429 | 438 | /* SYNC detect line */ |
| 430 | | data |= !(c1551->mode && ((c1551->data & G64_SYNC_MARK) == G64_SYNC_MARK)) << 6; |
| 439 | data |= SYNC << 6; |
| 431 | 440 | |
| 432 | 441 | /* TCBM data valid */ |
| 433 | 442 | data |= c1551->dav << 7; |
| r7314 | r7315 | |
| 644 | 653 | static MACHINE_DRIVER_START( c1551 ) |
| 645 | 654 | MDRV_CPU_ADD(M6510T_TAG, M6510T, XTAL_16MHz/8) |
| 646 | 655 | MDRV_CPU_PROGRAM_MAP(c1551_map) |
| 656 | MDRV_CPU_CONFIG(m6510t_intf) |
| 647 | 657 | |
| 648 | 658 | MDRV_TPI6525_ADD(M6523_0_TAG, tpi0_intf) // 6523 |
| 649 | 659 | MDRV_TPI6525_ADD(M6523_1_TAG, tpi1_intf) // 6523 |
| r7314 | r7315 | |
| 683 | 693 | c1551->tpi1 = device->subdevice(M6523_1_TAG); |
| 684 | 694 | c1551->image = device->subdevice(FLOPPY_0); |
| 685 | 695 | |
| 686 | | /* allocate track buffer */ |
| 687 | | // c1551->track_buffer = auto_alloc_array(device->machine, UINT8, G64_BUFFER_SIZE); |
| 688 | | |
| 689 | 696 | /* allocate data timer */ |
| 690 | 697 | c1551->bit_timer = timer_alloc(device->machine, bit_tick, (void *)device); |
| 691 | 698 | |
| 692 | | /* map TPI1 to main CPU memory space */ |
| 693 | | const address_space *program = cpu_get_address_space(device->machine->firstcpu, ADDRESS_SPACE_PROGRAM); |
| 694 | | memory_install_readwrite8_device_handler(program, c1551->tpi1, 0xfef0, 0xfef7, 0, 0, tpi6525_r, tpi6525_w); |
| 699 | /* map TPI1 to host CPU memory space */ |
| 700 | const address_space *program = cpu_get_address_space(devtag_get_device(device->machine, config->cpu_tag), ADDRESS_SPACE_PROGRAM); |
| 701 | UINT32 start_address = c1551->address ? 0xfec0 : 0xfef0; |
| 695 | 702 | |
| 703 | memory_install_readwrite8_device_handler(program, c1551->tpi1, start_address, start_address + 7, 0, 0, tpi6525_r, tpi6525_w); |
| 704 | |
| 696 | 705 | /* register for state saving */ |
| 697 | | // state_save_register_device_item_pointer(device, 0, c1551->track_buffer, G64_BUFFER_SIZE); |
| 706 | state_save_register_device_item(device, 0, c1551->tcbm_data); |
| 707 | state_save_register_device_item(device, 0, c1551->status); |
| 708 | state_save_register_device_item(device, 0, c1551->dav); |
| 709 | state_save_register_device_item(device, 0, c1551->ack); |
| 710 | state_save_register_device_item(device, 0, c1551->stp); |
| 711 | state_save_register_device_item(device, 0, c1551->mtr); |
| 698 | 712 | state_save_register_device_item(device, 0, c1551->track_len); |
| 699 | 713 | state_save_register_device_item(device, 0, c1551->buffer_pos); |
| 700 | 714 | state_save_register_device_item(device, 0, c1551->bit_pos); |
| 701 | 715 | state_save_register_device_item(device, 0, c1551->bit_count); |
| 702 | 716 | state_save_register_device_item(device, 0, c1551->data); |
| 703 | 717 | state_save_register_device_item(device, 0, c1551->yb); |
| 704 | | state_save_register_device_item(device, 0, c1551->byte); |
| 705 | 718 | state_save_register_device_item(device, 0, c1551->ds); |
| 706 | | state_save_register_device_item(device, 0, c1551->stp); |
| 707 | 719 | state_save_register_device_item(device, 0, c1551->soe); |
| 720 | state_save_register_device_item(device, 0, c1551->byte); |
| 708 | 721 | state_save_register_device_item(device, 0, c1551->mode); |
| 709 | 722 | } |
| 710 | 723 | |