src/mess/machine/c1581.c
| r7275 | r7276 | |
| 11 | 11 | |
| 12 | 12 | TODO: |
| 13 | 13 | |
| 14 | | - D81 sector translation |
| 15 | | - WD1770 MO/RDY pin confusion |
| 16 | | - ready signal polarity |
| 17 | 14 | - floppy access |
| 15 | - disk change |
| 18 | 16 | - power LED |
| 19 | 17 | - activity LED |
| 20 | 18 | |
| r7275 | r7276 | |
| 24 | 22 | #include "c1581.h" |
| 25 | 23 | #include "cpu/m6502/m6502.h" |
| 26 | 24 | #include "devices/flopdrv.h" |
| 27 | | #include "formats/basicdsk.h" |
| 25 | #include "formats/d81_dsk.h" |
| 28 | 26 | #include "machine/6526cia.h" |
| 29 | 27 | #include "machine/cbmiec.h" |
| 30 | 28 | #include "machine/wd17xx.h" |
| r7275 | r7276 | |
| 46 | 44 | typedef struct _c1581_t c1581_t; |
| 47 | 45 | struct _c1581_t |
| 48 | 46 | { |
| 49 | | int address; /* device number */ |
| 47 | int address; /* device number */ |
| 50 | 48 | |
| 51 | | int data_out; /* serial data out */ |
| 52 | | int atn_ack; /* attention acknowledge */ |
| 53 | | int ser_dir; /* fast serial direction */ |
| 49 | int data_out; /* serial data out */ |
| 50 | int atn_ack; /* attention acknowledge */ |
| 51 | int ser_dir; /* fast serial direction */ |
| 52 | int sp_out; /* fast serial data out */ |
| 53 | int cnt_out; /* fast serial clock out */ |
| 54 | 54 | |
| 55 | 55 | /* devices */ |
| 56 | 56 | running_device *cpu; |
| r7275 | r7276 | |
| 79 | 79 | return (c1581_config *)device->baseconfig().inline_config; |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | INLINE void set_iec_data(running_device *device) |
| 83 | { |
| 84 | c1581_t *c1581 = get_safe_token(device); |
| 85 | |
| 86 | int atn = cbm_iec_atn_r(c1581->serial_bus); |
| 87 | int data = !c1581->data_out & !(c1581->atn_ack & !atn); |
| 88 | |
| 89 | /* fast serial data */ |
| 90 | if (c1581->ser_dir) data &= c1581->sp_out; |
| 91 | |
| 92 | cbm_iec_data_w(c1581->serial_bus, device, data); |
| 93 | } |
| 94 | |
| 95 | INLINE void set_iec_srq(running_device *device) |
| 96 | { |
| 97 | c1581_t *c1581 = get_safe_token(device); |
| 98 | |
| 99 | int srq = 1; |
| 100 | |
| 101 | /* fast serial clock */ |
| 102 | if (c1581->ser_dir) srq &= c1581->cnt_out; |
| 103 | |
| 104 | cbm_iec_srq_w(c1581->serial_bus, device, srq); |
| 105 | } |
| 106 | |
| 82 | 107 | /*************************************************************************** |
| 83 | 108 | IMPLEMENTATION |
| 84 | 109 | ***************************************************************************/ |
| r7275 | r7276 | |
| 90 | 115 | WRITE_LINE_DEVICE_HANDLER( c1581_iec_atn_w ) |
| 91 | 116 | { |
| 92 | 117 | c1581_t *c1581 = get_safe_token(device); |
| 93 | | int data_out = !c1581->data_out && !(c1581->atn_ack && !state); |
| 94 | 118 | |
| 95 | 119 | mos6526_flag_w(c1581->cia, state); |
| 96 | | |
| 97 | | cbm_iec_data_w(c1581->serial_bus, device, data_out); |
| 120 | set_iec_data(device); |
| 98 | 121 | } |
| 99 | 122 | |
| 100 | 123 | /*------------------------------------------------- |
| r7275 | r7276 | |
| 163 | 186 | mos6526_interface cia_intf |
| 164 | 187 | -------------------------------------------------*/ |
| 165 | 188 | |
| 189 | static WRITE_LINE_DEVICE_HANDLER( cia_irq_w ) |
| 190 | { |
| 191 | c1581_t *c1581 = get_safe_token(device->owner); |
| 192 | |
| 193 | cpu_set_input_line(c1581->cpu, M6502_IRQ_LINE, state); |
| 194 | } |
| 195 | |
| 196 | static WRITE_LINE_DEVICE_HANDLER( cia_cnt_w ) |
| 197 | { |
| 198 | c1581_t *c1581 = get_safe_token(device->owner); |
| 199 | |
| 200 | /* fast serial clock out */ |
| 201 | c1581->cnt_out = state; |
| 202 | set_iec_srq(device->owner); |
| 203 | } |
| 204 | |
| 205 | static WRITE_LINE_DEVICE_HANDLER( cia_sp_w ) |
| 206 | { |
| 207 | c1581_t *c1581 = get_safe_token(device->owner); |
| 208 | |
| 209 | /* fast serial data out */ |
| 210 | c1581->sp_out = state; |
| 211 | set_iec_data(device->owner); |
| 212 | } |
| 213 | |
| 166 | 214 | static READ8_DEVICE_HANDLER( cia_pa_r ) |
| 167 | 215 | { |
| 168 | 216 | /* |
| r7275 | r7276 | |
| 186 | 234 | /* ready */ |
| 187 | 235 | data |= !(floppy_drive_get_flag_state(c1581->image, FLOPPY_DRIVE_READY) == FLOPPY_DRIVE_READY) << 1; |
| 188 | 236 | |
| 189 | | /* serial address */ |
| 237 | /* device number */ |
| 190 | 238 | data |= c1581->address << 3; |
| 191 | 239 | |
| 240 | /* TODO disk change */ |
| 241 | //data |= 0x80; |
| 242 | |
| 192 | 243 | return data; |
| 193 | 244 | } |
| 194 | 245 | |
| r7275 | r7276 | |
| 210 | 261 | */ |
| 211 | 262 | |
| 212 | 263 | c1581_t *c1581 = get_safe_token(device->owner); |
| 213 | | int motor = BIT(data, 2); |
| 214 | 264 | |
| 215 | 265 | /* side 0 */ |
| 216 | 266 | wd17xx_set_side(c1581->wd1770, !BIT(data, 0)); |
| 217 | 267 | |
| 218 | 268 | /* motor */ |
| 269 | int motor = BIT(data, 2); |
| 219 | 270 | floppy_mon_w(c1581->image, motor); |
| 220 | 271 | floppy_drive_set_ready_state(c1581->image, !motor, 1); |
| 221 | 272 | |
| 222 | | /* power led */ |
| 273 | /* TODO power led */ |
| 223 | 274 | |
| 224 | | /* active led */ |
| 225 | | |
| 275 | /* TODO activity led */ |
| 226 | 276 | } |
| 227 | 277 | |
| 228 | 278 | static READ8_DEVICE_HANDLER( cia_pb_r ) |
| r7275 | r7276 | |
| 279 | 329 | |
| 280 | 330 | c1581_t *c1581 = get_safe_token(device->owner); |
| 281 | 331 | |
| 282 | | int data_out = BIT(data, 1); |
| 283 | | int clk_out = BIT(data, 3); |
| 284 | | int atn_ack = BIT(data, 4); |
| 285 | | |
| 286 | 332 | /* data out */ |
| 287 | | int serial_data = !data_out && !(atn_ack && !cbm_iec_atn_r(c1581->serial_bus)); |
| 288 | | cbm_iec_data_w(c1581->serial_bus, device->owner, serial_data); |
| 289 | | c1581->data_out = data_out; |
| 333 | c1581->data_out = BIT(data, 1); |
| 290 | 334 | |
| 291 | 335 | /* clock out */ |
| 292 | | cbm_iec_clk_w(c1581->serial_bus, device->owner, !clk_out); |
| 336 | cbm_iec_clk_w(c1581->serial_bus, device->owner, !BIT(data, 3)); |
| 293 | 337 | |
| 294 | 338 | /* attention acknowledge */ |
| 295 | | c1581->atn_ack = atn_ack; |
| 339 | c1581->atn_ack = BIT(data, 4); |
| 296 | 340 | |
| 297 | 341 | /* fast serial direction */ |
| 298 | 342 | c1581->ser_dir = BIT(data, 5); |
| 299 | | } |
| 300 | 343 | |
| 301 | | static WRITE_LINE_DEVICE_HANDLER( cia_cnt_w ) |
| 302 | | { |
| 303 | | c1581_t *c1581 = get_safe_token(device->owner); |
| 304 | | |
| 305 | | if (c1581->ser_dir) |
| 306 | | { |
| 307 | | /* fast clock out */ |
| 308 | | cbm_iec_srq_w(c1581->serial_bus, device->owner, state); |
| 309 | | } |
| 344 | set_iec_data(device->owner); |
| 345 | set_iec_srq(device->owner); |
| 310 | 346 | } |
| 311 | 347 | |
| 312 | | static WRITE_LINE_DEVICE_HANDLER( cia_sp_w ) |
| 313 | | { |
| 314 | | c1581_t *c1581 = get_safe_token(device->owner); |
| 315 | | |
| 316 | | if (c1581->ser_dir) |
| 317 | | { |
| 318 | | /* fast data out */ |
| 319 | | cbm_iec_data_w(c1581->serial_bus, device->owner, state); |
| 320 | | } |
| 321 | | } |
| 322 | | |
| 323 | 348 | static MOS8520_INTERFACE( cia_intf ) |
| 324 | 349 | { |
| 325 | 350 | XTAL_16MHz/8, |
| 326 | | DEVCB_CPU_INPUT_LINE(M6502_TAG, INPUT_LINE_IRQ0), |
| 351 | // DEVCB_CPU_INPUT_LINE(M6502_TAG, INPUT_LINE_IRQ0), |
| 352 | DEVCB_LINE(cia_irq_w), |
| 327 | 353 | DEVCB_NULL, |
| 328 | 354 | DEVCB_LINE(cia_cnt_w), |
| 329 | 355 | DEVCB_LINE(cia_sp_w), |
| 330 | 356 | DEVCB_HANDLER(cia_pa_r), |
| 331 | 357 | DEVCB_HANDLER(cia_pa_w), |
| 332 | 358 | DEVCB_HANDLER(cia_pb_r), |
| 333 | | DEVCB_HANDLER(cia_pb_w), |
| 359 | DEVCB_HANDLER(cia_pb_w) |
| 334 | 360 | }; |
| 335 | 361 | |
| 336 | 362 | /*------------------------------------------------- |
| r7275 | r7276 | |
| 349 | 375 | -------------------------------------------------*/ |
| 350 | 376 | |
| 351 | 377 | static FLOPPY_OPTIONS_START( c1581 ) |
| 352 | | FLOPPY_OPTION( c1581, "d81", "Commodore 1581 Disk Image", basicdsk_identify_default, basicdsk_construct_default, |
| 353 | | HEADS([2]) |
| 354 | | TRACKS([80]) |
| 355 | | SECTORS([10]) |
| 356 | | SECTOR_LENGTH([512]) |
| 357 | | FIRST_SECTOR_ID([1])) |
| 378 | FLOPPY_OPTION( c1581, "d81", "Commodore 1581 Disk Image", d81_dsk_identify, d81_dsk_construct, NULL ) |
| 358 | 379 | FLOPPY_OPTIONS_END |
| 359 | 380 | |
| 360 | 381 | /*------------------------------------------------- |
| r7275 | r7276 | |
| 447 | 468 | wd17xx_set_density(c1581->wd1770, DEN_MFM_LO); |
| 448 | 469 | |
| 449 | 470 | /* register for state saving */ |
| 471 | state_save_register_device_item(device, 0, c1581->address); |
| 472 | state_save_register_device_item(device, 0, c1581->data_out); |
| 473 | state_save_register_device_item(device, 0, c1581->atn_ack); |
| 474 | state_save_register_device_item(device, 0, c1581->ser_dir); |
| 475 | state_save_register_device_item(device, 0, c1581->sp_out); |
| 476 | state_save_register_device_item(device, 0, c1581->cnt_out); |
| 450 | 477 | } |
| 451 | 478 | |
| 452 | 479 | /*------------------------------------------------- |
src/mess/formats/d81_dsk.c
| r0 | r7276 | |
| 1 | /*********************************************************************
|
| 2 | |
| 3 | formats/d81_dsk.c
|
| 4 | |
| 5 | Floppy format code for Commodore 1581 disk images
|
| 6 | |
| 7 | *********************************************************************/
|
| 8 | |
| 9 | #include "emu.h"
|
| 10 | #include "formats/basicdsk.h"
|
| 11 | |
| 12 | /***************************************************************************
|
| 13 | PARAMETERS
|
| 14 | ***************************************************************************/
|
| 15 | |
| 16 | #define LOG 0
|
| 17 | |
| 18 | #define D81_SIZE 819200
|
| 19 | |
| 20 | /***************************************************************************
|
| 21 | IMPLEMENTATION
|
| 22 | ***************************************************************************/
|
| 23 | |
| 24 | /*-------------------------------------------------
|
| 25 | d81_translate_offset - translates the
|
| 26 | physical offset to a logical offset within
|
| 27 | the disk image
|
| 28 | -------------------------------------------------*/
|
| 29 | |
| 30 | /*
|
| 31 | |
| 32 | file offset | CBM logical | drive physical | specials
|
| 33 | decimal sedecimal | track/sector | cyl head sec offs |
|
| 34 | ------------------+--------------+-------------------+--------------
|
| 35 | 0 0x000000 | 01;00 | 00;01;01 | first block
|
| 36 | 256 0x000100 | 01;01 | 00;01;01 +256 |
|
| 37 | . . | . | . . |
|
| 38 | 4864 0x001300 | 01;19 | 00;01;10 +256 |
|
| 39 | 5120 0x001400 | 01;20 | 00;00;01 |
|
| 40 | . . | . | . . |
|
| 41 | 9984 0x002700 | 01;39 | 00;00;10 +256 |
|
| 42 | 10240 0x002800 | 02;00 | 01;01;01 |
|
| 43 | . . | . | . . |
|
| 44 | 15360 0x003C00 | 02;20 | 01;00;01 |
|
| 45 | . . | . | . . |
|
| 46 | 20480 0x005000 | 03;00 | 02;01;01 |
|
| 47 | . . | . | . . |
|
| 48 | . . | . | . . |
|
| 49 | 30729 0x007800 | 04;00 | 03;01;01 |
|
| 50 | . . | . | . . |
|
| 51 | . . | . | . . |
|
| 52 | . . | . | . . |
|
| 53 | 399360 0x061800 | 40;00 | 39;01;01 | disk header
|
| 54 | 399616 0x061900 | 40;01 | 39;01;01 +256 | 1st BAM block
|
| 55 | 399872 0x061A00 | 40;02 | 39;01;02 | 2nd BAM block
|
| 56 | 400128 0x061B00 | 40;03 | 39;01;02 +256 | 1st dir block
|
| 57 | . . | . | . . |
|
| 58 | 409600 0x064000 | 41;00 | 40;01;01 |
|
| 59 | . . | . | . . |
|
| 60 | . . | . | . . |
|
| 61 | . . | . | . . |
|
| 62 | 808960 0x0C5800 | 80;00 | 79;01;01 |
|
| 63 | . . | . | . . |
|
| 64 | 813824 0x0C6B00 | 80;19 | 79;01;10 +256 |
|
| 65 | 814080 0x0C6C00 | 80;20 | 79;00;01 |
|
| 66 | . . | . | . . |
|
| 67 | 818688 0x0C7E00 | 80;38 | 79;00;10 |
|
| 68 | 818944 0x0C7F00 | 80;39 | 79;00;10 +256 | last block
|
| 69 | |
| 70 | */
|
| 71 | |
| 72 | UINT64 d81_translate_offset(floppy_image *floppy, const struct basicdsk_geometry *geom, int track, int head, int sector)
|
| 73 | {
|
| 74 | UINT64 offset = ((track * 20) + (!head * 10) + (sector - 1)) * 512;
|
| 75 | |
| 76 | if (LOG) logerror("D81 offset %06x: track %u head %u sector %u\n", (UINT32)offset, track, head, sector);
|
| 77 | |
| 78 | return offset;
|
| 79 | }
|
| 80 | |
| 81 | /*-------------------------------------------------
|
| 82 | FLOPPY_IDENTIFY( d81_dsk_identify )
|
| 83 | -------------------------------------------------*/
|
| 84 | |
| 85 | FLOPPY_IDENTIFY( d81_dsk_identify )
|
| 86 | {
|
| 87 | *vote = (floppy_image_size(floppy) == D81_SIZE) ? 100 : 0;
|
| 88 | |
| 89 | return FLOPPY_ERROR_SUCCESS;
|
| 90 | }
|
| 91 | |
| 92 | /*-------------------------------------------------
|
| 93 | FLOPPY_CONSTRUCT( d81_dsk_construct )
|
| 94 | -------------------------------------------------*/
|
| 95 | |
| 96 | FLOPPY_CONSTRUCT( d81_dsk_construct )
|
| 97 | {
|
| 98 | struct basicdsk_geometry geometry;
|
| 99 | |
| 100 | memset(&geometry, 0, sizeof(geometry));
|
| 101 | |
| 102 | geometry.heads = 2;
|
| 103 | geometry.first_sector_id = 1;
|
| 104 | geometry.sector_length = 512;
|
| 105 | geometry.tracks = 80;
|
| 106 | geometry.sectors = 10;
|
| 107 | geometry.translate_offset = d81_translate_offset;
|
| 108 | |
| 109 | return basicdsk_construct(floppy, &geometry);
|
| 110 | }
|