trunk/src/lib/formats/d81_dsk.c
| r19556 | r19557 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | Copyright Olivier Galibert |
| 4 | All rights reserved. |
| 5 | |
| 6 | Redistribution and use in source and binary forms, with or without |
| 7 | modification, are permitted provided that the following conditions are |
| 8 | met: |
| 9 | |
| 10 | * Redistributions of source code must retain the above copyright |
| 11 | notice, this list of conditions and the following disclaimer. |
| 12 | * Redistributions in binary form must reproduce the above copyright |
| 13 | notice, this list of conditions and the following disclaimer in |
| 14 | the documentation and/or other materials provided with the |
| 15 | distribution. |
| 16 | * Neither the name 'MAME' nor the names of its contributors may be |
| 17 | used to endorse or promote products derived from this software |
| 18 | without specific prior written permission. |
| 19 | |
| 20 | THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR |
| 21 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 23 | DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, |
| 24 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 27 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 28 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 29 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 30 | POSSIBILITY OF SUCH DAMAGE. |
| 31 | |
| 32 | ****************************************************************************/ |
| 33 | |
| 1 | 34 | /********************************************************************* |
| 2 | 35 | |
| 3 | 36 | formats/d81_dsk.c |
| r19556 | r19557 | |
| 2 | 35 | |
| 3 | | Floppy format code for Commodore 1581 disk images |
| 36 | Commodore 1581 disk image format |
| 4 | 37 | |
| 5 | 38 | *********************************************************************/ |
| 6 | 39 | |
| 7 | | #include "basicdsk.h" |
| 8 | | #include "d81_dsk.h" |
| 40 | /* |
| 9 | 41 | |
| 10 | | /*************************************************************************** |
| 11 | | PARAMETERS |
| 12 | | ***************************************************************************/ |
| 42 | PER TRACK ORGANIZATION: |
| 13 | 43 | |
| 14 | | #define D81_SIZE 819200 |
| 44 | Hex 4E written as a gap, with 10 sectors of data, with full gaps written for motor speed variation. |
| 15 | 45 | |
| 16 | | /*************************************************************************** |
| 17 | | IMPLEMENTATION |
| 18 | | ***************************************************************************/ |
| 46 | PER SECTOR ORGANIZATION: |
| 19 | 47 | |
| 20 | | /*------------------------------------------------- |
| 21 | | d81_translate_offset - translates the |
| 22 | | physical offset to a logical offset within |
| 23 | | the disk image |
| 24 | | -------------------------------------------------*/ |
| 48 | MFM Encoding |
| 49 | 12 Bytes of Hex 00 |
| 50 | 3 Bytes of Hex A1 (Data Hex A1, Clock Hex 0A) |
| 51 | 1 Byte of Hex FE (ID Address Mark) |
| 52 | 1 Byte (Track Number) |
| 53 | 1 Byte (Side Number) |
| 54 | 1 Byte (Sector Number) |
| 55 | 1 Byte (Sector Length, 02 for 512 Byte Sectors) |
| 56 | 2 Bytes CRC (Cyclic Redundancy Check) |
| 57 | 22 Bytes of Hex 22 |
| 58 | 12 Bytes of Hex 00 |
| 59 | 3 Bytes of Hex A1 (Data Hex A1, Clock Hex 0A) |
| 60 | 1 Byte of Hex FB (Data Address Mark) |
| 61 | 512 Bytes of Data |
| 62 | 2 Bytes of CRC (Cyclic Redundancy Check) |
| 63 | 38 Bytes of Hex 4E |
| 25 | 64 | |
| 26 | | /* |
| 65 | file offset | CBM logical | drive physical | specials |
| 66 | decimal sedecimal | track/sector | cyl head sec offs | |
| 67 | ------------------+--------------+-------------------+-------------- |
| 68 | 0 0x000000 | 01;00 | 00;01;01 | first block |
| 69 | 256 0x000100 | 01;01 | 00;01;01 +256 | |
| 70 | . . | . | . . | |
| 71 | 4864 0x001300 | 01;19 | 00;01;10 +256 | |
| 72 | 5120 0x001400 | 01;20 | 00;00;01 | |
| 73 | . . | . | . . | |
| 74 | 9984 0x002700 | 01;39 | 00;00;10 +256 | |
| 75 | 10240 0x002800 | 02;00 | 01;01;01 | |
| 76 | . . | . | . . | |
| 77 | 15360 0x003C00 | 02;20 | 01;00;01 | |
| 78 | . . | . | . . | |
| 79 | 20480 0x005000 | 03;00 | 02;01;01 | |
| 80 | . . | . | . . | |
| 81 | . . | . | . . | |
| 82 | 30729 0x007800 | 04;00 | 03;01;01 | |
| 83 | . . | . | . . | |
| 84 | . . | . | . . | |
| 85 | . . | . | . . | |
| 86 | 399360 0x061800 | 40;00 | 39;01;01 | disk header |
| 87 | 399616 0x061900 | 40;01 | 39;01;01 +256 | 1st BAM block |
| 88 | 399872 0x061A00 | 40;02 | 39;01;02 | 2nd BAM block |
| 89 | 400128 0x061B00 | 40;03 | 39;01;02 +256 | 1st dir block |
| 90 | . . | . | . . | |
| 91 | 409600 0x064000 | 41;00 | 40;01;01 | |
| 92 | . . | . | . . | |
| 93 | . . | . | . . | |
| 94 | . . | . | . . | |
| 95 | 808960 0x0C5800 | 80;00 | 79;01;01 | |
| 96 | . . | . | . . | |
| 97 | 813824 0x0C6B00 | 80;19 | 79;01;10 +256 | |
| 98 | 814080 0x0C6C00 | 80;20 | 79;00;01 | |
| 99 | . . | . | . . | |
| 100 | 818688 0x0C7E00 | 80;38 | 79;00;10 | |
| 101 | 818944 0x0C7F00 | 80;39 | 79;00;10 +256 | last block |
| 27 | 102 | |
| 28 | | file offset | CBM logical | drive physical | specials |
| 29 | | decimal sedecimal | track/sector | cyl head sec offs | |
| 30 | | ------------------+--------------+-------------------+-------------- |
| 31 | | 0 0x000000 | 01;00 | 00;01;01 | first block |
| 32 | | 256 0x000100 | 01;01 | 00;01;01 +256 | |
| 33 | | . . | . | . . | |
| 34 | | 4864 0x001300 | 01;19 | 00;01;10 +256 | |
| 35 | | 5120 0x001400 | 01;20 | 00;00;01 | |
| 36 | | . . | . | . . | |
| 37 | | 9984 0x002700 | 01;39 | 00;00;10 +256 | |
| 38 | | 10240 0x002800 | 02;00 | 01;01;01 | |
| 39 | | . . | . | . . | |
| 40 | | 15360 0x003C00 | 02;20 | 01;00;01 | |
| 41 | | . . | . | . . | |
| 42 | | 20480 0x005000 | 03;00 | 02;01;01 | |
| 43 | | . . | . | . . | |
| 44 | | . . | . | . . | |
| 45 | | 30729 0x007800 | 04;00 | 03;01;01 | |
| 46 | | . . | . | . . | |
| 47 | | . . | . | . . | |
| 48 | | . . | . | . . | |
| 49 | | 399360 0x061800 | 40;00 | 39;01;01 | disk header |
| 50 | | 399616 0x061900 | 40;01 | 39;01;01 +256 | 1st BAM block |
| 51 | | 399872 0x061A00 | 40;02 | 39;01;02 | 2nd BAM block |
| 52 | | 400128 0x061B00 | 40;03 | 39;01;02 +256 | 1st dir block |
| 53 | | . . | . | . . | |
| 54 | | 409600 0x064000 | 41;00 | 40;01;01 | |
| 55 | | . . | . | . . | |
| 56 | | . . | . | . . | |
| 57 | | . . | . | . . | |
| 58 | | 808960 0x0C5800 | 80;00 | 79;01;01 | |
| 59 | | . . | . | . . | |
| 60 | | 813824 0x0C6B00 | 80;19 | 79;01;10 +256 | |
| 61 | | 814080 0x0C6C00 | 80;20 | 79;00;01 | |
| 62 | | . . | . | . . | |
| 63 | | 818688 0x0C7E00 | 80;38 | 79;00;10 | |
| 64 | | 818944 0x0C7F00 | 80;39 | 79;00;10 +256 | last block |
| 65 | | |
| 66 | 103 | */ |
| 67 | 104 | |
| 68 | | static UINT64 d81_translate_offset(floppy_image_legacy *floppy, const struct basicdsk_geometry *geom, int track, int head, int sector) |
| 105 | #include "emu.h" |
| 106 | #include "formats/d81_dsk.h" |
| 107 | |
| 108 | d81_format::d81_format() : wd177x_format(formats) |
| 69 | 109 | { |
| 70 | | UINT64 offset = (track * 20) + (!head * 10) + sector; |
| 110 | } |
| 71 | 111 | |
| 72 | | return offset; |
| 112 | const char *d81_format::name() const |
| 113 | { |
| 114 | return "d81"; |
| 73 | 115 | } |
| 74 | 116 | |
| 75 | | /*------------------------------------------------- |
| 76 | | FLOPPY_IDENTIFY( d81_dsk_identify ) |
| 77 | | -------------------------------------------------*/ |
| 117 | const char *d81_format::description() const |
| 118 | { |
| 119 | return "Commodore 1581 disk image"; |
| 120 | } |
| 78 | 121 | |
| 79 | | FLOPPY_IDENTIFY( d81_dsk_identify ) |
| 122 | const char *d81_format::extensions() const |
| 80 | 123 | { |
| 81 | | *vote = (floppy_image_size(floppy) == D81_SIZE) ? 100 : 0; |
| 82 | | |
| 83 | | return FLOPPY_ERROR_SUCCESS; |
| 124 | return "d81"; |
| 84 | 125 | } |
| 85 | 126 | |
| 86 | | /*------------------------------------------------- |
| 87 | | FLOPPY_CONSTRUCT( d81_dsk_construct ) |
| 88 | | -------------------------------------------------*/ |
| 127 | // Unverified gap sizes |
| 128 | const d81_format::format d81_format::formats[] = { |
| 129 | { |
| 130 | floppy_image::FF_35, floppy_image::DSDD, |
| 131 | 2000, 10, 80, 2, 512, {}, 1, {}, 32, 22, 35 |
| 132 | }, |
| 133 | {} |
| 134 | }; |
| 89 | 135 | |
| 90 | | /* |
| 91 | | PER TRACK ORGANIZATION: |
| 136 | bool d81_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) |
| 137 | { |
| 138 | int type = find_size(io, form_factor); |
| 139 | if(type == -1) |
| 140 | return false; |
| 92 | 141 | |
| 93 | | Hex 4E written as a gap, with 10 sectors of data, with full gaps written for motor speed variation. |
| 142 | const format &f = formats[type]; |
| 94 | 143 | |
| 95 | | PER SECTOR ORGANIZATION: |
| 144 | floppy_image_format_t::desc_e desc[] = { |
| 145 | /* 00 */ { MFM, 0x4e, f.gap_1 }, |
| 146 | /* 01 */ { SECTOR_LOOP_START, 0, f.sector_count-1 }, |
| 147 | /* 02 */ { MFM, 0x00, 12 }, |
| 148 | /* 03 */ { CRC_CCITT_START, 1 }, |
| 149 | /* 04 */ { RAW, 0x4489, 3 }, |
| 150 | /* 05 */ { MFM, 0xfe, 1 }, |
| 151 | /* 06 */ { TRACK_ID }, |
| 152 | /* 07 */ { HEAD_ID_SWAP }, |
| 153 | /* 08 */ { SECTOR_ID }, |
| 154 | /* 09 */ { SIZE_ID }, |
| 155 | /* 10 */ { CRC_END, 1 }, |
| 156 | /* 11 */ { CRC, 1 }, |
| 157 | /* 12 */ { MFM, 0x4e, f.gap_2 }, |
| 158 | /* 13 */ { MFM, 0x00, 12 }, |
| 159 | /* 14 */ { CRC_CCITT_START, 2 }, |
| 160 | /* 15 */ { RAW, 0x4489, 3 }, |
| 161 | /* 16 */ { MFM, 0xfb, 1 }, |
| 162 | /* 17 */ { SECTOR_DATA, -1 }, |
| 163 | /* 18 */ { CRC_END, 2 }, |
| 164 | /* 19 */ { CRC, 2 }, |
| 165 | /* 20 */ { MFM, 0x4e, f.gap_3 }, |
| 166 | /* 21 */ { SECTOR_LOOP_END }, |
| 167 | /* 22 */ { MFM, 0x4e, 0 }, |
| 168 | /* 23 */ { RAWBITS, 0x9254, 0 }, |
| 169 | /* 24 */ { END } |
| 170 | }; |
| 96 | 171 | |
| 97 | | MFM Encoding |
| 98 | | 12 Bytes of Hex 00 |
| 99 | | 3 Bytes of Hex A1 (Data Hex A1, Clock Hex 0A) |
| 100 | | 1 Byte of Hex FE (ID Address Mark) |
| 101 | | 1 Byte (Track Number) |
| 102 | | 1 Byte (Side Number) |
| 103 | | 1 Byte (Sector Number) |
| 104 | | 1 Byte (Sector Length, 02 for 512 Byte Sectors) |
| 105 | | 2 Bytes CRC (Cyclic Redundancy Check) |
| 106 | | 22 Bytes of Hex 22 |
| 107 | | 12 Bytes of Hex 00 |
| 108 | | 3 Bytes of Hex A1 (Data Hex A1, Clock Hex 0A) |
| 109 | | 1 Byte of Hex FB (Data Address Mark) |
| 110 | | 512 Bytes of Data |
| 111 | | 2 Bytes of CRC (Cyclic Redundancy Check) |
| 112 | | 38 Bytes of Hex 4E |
| 113 | | */ |
| 172 | int current_size = f.gap_1*16; |
| 173 | if(f.sector_base_size) |
| 174 | current_size += f.sector_base_size * f.sector_count * 16; |
| 175 | else { |
| 176 | for(int j=0; j != f.sector_count; j++) |
| 177 | current_size += f.per_sector_size[j] * 16; |
| 178 | } |
| 179 | current_size += (12+3+1+4+2+f.gap_2+12+3+1+2+f.gap_3) * f.sector_count * 16; |
| 114 | 180 | |
| 115 | | FLOPPY_CONSTRUCT( d81_dsk_construct ) |
| 116 | | { |
| 117 | | struct basicdsk_geometry geometry; |
| 181 | int total_size = 200000000/f.cell_size; |
| 182 | int remaining_size = total_size - current_size; |
| 183 | if(remaining_size < 0) |
| 184 | throw emu_fatalerror("d81_format: Incorrect track layout, max_size=%d, current_size=%d", total_size, current_size); |
| 118 | 185 | |
| 119 | | memset(&geometry, 0, sizeof(geometry)); |
| 186 | // Fixup the end gap |
| 187 | desc[22].p2 = remaining_size / 16; |
| 188 | desc[23].p2 = remaining_size & 15; |
| 189 | desc[23].p1 >>= 16-(remaining_size & 15); |
| 120 | 190 | |
| 121 | | geometry.heads = 2; |
| 122 | | geometry.first_sector_id = 1; |
| 123 | | geometry.sector_length = 512; |
| 124 | | geometry.tracks = 80; |
| 125 | | geometry.sectors = 10; |
| 126 | | geometry.translate_offset = d81_translate_offset; |
| 191 | int track_size = compute_track_size(f); |
| 127 | 192 | |
| 128 | | return basicdsk_construct(floppy, &geometry); |
| 193 | UINT8 sectdata[40*512]; |
| 194 | desc_s sectors[40]; |
| 195 | build_sector_description(f, sectdata, sectors); |
| 196 | |
| 197 | for(int track=0; track < f.track_count; track++) |
| 198 | for(int head=0; head < f.head_count; head++) { |
| 199 | io_generic_read(io, sectdata, (track*f.head_count + !head)*track_size, track_size); |
| 200 | generate_track(desc, track, head, sectors, f.sector_count, total_size, image); |
| 201 | } |
| 202 | |
| 203 | image->set_variant(f.variant); |
| 204 | |
| 205 | return true; |
| 129 | 206 | } |
| 207 | |
| 208 | const floppy_format_type FLOPPY_D81_FORMAT = &floppy_image_format_creator<d81_format>; |
trunk/src/mess/machine/c1581.c
| r19556 | r19557 | |
| 7 | 7 | |
| 8 | 8 | **********************************************************************/ |
| 9 | 9 | |
| 10 | /* |
| 11 | |
| 12 | TODO: |
| 13 | |
| 14 | - wd_fdc drops the busy bit too soon, c1581 aborts reading the sector ID after the first CRC byte @CD17 |
| 15 | |
| 16 | */ |
| 17 | |
| 10 | 18 | #include "c1581.h" |
| 11 | 19 | |
| 12 | 20 | |
| r19556 | r19557 | |
| 15 | 23 | // MACROS / CONSTANTS |
| 16 | 24 | //************************************************************************** |
| 17 | 25 | |
| 18 | | #define M6502_TAG "u1" |
| 19 | | #define M8520_TAG "u5" |
| 20 | | #define WD1770_TAG "u4" |
| 26 | #define M6502_TAG "u1" |
| 27 | #define M8520_TAG "u5" |
| 28 | #define WD1772_TAG "u4" |
| 21 | 29 | |
| 22 | 30 | |
| 23 | 31 | enum |
| r19556 | r19557 | |
| 64 | 72 | |
| 65 | 73 | ROM_START( c1581 ) |
| 66 | 74 | ROM_REGION( 0x8000, M6502_TAG, 0 ) |
| 67 | | ROM_DEFAULT_BIOS("r2") |
| 68 | | ROM_SYSTEM_BIOS( 0, "beta", "Beta" ) |
| 69 | | ROMX_LOAD( "beta.u2", 0x0000, 0x8000, CRC(ecc223cd) SHA1(a331d0d46ead1f0275b4ca594f87c6694d9d9594), ROM_BIOS(1) ) |
| 70 | | ROM_SYSTEM_BIOS( 1, "r1", "Revision 1" ) |
| 71 | | ROMX_LOAD( "318045-01.u2", 0x0000, 0x8000, CRC(113af078) SHA1(3fc088349ab83e8f5948b7670c866a3c954e6164), ROM_BIOS(2) ) |
| 72 | | ROM_SYSTEM_BIOS( 2, "r2", "Revision 2" ) |
| 73 | | ROMX_LOAD( "318045-02.u2", 0x0000, 0x8000, CRC(a9011b84) SHA1(01228eae6f066bd9b7b2b6a7fa3f667e41dad393), ROM_BIOS(3) ) |
| 75 | ROM_DEFAULT_BIOS("r1") |
| 76 | ROM_SYSTEM_BIOS( 0, "beta", "Beta" ) |
| 77 | ROMX_LOAD( "beta.u2", 0x0000, 0x8000, CRC(ecc223cd) SHA1(a331d0d46ead1f0275b4ca594f87c6694d9d9594), ROM_BIOS(1) ) |
| 78 | ROM_SYSTEM_BIOS( 1, "r1", "Revision 1" ) |
| 79 | ROMX_LOAD( "318045-01.u2", 0x0000, 0x8000, CRC(113af078) SHA1(3fc088349ab83e8f5948b7670c866a3c954e6164), ROM_BIOS(2) ) |
| 80 | ROM_SYSTEM_BIOS( 2, "r2", "Revision 2" ) |
| 81 | ROMX_LOAD( "318045-02.u2", 0x0000, 0x8000, CRC(a9011b84) SHA1(01228eae6f066bd9b7b2b6a7fa3f667e41dad393), ROM_BIOS(3) ) |
| 74 | 82 | ROM_SYSTEM_BIOS( 3, "jiffydos", "JiffyDOS v6.01" ) |
| 75 | 83 | ROMX_LOAD( "jiffydos 1581.u2", 0x0000, 0x8000, CRC(98873d0f) SHA1(65bbf2be7bcd5bdcbff609d6c66471ffb9d04bfe), ROM_BIOS(4) ) |
| 76 | 84 | ROM_END |
| r19556 | r19557 | |
| 82 | 90 | |
| 83 | 91 | ROM_START( c1563 ) |
| 84 | 92 | ROM_REGION( 0x8000, M6502_TAG, 0 ) |
| 85 | | ROM_LOAD( "1563-rom.bin", 0x0000, 0x8000, CRC(1d184687) SHA1(2c5111a9c15be7b7955f6c8775fea25ec10c0ca0) ) |
| 93 | ROM_LOAD( "1563-rom.bin", 0x0000, 0x8000, CRC(1d184687) SHA1(2c5111a9c15be7b7955f6c8775fea25ec10c0ca0) ) |
| 86 | 94 | ROM_END |
| 87 | 95 | |
| 88 | 96 | |
| r19556 | r19557 | |
| 109 | 117 | //------------------------------------------------- |
| 110 | 118 | |
| 111 | 119 | static ADDRESS_MAP_START( c1581_mem, AS_PROGRAM, 8, base_c1581_device ) |
| 112 | | AM_RANGE(0x0000, 0x1fff) AM_MIRROR(0x2000) AM_RAM |
| 120 | AM_RANGE(0x0000, 0x1fff) AM_RAM |
| 113 | 121 | AM_RANGE(0x4000, 0x400f) AM_MIRROR(0x1ff0) AM_DEVREADWRITE(M8520_TAG, mos8520_device, read, write) |
| 114 | | AM_RANGE(0x6000, 0x6003) AM_MIRROR(0x1ffc) AM_DEVREADWRITE_LEGACY(WD1770_TAG, wd17xx_r, wd17xx_w) |
| 122 | AM_RANGE(0x6000, 0x6003) AM_MIRROR(0x1ffc) AM_DEVREADWRITE(WD1772_TAG, wd1772_t, read, write) |
| 115 | 123 | AM_RANGE(0x8000, 0xffff) AM_ROM AM_REGION(M6502_TAG, 0) |
| 116 | 124 | ADDRESS_MAP_END |
| 117 | 125 | |
| r19556 | r19557 | |
| 122 | 130 | |
| 123 | 131 | WRITE_LINE_MEMBER( base_c1581_device::cnt_w ) |
| 124 | 132 | { |
| 125 | | // fast serial clock out |
| 126 | 133 | m_cnt_out = state; |
| 127 | 134 | |
| 128 | | set_iec_srq(); |
| 135 | update_iec(); |
| 129 | 136 | } |
| 130 | 137 | |
| 131 | 138 | WRITE_LINE_MEMBER( base_c1581_device::sp_w ) |
| 132 | 139 | { |
| 133 | | // fast serial data out |
| 134 | 140 | m_sp_out = state; |
| 135 | 141 | |
| 136 | | set_iec_data(); |
| 142 | update_iec(); |
| 137 | 143 | } |
| 138 | 144 | |
| 139 | 145 | READ8_MEMBER( base_c1581_device::cia_pa_r ) |
| 140 | 146 | { |
| 141 | 147 | /* |
| 142 | 148 | |
| 143 | | bit description |
| 149 | bit description |
| 144 | 150 | |
| 145 | | PA0 |
| 146 | | PA1 /RDY |
| 147 | | PA2 |
| 148 | | PA3 DEV# SEL (SW1) |
| 149 | | PA4 DEV# SEL (SW1) |
| 150 | | PA5 |
| 151 | | PA6 |
| 152 | | PA7 /DISK CHNG |
| 151 | PA0 |
| 152 | PA1 /RDY |
| 153 | PA2 |
| 154 | PA3 DEV# SEL (SW1) |
| 155 | PA4 DEV# SEL (SW1) |
| 156 | PA5 |
| 157 | PA6 |
| 158 | PA7 /DISK CHNG |
| 153 | 159 | |
| 154 | | */ |
| 160 | */ |
| 155 | 161 | |
| 156 | 162 | UINT8 data = 0; |
| 157 | 163 | |
| 158 | 164 | // ready |
| 159 | | data |= !(floppy_drive_get_flag_state(m_image, FLOPPY_DRIVE_READY) == FLOPPY_DRIVE_READY) << 1; |
| 165 | data |= !m_floppy->ready_r() << 1; |
| 160 | 166 | |
| 161 | 167 | // device number |
| 162 | 168 | data |= (m_address - 8) << 3; |
| 163 | 169 | |
| 164 | 170 | // disk change |
| 165 | | data |= floppy_dskchg_r(m_image) << 7; |
| 171 | data |= m_floppy->dskchg_r() << 7; |
| 166 | 172 | |
| 167 | 173 | return data; |
| 168 | 174 | } |
| r19556 | r19557 | |
| 171 | 177 | { |
| 172 | 178 | /* |
| 173 | 179 | |
| 174 | | bit description |
| 180 | bit description |
| 175 | 181 | |
| 176 | | PA0 SIDE0 |
| 177 | | PA1 |
| 178 | | PA2 /MOTOR |
| 179 | | PA3 |
| 180 | | PA4 |
| 181 | | PA5 POWER LED |
| 182 | | PA6 ACT LED |
| 183 | | PA7 |
| 182 | PA0 SIDE0 |
| 183 | PA1 |
| 184 | PA2 /MOTOR |
| 185 | PA3 |
| 186 | PA4 |
| 187 | PA5 POWER LED |
| 188 | PA6 ACT LED |
| 189 | PA7 |
| 184 | 190 | |
| 185 | | */ |
| 191 | */ |
| 186 | 192 | |
| 187 | | // side 0 |
| 188 | | wd17xx_set_side(m_fdc, !BIT(data, 0)); |
| 193 | // side select |
| 194 | m_floppy->ss_w(BIT(data, 0)); |
| 189 | 195 | |
| 190 | 196 | // motor |
| 191 | | int motor = BIT(data, 2); |
| 192 | | floppy_mon_w(m_image, motor); |
| 193 | | floppy_drive_set_ready_state(m_image, !motor, 1); |
| 197 | m_floppy->mon_w(BIT(data, 2)); |
| 194 | 198 | |
| 195 | 199 | // power led |
| 196 | 200 | output_set_led_value(LED_POWER, BIT(data, 5)); |
| r19556 | r19557 | |
| 203 | 207 | { |
| 204 | 208 | /* |
| 205 | 209 | |
| 206 | | bit description |
| 210 | bit description |
| 207 | 211 | |
| 208 | | PB0 DATA IN |
| 209 | | PB1 |
| 210 | | PB2 CLK IN |
| 211 | | PB3 |
| 212 | | PB4 |
| 213 | | PB5 |
| 214 | | PB6 /WPRT |
| 215 | | PB7 ATN IN |
| 212 | PB0 DATA IN |
| 213 | PB1 |
| 214 | PB2 CLK IN |
| 215 | PB3 |
| 216 | PB4 |
| 217 | PB5 |
| 218 | PB6 /WPRT |
| 219 | PB7 ATN IN |
| 216 | 220 | |
| 217 | | */ |
| 221 | */ |
| 218 | 222 | |
| 219 | 223 | UINT8 data = 0; |
| 220 | 224 | |
| r19556 | r19557 | |
| 225 | 229 | data |= !m_bus->clk_r() << 2; |
| 226 | 230 | |
| 227 | 231 | // write protect |
| 228 | | data |= !floppy_wpt_r(m_image) << 6; |
| 232 | data |= !m_floppy->wpt_r() << 6; |
| 229 | 233 | |
| 230 | 234 | // attention in |
| 231 | 235 | data |= !m_bus->atn_r() << 7; |
| r19556 | r19557 | |
| 237 | 241 | { |
| 238 | 242 | /* |
| 239 | 243 | |
| 240 | | bit description |
| 244 | bit description |
| 241 | 245 | |
| 242 | | PB0 |
| 243 | | PB1 DATA OUT |
| 244 | | PB2 |
| 245 | | PB3 CLK OUT |
| 246 | | PB4 ATN ACK |
| 247 | | PB5 FAST SER DIR |
| 248 | | PB6 |
| 249 | | PB7 |
| 246 | PB0 |
| 247 | PB1 DATA OUT |
| 248 | PB2 |
| 249 | PB3 CLK OUT |
| 250 | PB4 ATN ACK |
| 251 | PB5 FAST SER DIR |
| 252 | PB6 |
| 253 | PB7 |
| 250 | 254 | |
| 251 | | */ |
| 255 | */ |
| 252 | 256 | |
| 253 | 257 | // data out |
| 254 | 258 | m_data_out = BIT(data, 1); |
| r19556 | r19557 | |
| 260 | 264 | m_atn_ack = BIT(data, 4); |
| 261 | 265 | |
| 262 | 266 | // fast serial direction |
| 263 | | int fast_ser_dir = BIT(data, 5); |
| 267 | m_fast_ser_dir = BIT(data, 5); |
| 264 | 268 | |
| 265 | | if (m_fast_ser_dir != fast_ser_dir) |
| 266 | | { |
| 267 | | m_fast_ser_dir = fast_ser_dir; |
| 268 | | |
| 269 | | set_iec_data(); |
| 270 | | set_iec_srq(); |
| 271 | | |
| 272 | | m_cia->cnt_w(m_fast_ser_dir || m_bus->srq_r()); |
| 273 | | m_cia->sp_w(m_fast_ser_dir || m_bus->data_r()); |
| 274 | | } |
| 269 | update_iec(); |
| 275 | 270 | } |
| 276 | 271 | |
| 277 | 272 | static MOS8520_INTERFACE( cia_intf ) |
| r19556 | r19557 | |
| 288 | 283 | |
| 289 | 284 | |
| 290 | 285 | //------------------------------------------------- |
| 291 | | // wd17xx_interface fdc_intf |
| 286 | // SLOT_INTERFACE( c1581_floppies ) |
| 292 | 287 | //------------------------------------------------- |
| 293 | 288 | |
| 294 | | static const wd17xx_interface fdc_intf = |
| 295 | | { |
| 296 | | DEVCB_LINE_GND, |
| 297 | | DEVCB_NULL, |
| 298 | | DEVCB_NULL, |
| 299 | | { FLOPPY_0, NULL, NULL, NULL } |
| 300 | | }; |
| 289 | static SLOT_INTERFACE_START( c1581_floppies ) |
| 290 | SLOT_INTERFACE( "35dd", FLOPPY_35_DD ) // Chinon F-354-E |
| 291 | SLOT_INTERFACE_END |
| 301 | 292 | |
| 302 | 293 | |
| 303 | 294 | //------------------------------------------------- |
| 304 | | // LEGACY_FLOPPY_OPTIONS( c1581 ) |
| 295 | // FLOPPY_FORMATS( c1581_device::floppy_formats ) |
| 305 | 296 | //------------------------------------------------- |
| 306 | 297 | |
| 307 | | static LEGACY_FLOPPY_OPTIONS_START( c1581 ) |
| 308 | | LEGACY_FLOPPY_OPTION( c1581, "d81", "Commodore 1581 Disk Image", d81_dsk_identify, d81_dsk_construct, NULL, NULL ) |
| 309 | | LEGACY_FLOPPY_OPTIONS_END |
| 298 | FLOPPY_FORMATS_MEMBER( base_c1581_device::floppy_formats ) |
| 299 | FLOPPY_D81_FORMAT |
| 300 | FLOPPY_FORMATS_END |
| 310 | 301 | |
| 311 | 302 | |
| 312 | 303 | //------------------------------------------------- |
| 313 | | // floppy_interface c1581_floppy_interface |
| 314 | | //------------------------------------------------- |
| 315 | | |
| 316 | | static const floppy_interface c1581_floppy_interface = |
| 317 | | { |
| 318 | | DEVCB_NULL, |
| 319 | | DEVCB_NULL, |
| 320 | | DEVCB_NULL, |
| 321 | | DEVCB_NULL, |
| 322 | | DEVCB_NULL, |
| 323 | | FLOPPY_STANDARD_3_5_DSDD, |
| 324 | | LEGACY_FLOPPY_OPTIONS_NAME(c1581), |
| 325 | | "floppy_3_5", |
| 326 | | NULL |
| 327 | | }; |
| 328 | | |
| 329 | | |
| 330 | | //------------------------------------------------- |
| 331 | 304 | // MACHINE_DRIVER( c1581 ) |
| 332 | 305 | //------------------------------------------------- |
| 333 | 306 | |
| r19556 | r19557 | |
| 336 | 309 | MCFG_CPU_PROGRAM_MAP(c1581_mem) |
| 337 | 310 | |
| 338 | 311 | MCFG_MOS8520_ADD(M8520_TAG, XTAL_16MHz/8, 0, cia_intf) |
| 339 | | MCFG_WD1770_ADD(WD1770_TAG, /*XTAL_16MHz/2,*/ fdc_intf) |
| 312 | MCFG_WD1772x_ADD(WD1772_TAG, XTAL_16MHz/2) |
| 340 | 313 | |
| 341 | | MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, c1581_floppy_interface) |
| 314 | MCFG_FLOPPY_DRIVE_ADD(WD1772_TAG":0", c1581_floppies, "35dd", 0, base_c1581_device::floppy_formats) |
| 342 | 315 | MACHINE_CONFIG_END |
| 343 | 316 | |
| 344 | 317 | |
| r19556 | r19557 | |
| 355 | 328 | |
| 356 | 329 | |
| 357 | 330 | //************************************************************************** |
| 358 | | // INLINE HELPERS |
| 359 | | //************************************************************************** |
| 360 | | |
| 361 | | //------------------------------------------------- |
| 362 | | // base_c1581_device - constructor |
| 363 | | //------------------------------------------------- |
| 364 | | |
| 365 | | inline void base_c1581_device::set_iec_data() |
| 366 | | { |
| 367 | | int atn = m_bus->atn_r(); |
| 368 | | int data = !m_data_out && !(m_atn_ack && !atn); |
| 369 | | |
| 370 | | // fast serial data |
| 371 | | if (m_fast_ser_dir) data &= m_sp_out; |
| 372 | | |
| 373 | | m_bus->data_w(this, data); |
| 374 | | } |
| 375 | | |
| 376 | | |
| 377 | | //------------------------------------------------- |
| 378 | | // base_c1581_device - constructor |
| 379 | | //------------------------------------------------- |
| 380 | | |
| 381 | | inline void base_c1581_device::set_iec_srq() |
| 382 | | { |
| 383 | | int srq = 1; |
| 384 | | |
| 385 | | // fast serial clock |
| 386 | | if (m_fast_ser_dir) srq &= m_cnt_out; |
| 387 | | |
| 388 | | m_bus->srq_w(this, srq); |
| 389 | | } |
| 390 | | |
| 391 | | |
| 392 | | |
| 393 | | //************************************************************************** |
| 394 | 331 | // LIVE DEVICE |
| 395 | 332 | //************************************************************************** |
| 396 | 333 | |
| r19556 | r19557 | |
| 399 | 336 | //------------------------------------------------- |
| 400 | 337 | |
| 401 | 338 | base_c1581_device::base_c1581_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant) |
| 402 | | : device_t(mconfig, type, name, tag, owner, clock), |
| 403 | | device_cbm_iec_interface(mconfig, *this), |
| 404 | | m_maincpu(*this, M6502_TAG), |
| 405 | | m_cia(*this, M8520_TAG), |
| 406 | | m_fdc(*this, WD1770_TAG), |
| 407 | | m_image(*this, FLOPPY_0), |
| 408 | | m_variant(variant) |
| 339 | : device_t(mconfig, type, name, tag, owner, clock), |
| 340 | device_cbm_iec_interface(mconfig, *this), |
| 341 | m_maincpu(*this, M6502_TAG), |
| 342 | m_cia(*this, M8520_TAG), |
| 343 | m_fdc(*this, WD1772_TAG), |
| 344 | m_floppy(*this, WD1772_TAG":0:35dd"), |
| 345 | m_data_out(0), |
| 346 | m_atn_ack(0), |
| 347 | m_fast_ser_dir(0), |
| 348 | m_sp_out(1), |
| 349 | m_cnt_out(1), |
| 350 | m_variant(variant) |
| 409 | 351 | { |
| 410 | 352 | } |
| 411 | 353 | |
| r19556 | r19557 | |
| 447 | 389 | |
| 448 | 390 | void base_c1581_device::device_reset() |
| 449 | 391 | { |
| 450 | | m_maincpu->reset(); |
| 392 | m_maincpu->reset(); |
| 451 | 393 | |
| 452 | | m_cia->reset(); |
| 394 | m_cia->reset(); |
| 395 | m_fdc->reset(); |
| 453 | 396 | |
| 454 | | wd17xx_mr_w(m_fdc, 0); |
| 455 | | wd17xx_mr_w(m_fdc, 1); |
| 397 | m_fdc->set_floppy(m_floppy); |
| 398 | m_fdc->dden_w(0); |
| 456 | 399 | |
| 457 | 400 | m_sp_out = 1; |
| 458 | 401 | m_cnt_out = 1; |
| 402 | |
| 403 | update_iec(); |
| 459 | 404 | } |
| 460 | 405 | |
| 461 | 406 | |
| r19556 | r19557 | |
| 465 | 410 | |
| 466 | 411 | void base_c1581_device::cbm_iec_srq(int state) |
| 467 | 412 | { |
| 468 | | m_cia->cnt_w(m_fast_ser_dir || state); |
| 413 | update_iec(); |
| 469 | 414 | } |
| 470 | 415 | |
| 471 | 416 | |
| r19556 | r19557 | |
| 475 | 420 | |
| 476 | 421 | void base_c1581_device::cbm_iec_atn(int state) |
| 477 | 422 | { |
| 478 | | m_cia->flag_w(state); |
| 479 | | |
| 480 | | set_iec_data(); |
| 423 | update_iec(); |
| 481 | 424 | } |
| 482 | 425 | |
| 483 | 426 | |
| r19556 | r19557 | |
| 487 | 430 | |
| 488 | 431 | void base_c1581_device::cbm_iec_data(int state) |
| 489 | 432 | { |
| 490 | | m_cia->sp_w(m_fast_ser_dir || state); |
| 433 | update_iec(); |
| 491 | 434 | } |
| 492 | 435 | |
| 493 | 436 | |
| r19556 | r19557 | |
| 502 | 445 | device_reset(); |
| 503 | 446 | } |
| 504 | 447 | } |
| 448 | |
| 449 | |
| 450 | //------------------------------------------------- |
| 451 | // update_iec - |
| 452 | //------------------------------------------------- |
| 453 | |
| 454 | void base_c1581_device::update_iec() |
| 455 | { |
| 456 | int atn = m_bus->atn_r(); |
| 457 | |
| 458 | m_cia->cnt_w(m_fast_ser_dir || m_bus->srq_r()); |
| 459 | m_cia->sp_w(m_fast_ser_dir || m_bus->data_r()); |
| 460 | m_cia->flag_w(atn); |
| 461 | |
| 462 | // serial data |
| 463 | int data = !m_data_out && !(m_atn_ack && !atn); |
| 464 | |
| 465 | if (m_fast_ser_dir) data &= m_sp_out; |
| 466 | |
| 467 | m_bus->data_w(this, data); |
| 468 | |
| 469 | // fast clock |
| 470 | int srq = 1; |
| 471 | |
| 472 | if (m_fast_ser_dir) srq &= m_cnt_out; |
| 473 | |
| 474 | m_bus->srq_w(this, srq); |
| 475 | } |
trunk/src/mess/machine/c1581.h
| r19556 | r19557 | |
| 15 | 15 | |
| 16 | 16 | #include "emu.h" |
| 17 | 17 | #include "cpu/m6502/m6502.h" |
| 18 | | #include "imagedev/flopdrv.h" |
| 19 | 18 | #include "formats/d81_dsk.h" |
| 20 | 19 | #include "machine/cbmiec.h" |
| 21 | 20 | #include "machine/mos6526.h" |
| 22 | | #include "machine/wd17xx.h" |
| 21 | #include "machine/wd_fdc.h" |
| 23 | 22 | |
| 24 | 23 | |
| 25 | 24 | |
| r19556 | r19557 | |
| 27 | 26 | // MACROS / CONSTANTS |
| 28 | 27 | //************************************************************************** |
| 29 | 28 | |
| 30 | | #define C1581_TAG "c1581" |
| 29 | #define C1581_TAG "c1581" |
| 31 | 30 | |
| 32 | 31 | |
| 33 | 32 | |
| r19556 | r19557 | |
| 38 | 37 | // ======================> base_c1581_device |
| 39 | 38 | |
| 40 | 39 | class base_c1581_device : public device_t, |
| 41 | | public device_cbm_iec_interface |
| 40 | public device_cbm_iec_interface |
| 42 | 41 | { |
| 43 | 42 | |
| 44 | 43 | public: |
| 45 | | // construction/destruction |
| 46 | | base_c1581_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant); |
| 44 | // construction/destruction |
| 45 | base_c1581_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT32 variant); |
| 47 | 46 | |
| 48 | 47 | enum |
| 49 | 48 | { |
| r19556 | r19557 | |
| 63 | 62 | DECLARE_READ8_MEMBER( cia_pb_r ); |
| 64 | 63 | DECLARE_WRITE8_MEMBER( cia_pb_w ); |
| 65 | 64 | |
| 65 | DECLARE_FLOPPY_FORMATS( floppy_formats ); |
| 66 | |
| 66 | 67 | protected: |
| 67 | | // device-level overrides |
| 68 | | virtual void device_config_complete(); |
| 69 | | virtual void device_start(); |
| 68 | // device-level overrides |
| 69 | virtual void device_config_complete(); |
| 70 | virtual void device_start(); |
| 70 | 71 | virtual void device_reset(); |
| 71 | 72 | |
| 72 | 73 | // device_cbm_iec_interface overrides |
| r19556 | r19557 | |
| 75 | 76 | virtual void cbm_iec_data(int state); |
| 76 | 77 | virtual void cbm_iec_reset(int state); |
| 77 | 78 | |
| 78 | | inline void set_iec_data(); |
| 79 | | inline void set_iec_srq(); |
| 79 | void update_iec(); |
| 80 | 80 | |
| 81 | 81 | required_device<cpu_device> m_maincpu; |
| 82 | 82 | required_device<mos6526_device> m_cia; |
| 83 | | required_device<wd1770_device> m_fdc; |
| 84 | | required_device<legacy_floppy_image_device> m_image; |
| 83 | required_device<wd1772_t> m_fdc; |
| 84 | required_device<floppy_image_device> m_floppy; |
| 85 | 85 | |
| 86 | | int m_data_out; // serial data out |
| 87 | | int m_atn_ack; // attention acknowledge |
| 88 | | int m_fast_ser_dir; // fast serial direction |
| 89 | | int m_sp_out; // fast serial data out |
| 90 | | int m_cnt_out; // fast serial clock out |
| 86 | int m_data_out; // serial data out |
| 87 | int m_atn_ack; // attention acknowledge |
| 88 | int m_fast_ser_dir; // fast serial direction |
| 89 | int m_sp_out; // fast serial data out |
| 90 | int m_cnt_out; // fast serial clock out |
| 91 | 91 | |
| 92 | 92 | int m_variant; |
| 93 | 93 | }; |
| r19556 | r19557 | |
| 98 | 98 | class c1563_device : public base_c1581_device |
| 99 | 99 | { |
| 100 | 100 | public: |
| 101 | | // construction/destruction |
| 102 | | c1563_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 101 | // construction/destruction |
| 102 | c1563_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 103 | 103 | }; |
| 104 | 104 | |
| 105 | 105 | |
| r19556 | r19557 | |
| 108 | 108 | class c1581_device : public base_c1581_device |
| 109 | 109 | { |
| 110 | 110 | public: |
| 111 | | // construction/destruction |
| 112 | | c1581_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 111 | // construction/destruction |
| 112 | c1581_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 113 | 113 | }; |
| 114 | 114 | |
| 115 | 115 | |