| Previous | 199869 Revisions | Next |
| r18420 Wednesday 10th October, 2012 at 15:33:51 UTC by O. Galibert |
|---|
| (mess) upd765: Modernize [O. Galibert] Remaining TODO list: - take WP into account - test the amstrad, implement its observational format (edsk) using pasti as a start. Or find the legendary amstrad IPFs. Or both. - correct read track, the implementation is completely wrong. See previous for testing, it's only used in protections the check the inter-sector gaps. - shake and bake on the amstrad, protections are the best to find bugs in a fdc - add the scan id commands, but nothing seems to use them - debug the 2.88M formatting which is unreliable. Fix its IDAM/DAM gap size on formatting too (but that's not what's making it unreliable) - test all the systems that were hit, and fix what needs to be fixed. Beware that multiple problems may happen: - upd765 may be wrong - the driver may not be working - the hookup may be wrong/incomplete (bitrate selection and floppy rpm in particular) - the driver may be too limited for the new implementation (the x68k dma device does not handle non-instant dma yet for instance) - report invalid command when appropriate depending on the actual chip emulated - add the russian clones with their real names |
| [src/lib] | lib.mak |
| [src/lib/formats] | a5105_dsk.c a5105_dsk.h apollo_dsk.c apollo_dsk.h bw12_dsk.c bw12_dsk.h d88_dsk.c flopimg.c flopimg.h iq151_dsk.c iq151_dsk.h kc85_dsk.c kc85_dsk.h m5_dsk.c m5_dsk.h mm_dsk.c mm_dsk.h nanos_dsk.c nanos_dsk.h pc_dsk.c pc_dsk.h pyldin_dsk.c pyldin_dsk.h sf7000_dsk.c sf7000_dsk.h upd765_dsk.c upd765_dsk.h |
| [src/mess] | mess.mak |
| [src/mess/drivers] | a5105.c amstr_pc.c amstrad.c apollo.c at.c bebox.c bw12.c compis.c dmv.c elwro800.c genpc.c hec2hrp.c ibmpc.c m5.c microdec.c mikromik.c mz6500.c nanos.c nc.c newbrain.c next.c p8k.c pasopia7.c pc.c pc1512.c pc8801.c pc88va.c pc9801.c pcw.c pcw16.c prof180x.c prof80.c pyl601.c qx10.c sage2.c sg1000.c specpls3.c tandy2k.c wangpc.c x68k.c |
| [src/mess/includes] | amstrad.h apollo.h bebox.h bw12.h compis.h hec2hrp.h m5.h mikromik.h nc.h newbrain.h next.h pc.h pc1512.h pcw.h pcw16.h prof80.h sage2.h sg1000.h tandy2k.h wangpc.h x68k.h |
| [src/mess/machine] | amstrad.c apollo.c bebox.c compis.c fd2000.c fd2000.h genpc.c hec2hrp.c hecdisk2.c iq151_disc2.c iq151_disc2.h isa.h isa_fdc.c isa_fdc.h kc_d004.c kc_d004.h |
| [src/mess/tools/floptool] | main.c |
| r18419 | r18420 | |
|---|---|---|
| 93 | 93 | $(LIBOBJ)/formats/ioprocs.o \ |
| 94 | 94 | $(LIBOBJ)/formats/basicdsk.o \ |
| 95 | 95 | $(LIBOBJ)/formats/a26_cas.o \ |
| 96 | $(LIBOBJ)/formats/a5105_dsk.o \ | |
| 96 | 97 | $(LIBOBJ)/formats/ace_tap.o \ |
| 97 | 98 | $(LIBOBJ)/formats/adam_cas.o \ |
| 98 | 99 | $(LIBOBJ)/formats/ami_dsk.o \ |
| 99 | 100 | $(LIBOBJ)/formats/ap2_dsk.o \ |
| 100 | 101 | $(LIBOBJ)/formats/apf_apt.o \ |
| 101 | 102 | $(LIBOBJ)/formats/apridisk.o \ |
| 103 | $(LIBOBJ)/formats/apollo_dsk.o \ | |
| 102 | 104 | $(LIBOBJ)/formats/ap_dsk35.o \ |
| 103 | 105 | $(LIBOBJ)/formats/atari_dsk.o \ |
| 104 | 106 | $(LIBOBJ)/formats/atarist_dsk.o \ |
| 105 | 107 | $(LIBOBJ)/formats/atom_tap.o \ |
| 108 | $(LIBOBJ)/formats/bw12_dsk.o \ | |
| 106 | 109 | $(LIBOBJ)/formats/cbm_tap.o \ |
| 107 | 110 | $(LIBOBJ)/formats/cgen_cas.o \ |
| 108 | 111 | $(LIBOBJ)/formats/coco_cas.o \ |
| r18419 | r18420 | |
| 127 | 130 | $(LIBOBJ)/formats/gtp_cas.o \ |
| 128 | 131 | $(LIBOBJ)/formats/hect_dsk.o \ |
| 129 | 132 | $(LIBOBJ)/formats/hect_tap.o \ |
| 133 | $(LIBOBJ)/formats/iq151_dsk.o \ | |
| 130 | 134 | $(LIBOBJ)/formats/imd_dsk.o \ |
| 131 | 135 | $(LIBOBJ)/formats/ipf_dsk.o \ |
| 132 | 136 | $(LIBOBJ)/formats/kc_cas.o \ |
| 137 | $(LIBOBJ)/formats/kc85_dsk.o \ | |
| 133 | 138 | $(LIBOBJ)/formats/kim1_cas.o \ |
| 134 | 139 | $(LIBOBJ)/formats/lviv_lvt.o \ |
| 140 | $(LIBOBJ)/formats/m5_dsk.o \ | |
| 141 | $(LIBOBJ)/formats/mm_dsk.o \ | |
| 135 | 142 | $(LIBOBJ)/formats/msx_dsk.o \ |
| 136 | 143 | $(LIBOBJ)/formats/mfi_dsk.o \ |
| 137 | 144 | $(LIBOBJ)/formats/mz_cas.o \ |
| 145 | $(LIBOBJ)/formats/nanos_dsk.o \ | |
| 138 | 146 | $(LIBOBJ)/formats/nes_dsk.o \ |
| 139 | 147 | $(LIBOBJ)/formats/orao_cas.o \ |
| 140 | 148 | $(LIBOBJ)/formats/oric_dsk.o \ |
| r18419 | r18420 | |
| 144 | 152 | $(LIBOBJ)/formats/pc_dsk.o \ |
| 145 | 153 | $(LIBOBJ)/formats/pmd_cas.o \ |
| 146 | 154 | $(LIBOBJ)/formats/primoptp.o \ |
| 155 | $(LIBOBJ)/formats/pyldin_dsk.o \ | |
| 147 | 156 | $(LIBOBJ)/formats/rk_cas.o \ |
| 148 | 157 | $(LIBOBJ)/formats/sc3000_bit.o \ |
| 158 | $(LIBOBJ)/formats/sf7000_dsk.o \ | |
| 149 | 159 | $(LIBOBJ)/formats/smx_dsk.o \ |
| 150 | 160 | $(LIBOBJ)/formats/sorc_dsk.o \ |
| 151 | 161 | $(LIBOBJ)/formats/sord_cas.o \ |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/nanos_dsk.h | |
| 4 | ||
| 5 | nanos format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef NANOS_DSK_H_ | |
| 10 | #define NANOS_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class nanos_format : public upd765_format { | |
| 15 | public: | |
| 16 | nanos_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_NANOS_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/mm_dsk.c | |
| 37 | ||
| 38 | mm format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/mm_dsk.h" | |
| 44 | ||
| 45 | mm1_format::mm1_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *mm1_format::name() const | |
| 50 | { | |
| 51 | return "mm1"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *mm1_format::description() const | |
| 55 | { | |
| 56 | return "Nokia MikroMikko 1 disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *mm1_format::extensions() const | |
| 60 | { | |
| 61 | return "dsk"; | |
| 62 | } | |
| 63 | ||
| 64 | mm2_format::mm2_format() : upd765_format(formats) | |
| 65 | { | |
| 66 | } | |
| 67 | ||
| 68 | const char *mm2_format::name() const | |
| 69 | { | |
| 70 | return "mm2"; | |
| 71 | } | |
| 72 | ||
| 73 | const char *mm2_format::description() const | |
| 74 | { | |
| 75 | return "Nokia MikroMikko 2 disk image"; | |
| 76 | } | |
| 77 | ||
| 78 | const char *mm2_format::extensions() const | |
| 79 | { | |
| 80 | return "dsk"; | |
| 81 | } | |
| 82 | ||
| 83 | // Unverified gap sizes | |
| 84 | const mm1_format::format mm1_format::formats[] = { | |
| 85 | { | |
| 86 | floppy_image::FF_525, floppy_image::DSQD, | |
| 87 | 2000, // 2us, 300rpm | |
| 88 | 8, 80, 2, | |
| 89 | 512, {}, | |
| 90 | -1, { 1,4,7,2,5,8,3,6 }, | |
| 91 | 80, 50, 22, 80 | |
| 92 | }, | |
| 93 | {} | |
| 94 | }; | |
| 95 | ||
| 96 | // Unverified gap sizes | |
| 97 | const mm2_format::format mm2_format::formats[] = { | |
| 98 | { | |
| 99 | floppy_image::FF_525, floppy_image::DSDD, | |
| 100 | 2000, // 2us, 300rpm | |
| 101 | 9, 40, 2, | |
| 102 | 512, {}, | |
| 103 | 1, {}, | |
| 104 | 80, 50, 22, 80 | |
| 105 | }, | |
| 106 | // 40 tracks but 18 sectors implying HD density at 300rpm, i.e. on | |
| 107 | // 3.5" media? That makes no sense | |
| 108 | { | |
| 109 | floppy_image::FF_525, floppy_image::DSHD, | |
| 110 | 1000, // 1us, 300rpm, otherwise it just won't fit | |
| 111 | 18, 40, 2, // That line is just nonsense | |
| 112 | 512, {}, | |
| 113 | 1, {}, | |
| 114 | 80, 50, 22, 80 | |
| 115 | } | |
| 116 | }; | |
| 117 | ||
| 118 | const floppy_format_type FLOPPY_MM1_FORMAT = &floppy_image_format_creator<mm1_format>; | |
| 119 | const floppy_format_type FLOPPY_MM2_FORMAT = &floppy_image_format_creator<mm2_format>; |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/mm_dsk.h | |
| 4 | ||
| 5 | MikroMikko formats | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef MM_DSK_H_ | |
| 10 | #define MM_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class mm1_format : public upd765_format { | |
| 15 | public: | |
| 16 | mm1_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | class mm2_format : public upd765_format { | |
| 27 | public: | |
| 28 | mm2_format(); | |
| 29 | ||
| 30 | virtual const char *name() const; | |
| 31 | virtual const char *description() const; | |
| 32 | virtual const char *extensions() const; | |
| 33 | ||
| 34 | private: | |
| 35 | static const format formats[]; | |
| 36 | }; | |
| 37 | ||
| 38 | extern const floppy_format_type FLOPPY_MM1_FORMAT; | |
| 39 | extern const floppy_format_type FLOPPY_MM2_FORMAT; | |
| 40 | ||
| 41 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 137 | 137 | SECTORS(8/[9]/10/15/18/36)) |
| 138 | 138 | LEGACY_FLOPPY_OPTIONS_END |
| 139 | 139 | |
| 140 | ||
| 141 | const floppy_image_format_t::desc_e pc_format::pc_9_desc[] = { | |
| 142 | { MFM, 0x4e, 80 }, | |
| 143 | { MFM, 0x00, 12 }, | |
| 144 | { RAW, 0x5224, 3 }, | |
| 145 | { MFM, 0xfc, 1 }, | |
| 146 | { MFM, 0x4e, 50 }, | |
| 147 | { MFM, 0x00, 12 }, | |
| 148 | { SECTOR_LOOP_START, 0, 8 }, | |
| 149 | { CRC_CCITT_START, 1 }, | |
| 150 | { RAW, 0x4489, 3 }, | |
| 151 | { MFM, 0xfe, 1 }, | |
| 152 | { TRACK_ID }, | |
| 153 | { HEAD_ID }, | |
| 154 | { SECTOR_ID }, | |
| 155 | { SIZE_ID }, | |
| 156 | { CRC_END, 1 }, | |
| 157 | { CRC, 1 }, | |
| 158 | { MFM, 0x4e, 22 }, | |
| 159 | { MFM, 0x00, 12 }, | |
| 160 | { CRC_CCITT_START, 2 }, | |
| 161 | { RAW, 0x4489, 3 }, | |
| 162 | { MFM, 0xfb, 1 }, | |
| 163 | { SECTOR_DATA, -1 }, | |
| 164 | { CRC_END, 2 }, | |
| 165 | { CRC, 2 }, | |
| 166 | { MFM, 0x4e, 84 }, | |
| 167 | { MFM, 0x00, 12 }, | |
| 168 | { SECTOR_LOOP_END }, | |
| 169 | { MFM, 0x4e, 170 }, | |
| 170 | { END } | |
| 171 | }; | |
| 172 | ||
| 173 | const floppy_image_format_t::desc_e pc_format::pc_18_desc[] = { | |
| 174 | { MFM, 0x4e, 80 }, | |
| 175 | { MFM, 0x00, 12 }, | |
| 176 | { RAW, 0x5224, 3 }, | |
| 177 | { MFM, 0xfc, 1 }, | |
| 178 | { MFM, 0x4e, 50 }, | |
| 179 | { MFM, 0x00, 12 }, | |
| 180 | { SECTOR_LOOP_START, 0, 17 }, | |
| 181 | { CRC_CCITT_START, 1 }, | |
| 182 | { RAW, 0x4489, 3 }, | |
| 183 | { MFM, 0xfe, 1 }, | |
| 184 | { TRACK_ID }, | |
| 185 | { HEAD_ID }, | |
| 186 | { SECTOR_ID }, | |
| 187 | { SIZE_ID }, | |
| 188 | { CRC_END, 1 }, | |
| 189 | { CRC, 1 }, | |
| 190 | { MFM, 0x4e, 22 }, | |
| 191 | { MFM, 0x00, 12 }, | |
| 192 | { CRC_CCITT_START, 2 }, | |
| 193 | { RAW, 0x4489, 3 }, | |
| 194 | { MFM, 0xfb, 1 }, | |
| 195 | { SECTOR_DATA, -1 }, | |
| 196 | { CRC_END, 2 }, | |
| 197 | { CRC, 2 }, | |
| 198 | { MFM, 0x4e, 84 }, | |
| 199 | { MFM, 0x00, 12 }, | |
| 200 | { SECTOR_LOOP_END }, | |
| 201 | { MFM, 0x4e, 498 }, | |
| 202 | { END } | |
| 203 | }; | |
| 204 | ||
| 205 | const floppy_image_format_t::desc_e pc_format::pc_36_desc[] = { | |
| 206 | { MFM, 0x4e, 80 }, | |
| 207 | { MFM, 0x00, 12 }, | |
| 208 | { RAW, 0x5224, 3 }, | |
| 209 | { MFM, 0xfc, 1 }, | |
| 210 | { MFM, 0x4e, 50 }, | |
| 211 | { MFM, 0x00, 12 }, | |
| 212 | { SECTOR_LOOP_START, 0, 35 }, | |
| 213 | { CRC_CCITT_START, 1 }, | |
| 214 | { RAW, 0x4489, 3 }, | |
| 215 | { MFM, 0xfe, 1 }, | |
| 216 | { TRACK_ID }, | |
| 217 | { HEAD_ID }, | |
| 218 | { SECTOR_ID }, | |
| 219 | { SIZE_ID }, | |
| 220 | { CRC_END, 1 }, | |
| 221 | { CRC, 1 }, | |
| 222 | { MFM, 0x4e, 22 }, | |
| 223 | { MFM, 0x00, 12 }, | |
| 224 | { CRC_CCITT_START, 2 }, | |
| 225 | { RAW, 0x4489, 3 }, | |
| 226 | { MFM, 0xfb, 1 }, | |
| 227 | { SECTOR_DATA, -1 }, | |
| 228 | { CRC_END, 2 }, | |
| 229 | { CRC, 2 }, | |
| 230 | { MFM, 0x4e, 84 }, | |
| 231 | { MFM, 0x00, 12 }, | |
| 232 | { SECTOR_LOOP_END }, | |
| 233 | { MFM, 0x4e, 1154 }, | |
| 234 | { END } | |
| 235 | }; | |
| 236 | ||
| 237 | const pc_format::format pc_format::formats[] = { | |
| 238 | { 8*1*40*512, floppy_image::FF_525, floppy_image::SSDD, 40, 1, 8, 0, 000000 }, /* 5 1/4 inch double density single sided */ | |
| 239 | { 8*2*40*512, floppy_image::FF_525, floppy_image::DSDD, 40, 2, 8, 0, 000000 }, /* 5 1/4 inch double density */ | |
| 240 | { 9*1*40*512, floppy_image::FF_525, floppy_image::SSDD, 40, 1, 9, 0, 000000 }, /* 5 1/4 inch double density single sided */ | |
| 241 | { 9*2*40*512, floppy_image::FF_525, floppy_image::DSDD, 40, 2, 9, 0, 000000 }, /* 5 1/4 inch double density */ | |
| 242 | { 10*2*40*512, floppy_image::FF_525, floppy_image::DSDD, 40, 2, 10, 0, 000000 }, /* 5 1/4 inch double density 10spt */ | |
| 243 | { 9*2*80*512, floppy_image::FF_525, floppy_image::DSDD, 80, 2, 9, 0, 000000 }, /* 80 tracks 5 1/4 inch drives rare in PCs */ | |
| 244 | { 9*2*80*512, floppy_image::FF_35, floppy_image::DSDD, 80, 2, 9, pc_9_desc, 100000 }, /* 3 1/2 inch double density */ | |
| 245 | { 15*2*80*512, floppy_image::FF_525, floppy_image::DSHD, 80, 2, 15, 0, 000000 }, /* 5 1/4 inch high density (or japanese 3 1/2 inch high density) */ | |
| 246 | { 18*2*80*512, floppy_image::FF_35, floppy_image::DSHD, 80, 2, 18, pc_18_desc, 200000 }, /* 3 1/2 inch high density */ | |
| 247 | { 21*2*80*512, floppy_image::FF_35, floppy_image::DSHD, 80, 2, 21, 0, 000000 }, /* 3 1/2 inch high density DMF */ | |
| 248 | { 36*2*80*512, floppy_image::FF_35, floppy_image::DSED, 80, 2, 36, pc_36_desc, 400000 }, /* 3 1/2 inch enhanced density */ | |
| 249 | { 0 }, | |
| 250 | }; | |
| 251 | ||
| 252 | pc_format::pc_format() | |
| 140 | pc_format::pc_format() : upd765_format(formats) | |
| 253 | 141 | { |
| 254 | 142 | } |
| 255 | 143 | |
| r18419 | r18420 | |
| 268 | 156 | return "dsk,ima,img,ufi,360"; |
| 269 | 157 | } |
| 270 | 158 | |
| 271 | bool pc_format::supports_save() const | |
| 272 | { | |
| 273 | return true; | |
| 274 | } | |
| 159 | const pc_format::format pc_format::formats[] = { | |
| 160 | { /* 160K 5 1/4 inch double density single sided */ | |
| 161 | floppy_image::FF_525, floppy_image::SSDD, | |
| 162 | 2000, 8, 40, 1, 512, {}, 1, {}, 80, 50, 22, 80 | |
| 163 | }, | |
| 164 | { /* 320K 5 1/4 inch double density */ | |
| 165 | floppy_image::FF_525, floppy_image::DSDD, | |
| 166 | 2000, 8, 40, 2, 512, {}, 1, {}, 80, 50, 22, 80 | |
| 167 | }, | |
| 168 | { /* 180K 5 1/4 inch double density single sided */ | |
| 169 | floppy_image::FF_525, floppy_image::SSDD, | |
| 170 | 2000, 9, 40, 1, 512, {}, 1, {}, 80, 50, 22, 80 | |
| 171 | }, | |
| 172 | { /* 360K 5 1/4 inch double density */ | |
| 173 | floppy_image::FF_525, floppy_image::DSDD, | |
| 174 | 2000, 9, 40, 2, 512, {}, 1, {}, 80, 50, 22, 80 | |
| 175 | }, | |
| 176 | { /* 400K 5 1/4 inch double density - gaps unverified */ | |
| 177 | floppy_image::FF_525, floppy_image::DSDD, | |
| 178 | 2000, 10, 40, 2, 512, {}, 1, {}, 80, 50, 22, 80 | |
| 179 | }, | |
| 180 | { /* 720K 5 1/4 inch quad density - gaps unverified */ | |
| 181 | floppy_image::FF_525, floppy_image::DSQD, | |
| 182 | 2000, 9, 80, 2, 512, {}, 1, {}, 80, 50, 22, 80 | |
| 183 | }, | |
| 184 | { /* 1200K 5 1/4 inch high density */ | |
| 185 | floppy_image::FF_525, floppy_image::DSHD, | |
| 186 | 1200, 15, 40, 2, 512, {}, 1, {}, 80, 50, 22, 84 | |
| 187 | }, | |
| 188 | { /* 720K 3 1/2 inch double density */ | |
| 189 | floppy_image::FF_35, floppy_image::DSDD, | |
| 190 | 2000, 9, 80, 2, 512, {}, 1, {}, 80, 50, 22, 80 | |
| 191 | }, | |
| 192 | { /* 1200K 3 1/2 inch high density (japanese variant) - gaps unverified */ | |
| 193 | floppy_image::FF_35, floppy_image::DSHD, | |
| 194 | 1200, 15, 40, 2, 512, {}, 1, {}, 80, 50, 22, 84 | |
| 195 | }, | |
| 196 | { /* 1440K 3 1/2 inch high density */ | |
| 197 | floppy_image::FF_35, floppy_image::DSHD, | |
| 198 | 1000, 18, 80, 2, 512, {}, 1, {}, 80, 50, 22, 108 | |
| 199 | }, | |
| 200 | { /* 2880K 3 1/2 inch extended density - gaps unverified */ | |
| 201 | floppy_image::FF_35, floppy_image::DSED, | |
| 202 | 500, 36, 80, 2, 512, {}, 1, {}, 80, 50, 41, 80 | |
| 203 | }, | |
| 204 | {} | |
| 205 | }; | |
| 275 | 206 | |
| 276 | int pc_format::find_size(io_generic *io, UINT32 form_factor) | |
| 277 | { | |
| 278 | int size = io_generic_size(io); | |
| 279 | for(int type = 0; formats[type].size; type++) | |
| 280 | if(formats[type].size == size && (formats[type].form_factor == form_factor || form_factor == floppy_image::FF_UNKNOWN)) | |
| 281 | return type; | |
| 282 | return -1; | |
| 283 | } | |
| 284 | ||
| 285 | int pc_format::identify(io_generic *io, UINT32 form_factor) | |
| 286 | { | |
| 287 | int type = find_size(io, form_factor); | |
| 288 | ||
| 289 | if(type != -1) | |
| 290 | return 50; | |
| 291 | return 0; | |
| 292 | } | |
| 293 | ||
| 294 | bool pc_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) | |
| 295 | { | |
| 296 | int type = find_size(io, form_factor); | |
| 297 | if(type == -1) | |
| 298 | return false; | |
| 299 | ||
| 300 | const format &f = formats[type]; | |
| 301 | if(!f.desc) | |
| 302 | return false; | |
| 303 | ||
| 304 | UINT8 sectdata[36*512]; | |
| 305 | desc_s sectors[36]; | |
| 306 | for(int i=0; i<f.sector_count; i++) { | |
| 307 | sectors[i].data = sectdata + 512*i; | |
| 308 | sectors[i].size = 512; | |
| 309 | sectors[i].sector_id = i + 1; | |
| 310 | } | |
| 311 | ||
| 312 | int track_size = f.sector_count*512; | |
| 313 | for(int track=0; track < f.track_count; track++) | |
| 314 | for(int head=0; head < f.head_count; head++) { | |
| 315 | io_generic_read(io, sectdata, (track*f.head_count + head)*track_size, track_size); | |
| 316 | generate_track(f.desc, track, head, sectors, f.sector_count, f.cell_count, image); | |
| 317 | } | |
| 318 | ||
| 319 | image->set_variant(f.variant); | |
| 320 | ||
| 321 | return true; | |
| 322 | } | |
| 323 | ||
| 324 | bool pc_format::save(io_generic *io, floppy_image *image) | |
| 325 | { | |
| 326 | int cell_time = 1000; | |
| 327 | switch(image->get_variant()) { | |
| 328 | case floppy_image::SSSD: | |
| 329 | cell_time = 4000; // fm too, actually | |
| 330 | break; | |
| 331 | case floppy_image::SSDD: | |
| 332 | case floppy_image::DSDD: | |
| 333 | cell_time = 2000; | |
| 334 | break; | |
| 335 | case floppy_image::DSHD: | |
| 336 | cell_time = 1000; | |
| 337 | break; | |
| 338 | case floppy_image::DSED: | |
| 339 | cell_time = 500; | |
| 340 | break; | |
| 341 | } | |
| 342 | ||
| 343 | int track_count, head_count, sector_count; | |
| 344 | get_geometry_mfm_pc(image, cell_time, track_count, head_count, sector_count); | |
| 345 | ||
| 346 | if(track_count < 80) | |
| 347 | track_count = 80; | |
| 348 | else if(track_count > 82) | |
| 349 | track_count = 82; | |
| 350 | ||
| 351 | // Happens for a fully unformatted floppy | |
| 352 | if(!head_count) | |
| 353 | head_count = 1; | |
| 354 | ||
| 355 | if(sector_count > 36) | |
| 356 | sector_count = 36; | |
| 357 | else if(sector_count < 8) | |
| 358 | sector_count = 8; | |
| 359 | ||
| 360 | UINT8 sectdata[36*512]; | |
| 361 | int track_size = sector_count*512; | |
| 362 | ||
| 363 | for(int track=0; track < track_count; track++) { | |
| 364 | for(int head=0; head < head_count; head++) { | |
| 365 | get_track_data_mfm_pc(track, head, image, cell_time, 512, sector_count, sectdata); | |
| 366 | io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size); | |
| 367 | } | |
| 368 | } | |
| 369 | ||
| 370 | return true; | |
| 371 | } | |
| 372 | ||
| 373 | 207 | const floppy_format_type FLOPPY_PC_FORMAT = &floppy_image_format_creator<pc_format>; |
| r18419 | r18420 | |
|---|---|---|
| 504 | 504 | if(!head_count) |
| 505 | 505 | return false; |
| 506 | 506 | |
| 507 | UINT32 *track_data = global_alloc_array(UINT32, cell_count+10000); | |
| 507 | 508 | UINT32 track_pos[164]; |
| 508 | 509 | io_generic_read(io, track_pos, 32, 164*4); |
| 509 | 510 | |
| r18419 | r18420 | |
| 513 | 514 | if(!pos) |
| 514 | 515 | continue; |
| 515 | 516 | |
| 516 | UINT32 track_data[210000]; | |
| 517 | 517 | UINT8 sect_data[65536]; |
| 518 | 518 | int tpos = 0; |
| 519 | 519 | |
| r18419 | r18420 | |
| 541 | 541 | else |
| 542 | 542 | gap3 = form_factor == floppy_image::FF_35 ? 84 : 80; |
| 543 | 543 | } |
| 544 | ||
| 545 | 544 | int cpos; |
| 546 | 545 | UINT16 crc; |
| 547 | 546 | // sync and IDAM and gap 2 |
| r18419 | r18420 | |
| 561 | 560 | for(int j=0; j<12; j++) mfm_w(track_data, tpos, 8, 0x00); |
| 562 | 561 | cpos = tpos; |
| 563 | 562 | for(int j=0; j< 3; j++) raw_w(track_data, tpos, 16, 0x4489); |
| 564 | mfm_w(track_data, tpos, 8, 0xfb); | |
| 563 | mfm_w(track_data, tpos, 8, hs[7] ? 0xf8 : 0xfb); | |
| 565 | 564 | for(int j=0; j<size; j++) mfm_w(track_data, tpos, 8, sect_data[j]); |
| 566 | 565 | crc = calc_crc_ccitt(track_data, cpos, tpos); |
| 567 | 566 | mfm_w(track_data, tpos, 16, crc); |
| r18419 | r18420 | |
| 578 | 577 | generate_track_from_levels(track, head, track_data, cell_count, 0, image); |
| 579 | 578 | } |
| 580 | 579 | |
| 580 | global_free(track_data); | |
| 581 | 581 | return true; |
| 582 | 582 | } |
| 583 | 583 |
| r18419 | r18420 | |
|---|---|---|
| 10 | 10 | #define PC_DSK_H |
| 11 | 11 | |
| 12 | 12 | #include "flopimg.h" |
| 13 | #include "upd765_dsk.h" | |
| 13 | 14 | |
| 14 | ||
| 15 | 15 | /**************************************************************************/ |
| 16 | 16 | |
| 17 | 17 | LEGACY_FLOPPY_OPTIONS_EXTERN(pc); |
| 18 | 18 | |
| 19 | 19 | |
| 20 | class pc_format : public | |
| 20 | class pc_format : public upd765_format | |
| 21 | 21 | { |
| 22 | 22 | public: |
| 23 | 23 | pc_format(); |
| 24 | 24 | |
| 25 | virtual int identify(io_generic *io, UINT32 form_factor); | |
| 26 | virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image); | |
| 27 | virtual bool save(io_generic *io, floppy_image *image); | |
| 28 | ||
| 29 | 25 | virtual const char *name() const; |
| 30 | 26 | virtual const char *description() const; |
| 31 | 27 | virtual const char *extensions() const; |
| 32 | virtual bool supports_save() const; | |
| 33 | 28 | |
| 34 | 29 | private: |
| 35 | struct format { | |
| 36 | int size; | |
| 37 | UINT32 form_factor; | |
| 38 | UINT32 variant; | |
| 39 | int track_count; | |
| 40 | int head_count; | |
| 41 | int sector_count; | |
| 42 | const desc_e *desc; | |
| 43 | int cell_count; | |
| 44 | }; | |
| 45 | ||
| 46 | 30 | static const format formats[]; |
| 47 | static const desc_e pc_9_desc[], pc_18_desc[], pc_36_desc[]; | |
| 48 | ||
| 49 | int find_size(io_generic *io, UINT32 form_factor); | |
| 50 | 31 | }; |
| 51 | 32 | |
| 52 | 33 | extern const floppy_format_type FLOPPY_PC_FORMAT; |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/sf7000_dsk.c | |
| 37 | ||
| 38 | sf7000 format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/sf7000_dsk.h" | |
| 44 | ||
| 45 | sf7000_format::sf7000_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *sf7000_format::name() const | |
| 50 | { | |
| 51 | return "sf7"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *sf7000_format::description() const | |
| 55 | { | |
| 56 | return "SF7 disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *sf7000_format::extensions() const | |
| 60 | { | |
| 61 | return "sf7"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | // Drivers says HD, I don't believe it. At all. | |
| 66 | const sf7000_format::format sf7000_format::formats[] = { | |
| 67 | { | |
| 68 | floppy_image::FF_525, floppy_image::SSDD, | |
| 69 | 2000, // 2us, 300rpm | |
| 70 | 16, 40, 1, | |
| 71 | 256, {}, | |
| 72 | 1, {}, | |
| 73 | 80, 50, 22, 80 | |
| 74 | }, | |
| 75 | {} | |
| 76 | }; | |
| 77 | ||
| 78 | const floppy_format_type FLOPPY_SF7000_FORMAT = &floppy_image_format_creator<sf7000_format>; |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/sf7000_dsk.h | |
| 4 | ||
| 5 | sf7000 format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef SF7000_DSK_H_ | |
| 10 | #define SF7000_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class sf7000_format : public upd765_format { | |
| 15 | public: | |
| 16 | sf7000_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_SF7000_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 1047 | 1047 | switch(variant) { |
| 1048 | 1048 | case SSSD: return "Single side, single density"; |
| 1049 | 1049 | case SSDD: return "Single side, double density"; |
| 1050 | case SSQD: return "Single side, quad density"; | |
| 1050 | 1051 | case DSDD: return "Double side, double density"; |
| 1052 | case DSQD: return "Double side, quad density"; | |
| 1051 | 1053 | case DSHD: return "Double side, high density"; |
| 1052 | 1054 | case DSED: return "Double side, extended density"; |
| 1053 | 1055 | } |
| r18419 | r18420 | |
| 1569 | 1571 | |
| 1570 | 1572 | case MG_W: |
| 1571 | 1573 | throw emu_fatalerror("Weak bits not yet handled, track %d head %d\n", track, head); |
| 1574 | ||
| 1572 | 1575 | case MG_0: |
| 1573 | 1576 | case floppy_image::MG_N: |
| 1574 | 1577 | case floppy_image::MG_D: |
| r18419 | r18420 | |
| 2202 | 2205 | idblk[idblk_count++] = pos; |
| 2203 | 2206 | i = pos-1; |
| 2204 | 2207 | } |
| 2205 | // fa, fb, fc, fd | |
| 2206 | if(header == 0x5544 || header == 0x5545 || header == 0x5553 || header == 0x5551) { | |
| 2208 | // f8, f9, fa, fb | |
| 2209 | if(header == 0x554a || header == 0x5549 || header == 0x5544 || header == 0x5545) { | |
| 2207 | 2210 | if(dblk_count < 100) |
| 2208 | 2211 | dblk[dblk_count++] = pos; |
| 2209 | 2212 | i = pos-1; |
| r18419 | r18420 | |
| 2229 | 2232 | continue; |
| 2230 | 2233 | |
| 2231 | 2234 | // Start of IDAM and DAM are supposed to be exactly 704 cells |
| 2232 | // apart. Of course the hardware is tolerant. Accept +/- 128 | |
| 2233 | // cells of shift. | |
| 2235 | // apart in normal format or 1008 cells apart in perpendicular | |
| 2236 | // format. Of course the hardware is tolerant. Accept +/- | |
| 2237 | // 128 cells of shift. | |
| 2234 | 2238 | |
| 2235 | 2239 | int d_index; |
| 2236 | 2240 | for(d_index = 0; d_index < dblk_count; d_index++) { |
| 2237 | 2241 | int delta = dblk[d_index] - idblk[i]; |
| 2238 | if(delta >= 704-128 && delta <= | |
| 2242 | if(delta >= 704-128 && delta <= 1008+128) | |
| 2239 | 2243 | break; |
| 2240 | 2244 | } |
| 2241 | 2245 | if(d_index == dblk_count) |
| r18419 | r18420 | |
|---|---|---|
| 683 | 683 | void set_write_splice_position(int track, int head, UINT32 pos) { write_splice[track][head] = pos; } |
| 684 | 684 | //! @return the current write splice position. |
| 685 | 685 | UINT32 get_write_splice_position(int track, int head) const { return write_splice[track][head]; } |
| 686 | //! @return the maximal geometry supported by thi | |
| 686 | //! @return the maximal geometry supported by this format. | |
| 687 | 687 | void get_maximal_geometry(int &tracks, int &heads); |
| 688 | ||
| 688 | 689 | //! @return the current geometry of the loaded image. |
| 689 | 690 | void get_actual_geometry(int &tracks, int &heads); |
| 691 | ||
| 690 | 692 | //! Returns the variant name for the particular disk form factor/variant |
| 691 | 693 | //! @param form_factor |
| 692 | 694 | //! @param variant |
| r18419 | r18420 | |
|---|---|---|
| 51 | 51 | { |
| 52 | 52 | int size = io_generic_size(io); |
| 53 | 53 | for(int i=0; formats[i].form_factor; i++) { |
| 54 | if(form_factor != floppy_image::FF_UNKNOWN && form_factor != formats[i].form_factor) | |
| 54 | const format &f = formats[i]; | |
| 55 | if(form_factor != floppy_image::FF_UNKNOWN && form_factor != f.form_factor) | |
| 55 | 56 | continue; |
| 56 | 57 | |
| 57 | int format_size; | |
| 58 | if(formats[i].sector_base_size) | |
| 59 | format_size = formats[i].sector_base_size * formats[i].sector_count; | |
| 60 | else { | |
| 61 | format_size = 0; | |
| 62 | for(int j=0; j != formats[i].sector_count; j++) | |
| 63 | format_size += formats[i].per_sector_size[j]; | |
| 64 | } | |
| 65 | ||
| 66 | format_size *= formats[i].track_count * formats[i].head_count; | |
| 67 | ||
| 68 | if(size == format_size) | |
| 58 | if(size == compute_track_size(f) * f.track_count * f.head_count) | |
| 69 | 59 | return i; |
| 70 | 60 | } |
| 71 | 61 | return -1; |
| r18419 | r18420 | |
| 80 | 70 | return 0; |
| 81 | 71 | } |
| 82 | 72 | |
| 73 | int upd765_format::compute_track_size(const format &f) const | |
| 74 | { | |
| 75 | int track_size; | |
| 76 | if(f.sector_base_size) | |
| 77 | track_size = f.sector_base_size * f.sector_count; | |
| 78 | else { | |
| 79 | track_size = 0; | |
| 80 | for(int i=0; i != f.sector_count; i++) | |
| 81 | track_size += f.per_sector_size[i]; | |
| 82 | } | |
| 83 | return track_size; | |
| 84 | } | |
| 85 | ||
| 86 | void upd765_format::build_sector_description(const format &f, UINT8 *sectdata, desc_s *sectors) const | |
| 87 | { | |
| 88 | if(f.sector_base_id == -1) { | |
| 89 | for(int i=0; i<f.sector_count; i++) { | |
| 90 | int cur_offset = 0; | |
| 91 | for(int j=0; j<f.sector_count; j++) | |
| 92 | if(f.per_sector_id[j] < f.per_sector_id[i]) | |
| 93 | cur_offset += f.sector_base_size ? f.sector_base_size : f.per_sector_size[j]; | |
| 94 | sectors[i].data = sectdata + cur_offset; | |
| 95 | sectors[i].size = f.sector_base_size ? f.sector_base_size : f.per_sector_size[i]; | |
| 96 | sectors[i].sector_id = f.per_sector_id[i]; | |
| 97 | } | |
| 98 | } else { | |
| 99 | int cur_offset = 0; | |
| 100 | for(int i=0; i<f.sector_count; i++) { | |
| 101 | sectors[i].data = sectdata + cur_offset; | |
| 102 | sectors[i].size = f.sector_base_size ? f.sector_base_size : f.per_sector_size[i]; | |
| 103 | cur_offset += sectors[i].size; | |
| 104 | sectors[i].sector_id = i + f.sector_base_id; | |
| 105 | } | |
| 106 | } | |
| 107 | } | |
| 108 | ||
| 83 | 109 | bool upd765_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) |
| 84 | 110 | { |
| 85 | 111 | int type = find_size(io, form_factor); |
| r18419 | r18420 | |
| 139 | 165 | desc[27].p2 = remaining_size & 15; |
| 140 | 166 | desc[27].p1 >>= 16-(remaining_size & 15); |
| 141 | 167 | |
| 142 | int track_size; | |
| 143 | if(f.sector_base_size) | |
| 144 | track_size = f.sector_base_size * f.sector_count; | |
| 145 | else { | |
| 146 | track_size = 0; | |
| 147 | for(int i=0; i != f.sector_count; i++) | |
| 148 | track_size += f.per_sector_size[i]; | |
| 149 | } | |
| 168 | int track_size = compute_track_size(f); | |
| 150 | 169 | |
| 151 | 170 | UINT8 sectdata[40*512]; |
| 152 | 171 | desc_s sectors[40]; |
| 153 | if(f.sector_base_id == -1) { | |
| 154 | for(int i=0; i<f.sector_count; i++) { | |
| 155 | int cur_offset = 0; | |
| 156 | for(int j=0; j<f.sector_count; j++) | |
| 157 | if(f.per_sector_id[j] < f.per_sector_id[i]) | |
| 158 | cur_offset += f.sector_base_size ? f.sector_base_size : f.per_sector_size[j]; | |
| 159 | sectors[i].data = sectdata + cur_offset; | |
| 160 | sectors[i].size = f.sector_base_size ? f.sector_base_size : f.per_sector_size[i]; | |
| 161 | sectors[i].sector_id = f.per_sector_id[i]; | |
| 162 | } | |
| 163 | } else { | |
| 164 | int cur_offset = 0; | |
| 165 | for(int i=0; i<f.sector_count; i++) { | |
| 166 | sectors[i].data = sectdata + cur_offset; | |
| 167 | sectors[i].size = f.sector_base_size ? f.sector_base_size : f.per_sector_size[i]; | |
| 168 | cur_offset += sectors[i].size; | |
| 169 | sectors[i].sector_id = i + f.sector_base_id; | |
| 170 | } | |
| 171 | } | |
| 172 | build_sector_description(f, sectdata, sectors); | |
| 172 | 173 | |
| 173 | 174 | for(int track=0; track < f.track_count; track++) |
| 174 | 175 | for(int head=0; head < f.head_count; head++) { |
| r18419 | r18420 | |
| 181 | 182 | return true; |
| 182 | 183 | } |
| 183 | 184 | |
| 185 | bool upd765_format::supports_save() const | |
| 186 | { | |
| 187 | return true; | |
| 188 | } | |
| 184 | 189 | |
| 185 | 190 | bool upd765_format::save(io_generic *io, floppy_image *image) |
| 186 | 191 | { |
| 192 | // Count the number of formats | |
| 193 | int formats_count; | |
| 194 | for(formats_count=0; formats[formats_count].form_factor; formats_count++); | |
| 195 | ||
| 196 | // Allocate the storage for the list of testable formats for a | |
| 197 | // given cell size | |
| 198 | int *candidates = global_alloc_array(int, formats_count); | |
| 199 | ||
| 200 | // Format we're finally choosing | |
| 201 | int chosen_candidate = -1; | |
| 202 | ||
| 203 | // Previously tested cell size | |
| 204 | int min_cell_size = 0; | |
| 205 | for(;;) { | |
| 206 | // Build the list of all formats for the immediatly superior cell size | |
| 207 | int cur_cell_size = 0; | |
| 208 | int candidates_count = 0; | |
| 209 | for(int i=0; i != formats_count; i++) { | |
| 210 | if(image->get_form_factor() == floppy_image::FF_UNKNOWN || | |
| 211 | image->get_form_factor() == formats[i].form_factor) { | |
| 212 | if(formats[i].cell_size == cur_cell_size) | |
| 213 | candidates[candidates_count++] = i; | |
| 214 | else if((!cur_cell_size || formats[i].cell_size < cur_cell_size) && | |
| 215 | formats[i].cell_size > min_cell_size) { | |
| 216 | candidates[0] = i; | |
| 217 | candidates_count = 1; | |
| 218 | cur_cell_size = formats[i].cell_size; | |
| 219 | } | |
| 220 | } | |
| 221 | } | |
| 222 | ||
| 223 | min_cell_size = cur_cell_size; | |
| 224 | ||
| 225 | // No candidates with a cell size bigger than the previously | |
| 226 | // tested one, we're done | |
| 227 | if(!candidates_count) | |
| 228 | break; | |
| 229 | ||
| 230 | // Filter with track 0 head 0 | |
| 231 | check_compatibility(image, candidates, candidates_count); | |
| 232 | ||
| 233 | // Nobody matches, try with the next cell size | |
| 234 | if(!candidates_count) | |
| 235 | continue; | |
| 236 | ||
| 237 | // We have a match at that cell size, we just need to find the | |
| 238 | // best one given the geometry | |
| 239 | ||
| 240 | // If there's only one, we're done | |
| 241 | if(candidates_count == 1) { | |
| 242 | chosen_candidate = candidates[0]; | |
| 243 | break; | |
| 244 | } | |
| 245 | ||
| 246 | // Otherwise, find the best | |
| 247 | int tracks, heads; | |
| 248 | image->get_actual_geometry(tracks, heads); | |
| 249 | chosen_candidate = candidates[0]; | |
| 250 | for(int i=1; i != candidates_count; i++) { | |
| 251 | const format &cc = formats[chosen_candidate]; | |
| 252 | const format &cn = formats[candidates[i]]; | |
| 253 | ||
| 254 | // Handling enough sides is better than not | |
| 255 | if(cn.head_count >= heads && cc.head_count < heads) | |
| 256 | goto change; | |
| 257 | else if(cc.head_count >= heads && cn.head_count < heads) | |
| 258 | goto dont_change; | |
| 259 | ||
| 260 | // Since we're limited to two heads, at that point head | |
| 261 | // count is identical for both formats. | |
| 262 | ||
| 263 | // Handling enough tracks is better than not | |
| 264 | if(cn.track_count >= tracks && cc.track_count < tracks) | |
| 265 | goto change; | |
| 266 | else if(cn.track_count >= tracks && cc.track_count < tracks) | |
| 267 | goto dont_change; | |
| 268 | ||
| 269 | // Both are on the same side of the track count, so closest is best | |
| 270 | if(cc.track_count < tracks && cn.track_count > cc.track_count) | |
| 271 | goto change; | |
| 272 | if(cc.track_count >= tracks && cn.track_count < cc.track_count) | |
| 273 | goto change; | |
| 274 | goto dont_change; | |
| 275 | ||
| 276 | change: | |
| 277 | chosen_candidate = candidates[i]; | |
| 278 | dont_change: | |
| 279 | ; | |
| 280 | } | |
| 281 | // We have a winner, bail out | |
| 282 | break; | |
| 283 | } | |
| 284 | ||
| 285 | // No match, pick the first one and be done with it | |
| 286 | if(chosen_candidate == -1) | |
| 287 | chosen_candidate = 0; | |
| 288 | ||
| 289 | ||
| 290 | const format &f = formats[chosen_candidate]; | |
| 291 | int track_size = compute_track_size(f); | |
| 292 | ||
| 293 | UINT8 sectdata[40*512]; | |
| 294 | desc_s sectors[40]; | |
| 295 | build_sector_description(f, sectdata, sectors); | |
| 296 | ||
| 297 | for(int track=0; track < f.track_count; track++) | |
| 298 | for(int head=0; head < f.head_count; head++) { | |
| 299 | extract_sectors(image, f, sectors, track, head); | |
| 300 | io_generic_write(io, sectdata, (track*f.head_count + head)*track_size, track_size); | |
| 301 | } | |
| 302 | ||
| 187 | 303 | return true; |
| 188 | 304 | } |
| 189 | 305 | |
| 190 | ||
| 306 | void upd765_format::check_compatibility(floppy_image *image, int *candidates, int &candidates_count) | |
| 191 | 307 | { |
| 192 | return true; | |
| 308 | UINT8 bitstream[500000/8]; | |
| 309 | UINT8 sectdata[50000]; | |
| 310 | desc_xs sectors[256]; | |
| 311 | int track_size; | |
| 312 | ||
| 313 | // Extract the sectors | |
| 314 | generate_bitstream_from_track(0, 0, formats[candidates[0]].cell_size, bitstream, track_size, image); | |
| 315 | extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); | |
| 316 | ||
| 317 | // Check compatibility with every candidate, copy in-place | |
| 318 | int *ok_cands = candidates; | |
| 319 | for(int i=0; i != candidates_count; i++) { | |
| 320 | const format &f = formats[candidates[i]]; | |
| 321 | int ns = 0; | |
| 322 | for(int j=0; j<256; j++) | |
| 323 | if(sectors[j].data) { | |
| 324 | int sid; | |
| 325 | if(f.sector_base_id == -1) { | |
| 326 | for(sid=0; sid < f.sector_count; sid++) | |
| 327 | if(f.per_sector_id[sid] == j) | |
| 328 | break; | |
| 329 | } else | |
| 330 | sid = j - f.sector_base_id; | |
| 331 | if(sid < 0 || sid > f.sector_count) | |
| 332 | goto fail; | |
| 333 | if(f.sector_base_size) { | |
| 334 | if(sectors[j].size != f.sector_base_size) | |
| 335 | goto fail; | |
| 336 | } else { | |
| 337 | if(sectors[j].size != f.per_sector_size[sid]) | |
| 338 | goto fail; | |
| 339 | } | |
| 340 | ns++; | |
| 341 | } | |
| 342 | if(ns == f.sector_count) | |
| 343 | *ok_cands++ = candidates[i]; | |
| 344 | fail: | |
| 345 | ; | |
| 346 | } | |
| 347 | candidates_count = ok_cands - candidates; | |
| 193 | 348 | } |
| 194 | 349 | |
| 350 | ||
| 351 | void upd765_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head) | |
| 352 | { | |
| 353 | UINT8 bitstream[500000/8]; | |
| 354 | UINT8 sectdata[50000]; | |
| 355 | desc_xs sectors[256]; | |
| 356 | int track_size; | |
| 357 | ||
| 358 | // Extract the sectors | |
| 359 | generate_bitstream_from_track(track, head, f.cell_size, bitstream, track_size, image); | |
| 360 | extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); | |
| 361 | ||
| 362 | for(int i=0; i<f.sector_count; i++) { | |
| 363 | desc_s &ds = sdesc[i]; | |
| 364 | desc_xs &xs = sectors[ds.sector_id]; | |
| 365 | if(!xs.data) | |
| 366 | memset((void *)ds.data, 0, ds.size); | |
| 367 | else if(xs.size < ds.size) { | |
| 368 | memcpy((void *)ds.data, xs.data, xs.size); | |
| 369 | memset((UINT8 *)ds.data + xs.size, 0, xs.size - ds.size); | |
| 370 | } else | |
| 371 | memcpy((void *)ds.data, xs.data, ds.size); | |
| 372 | } | |
| 373 | } |
| r18419 | r18420 | |
|---|---|---|
| 43 | 43 | private: |
| 44 | 44 | const format *formats; |
| 45 | 45 | int find_size(io_generic *io, UINT32 form_factor); |
| 46 | int compute_track_size(const format &f) const; | |
| 47 | void build_sector_description(const format &d, UINT8 *sectdata, desc_s *sectors) const; | |
| 48 | void check_compatibility(floppy_image *image, int *candidates, int &candidates_count); | |
| 49 | void extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head); | |
| 46 | 50 | }; |
| 47 | 51 | |
| 48 | 52 | #endif /* UPD765_DSK_H */ |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/bw12_dsk.c | |
| 37 | ||
| 38 | bw12 format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/bw12_dsk.h" | |
| 44 | ||
| 45 | bw12_format::bw12_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *bw12_format::name() const | |
| 50 | { | |
| 51 | return "bw12"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *bw12_format::description() const | |
| 55 | { | |
| 56 | return "Bronwell 12/14 disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *bw12_format::extensions() const | |
| 60 | { | |
| 61 | return "dsk"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | const bw12_format::format bw12_format::formats[] = { | |
| 66 | { // 180KB BW 12 | |
| 67 | floppy_image::FF_525, floppy_image::SSDD, | |
| 68 | 2000, // 2us, 300rpm | |
| 69 | 18, 40, 1, | |
| 70 | 256, {}, | |
| 71 | 0, {}, | |
| 72 | 80, 50, 22, 80 | |
| 73 | }, | |
| 74 | { // 360KB BW 12 | |
| 75 | floppy_image::FF_525, floppy_image::DSDD, | |
| 76 | 2000, // 2us, 300rpm | |
| 77 | 18, 40, 2, | |
| 78 | 256, {}, | |
| 79 | 0, {}, | |
| 80 | 80, 50, 22, 80 | |
| 81 | }, | |
| 82 | { // SVI-328 | |
| 83 | floppy_image::FF_525, floppy_image::SSDD, | |
| 84 | 2000, // 2us, 300rpm | |
| 85 | 17, 40, 1, | |
| 86 | 256, {}, | |
| 87 | 0, {}, | |
| 88 | 80, 50, 22, 80 | |
| 89 | }, | |
| 90 | { // SVI-328 | |
| 91 | floppy_image::FF_525, floppy_image::DSDD, | |
| 92 | 2000, // 2us, 300rpm | |
| 93 | 17, 40, 2, | |
| 94 | 256, {}, | |
| 95 | 0, {}, | |
| 96 | 80, 50, 22, 80 | |
| 97 | }, | |
| 98 | { // Kaypro II | |
| 99 | floppy_image::FF_525, floppy_image::SSDD, | |
| 100 | 2000, // 2us, 300rpm | |
| 101 | 10, 40, 1, | |
| 102 | 512, {}, | |
| 103 | 0, {}, | |
| 104 | 80, 50, 22, 80 | |
| 105 | }, | |
| 106 | {} | |
| 107 | }; | |
| 108 | ||
| 109 | const floppy_format_type FLOPPY_BW12_FORMAT = &floppy_image_format_creator<bw12_format>; |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/bw12_dsk.h | |
| 4 | ||
| 5 | Bonwell 12/14 format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef BW12_DSK_H_ | |
| 10 | #define BW12_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class bw12_format : public upd765_format { | |
| 15 | public: | |
| 16 | bw12_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_BW12_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/apollo_dsk.c | |
| 37 | ||
| 38 | apollo format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/apollo_dsk.h" | |
| 44 | ||
| 45 | apollo_format::apollo_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *apollo_format::name() const | |
| 50 | { | |
| 51 | return "apollo"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *apollo_format::description() const | |
| 55 | { | |
| 56 | return "APOLLO disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *apollo_format::extensions() const | |
| 60 | { | |
| 61 | return "afd"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | const apollo_format::format apollo_format::formats[] = { | |
| 66 | { | |
| 67 | floppy_image::FF_525, floppy_image::DSHD, | |
| 68 | 1200, // 1us, 360rpm | |
| 69 | 8, 77, 2, | |
| 70 | 1024, {}, | |
| 71 | 1, {}, | |
| 72 | 80, 50, 22, 80 | |
| 73 | }, | |
| 74 | {} | |
| 75 | }; | |
| 76 | ||
| 77 | const floppy_format_type FLOPPY_APOLLO_FORMAT = &floppy_image_format_creator<apollo_format>; |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/a5105_dsk.c | |
| 37 | ||
| 38 | a5105 format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/a5105_dsk.h" | |
| 44 | ||
| 45 | a5105_format::a5105_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *a5105_format::name() const | |
| 50 | { | |
| 51 | return "a5105"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *a5105_format::description() const | |
| 55 | { | |
| 56 | return "A5105 disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *a5105_format::extensions() const | |
| 60 | { | |
| 61 | return "img"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | const a5105_format::format a5105_format::formats[] = { | |
| 66 | { | |
| 67 | floppy_image::FF_525, floppy_image::DSQD, | |
| 68 | 2000, // 2us, 300rpm | |
| 69 | 5, 80, 2, | |
| 70 | 1024, {}, | |
| 71 | 1, {}, | |
| 72 | 80, 50, 22, 80 | |
| 73 | }, | |
| 74 | {} | |
| 75 | }; | |
| 76 | ||
| 77 | const floppy_format_type FLOPPY_A5105_FORMAT = &floppy_image_format_creator<a5105_format>; |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/apollo_dsk.h | |
| 4 | ||
| 5 | apollo format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef APOLLO_DSK_H_ | |
| 10 | #define APOLLO_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class apollo_format : public upd765_format { | |
| 15 | public: | |
| 16 | apollo_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_APOLLO_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/a5105_dsk.h | |
| 4 | ||
| 5 | a5105 format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef A5105_DSK_H_ | |
| 10 | #define A5105_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class a5105_format : public upd765_format { | |
| 15 | public: | |
| 16 | a5105_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_A5105_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/pyldin_dsk.c | |
| 37 | ||
| 38 | pyldin format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/pyldin_dsk.h" | |
| 44 | ||
| 45 | pyldin_format::pyldin_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *pyldin_format::name() const | |
| 50 | { | |
| 51 | return "pyldin"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *pyldin_format::description() const | |
| 55 | { | |
| 56 | return "PYLDIN disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *pyldin_format::extensions() const | |
| 60 | { | |
| 61 | return "img"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | // 720K on HD which handles 1.2M, really? | |
| 66 | const pyldin_format::format pyldin_format::formats[] = { | |
| 67 | { | |
| 68 | floppy_image::FF_525, floppy_image::DSHD, | |
| 69 | 1200, // 1us, 360rpm | |
| 70 | 9, 80, 2, | |
| 71 | 512, {}, | |
| 72 | 1, {}, | |
| 73 | 80, 50, 22, 80 | |
| 74 | }, | |
| 75 | {} | |
| 76 | }; | |
| 77 | ||
| 78 | const floppy_format_type FLOPPY_PYLDIN_FORMAT = &floppy_image_format_creator<pyldin_format>; |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/iq151_dsk.c | |
| 37 | ||
| 38 | iq151 format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/iq151_dsk.h" | |
| 44 | ||
| 45 | iq151_format::iq151_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *iq151_format::name() const | |
| 50 | { | |
| 51 | return "iq151"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *iq151_format::description() const | |
| 55 | { | |
| 56 | return "IQ151 disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *iq151_format::extensions() const | |
| 60 | { | |
| 61 | return "iqd"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes. May be FM. | |
| 65 | const iq151_format::format iq151_format::formats[] = { | |
| 66 | { | |
| 67 | floppy_image::FF_8, floppy_image::SSSD, | |
| 68 | 2000, // maybe | |
| 69 | 26, 77, 1, | |
| 70 | 128, {}, | |
| 71 | 1, {}, | |
| 72 | 80, 50, 22, 80 | |
| 73 | }, | |
| 74 | {} | |
| 75 | }; | |
| 76 | ||
| 77 | const floppy_format_type FLOPPY_IQ151_FORMAT = &floppy_image_format_creator<iq151_format>; |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/pyldin_dsk.h | |
| 4 | ||
| 5 | pyldin format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef PYLDIN_DSK_H_ | |
| 10 | #define PYLDIN_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class pyldin_format : public upd765_format { | |
| 15 | public: | |
| 16 | pyldin_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_PYLDIN_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/iq151_dsk.h | |
| 4 | ||
| 5 | iq151 format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef IQ151_DSK_H_ | |
| 10 | #define IQ151_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class iq151_format : public upd765_format { | |
| 15 | public: | |
| 16 | iq151_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_IQ151_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/m5_dsk.c | |
| 37 | ||
| 38 | sord m5 format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/m5_dsk.h" | |
| 44 | ||
| 45 | m5_format::m5_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *m5_format::name() const | |
| 50 | { | |
| 51 | return "m5"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *m5_format::description() const | |
| 55 | { | |
| 56 | return "Sord M5 disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *m5_format::extensions() const | |
| 60 | { | |
| 61 | return "dsk"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | const m5_format::format m5_format::formats[] = { | |
| 66 | { | |
| 67 | floppy_image::FF_525, floppy_image::DSDD, | |
| 68 | 2000, // 2us, 300rpm | |
| 69 | 18, 40, 2, | |
| 70 | 256, {}, | |
| 71 | 1, {}, | |
| 72 | 80, 50, 22, 80 | |
| 73 | }, | |
| 74 | {} | |
| 75 | }; | |
| 76 | ||
| 77 | const floppy_format_type FLOPPY_M5_FORMAT = &floppy_image_format_creator<m5_format>; |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/m5_dsk.h | |
| 4 | ||
| 5 | sord m5 format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef M5_DSK_H_ | |
| 10 | #define M5_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class m5_format : public upd765_format { | |
| 15 | public: | |
| 16 | m5_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_M5_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/kc85_dsk.c | |
| 37 | ||
| 38 | kc85 format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/kc85_dsk.h" | |
| 44 | ||
| 45 | kc85_format::kc85_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *kc85_format::name() const | |
| 50 | { | |
| 51 | return "kc85"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *kc85_format::description() const | |
| 55 | { | |
| 56 | return "KC85 disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *kc85_format::extensions() const | |
| 60 | { | |
| 61 | return "img"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | // 640-800K on HD which handles 1.2M, really? | |
| 66 | const kc85_format::format kc85_format::formats[] = { | |
| 67 | { | |
| 68 | floppy_image::FF_525, floppy_image::DSHD, | |
| 69 | 1200, // 1us, 360rpm | |
| 70 | 5, 80, 2, | |
| 71 | 1024, {}, | |
| 72 | 1, {}, | |
| 73 | 80, 50, 22, 80 | |
| 74 | }, | |
| 75 | { | |
| 76 | floppy_image::FF_525, floppy_image::DSHD, | |
| 77 | 1200, // 1us, 360rpm | |
| 78 | 9, 80, 2, | |
| 79 | 512, {}, | |
| 80 | 1, {}, | |
| 81 | 80, 50, 22, 80 | |
| 82 | }, | |
| 83 | { | |
| 84 | floppy_image::FF_525, floppy_image::DSHD, | |
| 85 | 1200, // 1us, 360rpm | |
| 86 | 16, 80, 2, | |
| 87 | 256, {}, | |
| 88 | 1, {}, | |
| 89 | 80, 50, 22, 80 | |
| 90 | }, | |
| 91 | {} | |
| 92 | }; | |
| 93 | ||
| 94 | const floppy_format_type FLOPPY_KC85_FORMAT = &floppy_image_format_creator<kc85_format>; |
| r18419 | r18420 | |
|---|---|---|
| 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 | ||
| 34 | /********************************************************************* | |
| 35 | ||
| 36 | formats/nanos_dsk.c | |
| 37 | ||
| 38 | nanos format | |
| 39 | ||
| 40 | *********************************************************************/ | |
| 41 | ||
| 42 | #include "emu.h" | |
| 43 | #include "formats/nanos_dsk.h" | |
| 44 | ||
| 45 | nanos_format::nanos_format() : upd765_format(formats) | |
| 46 | { | |
| 47 | } | |
| 48 | ||
| 49 | const char *nanos_format::name() const | |
| 50 | { | |
| 51 | return "nanos"; | |
| 52 | } | |
| 53 | ||
| 54 | const char *nanos_format::description() const | |
| 55 | { | |
| 56 | return "NANOS disk image"; | |
| 57 | } | |
| 58 | ||
| 59 | const char *nanos_format::extensions() const | |
| 60 | { | |
| 61 | return "img"; | |
| 62 | } | |
| 63 | ||
| 64 | // Unverified gap sizes | |
| 65 | // 800K on HD which handles 1.2M, really? | |
| 66 | const nanos_format::format nanos_format::formats[] = { | |
| 67 | { | |
| 68 | floppy_image::FF_525, floppy_image::DSHD, | |
| 69 | 1200, // 1us, 360rpm | |
| 70 | 5, 80, 2, | |
| 71 | 1024, {}, | |
| 72 | 1, {}, | |
| 73 | 80, 50, 22, 80 | |
| 74 | }, | |
| 75 | {} | |
| 76 | }; | |
| 77 | ||
| 78 | const floppy_format_type FLOPPY_NANOS_FORMAT = &floppy_image_format_creator<nanos_format>; |
| r18419 | r18420 | |
|---|---|---|
| 1 | /********************************************************************* | |
| 2 | ||
| 3 | formats/kc85_dsk.h | |
| 4 | ||
| 5 | kc85 format | |
| 6 | ||
| 7 | *********************************************************************/ | |
| 8 | ||
| 9 | #ifndef KC85_DSK_H_ | |
| 10 | #define KC85_DSK_H_ | |
| 11 | ||
| 12 | #include "upd765_dsk.h" | |
| 13 | ||
| 14 | class kc85_format : public upd765_format { | |
| 15 | public: | |
| 16 | kc85_format(); | |
| 17 | ||
| 18 | virtual const char *name() const; | |
| 19 | virtual const char *description() const; | |
| 20 | virtual const char *extensions() const; | |
| 21 | ||
| 22 | private: | |
| 23 | static const format formats[]; | |
| 24 | }; | |
| 25 | ||
| 26 | extern const floppy_format_type FLOPPY_KC85_FORMAT; | |
| 27 | ||
| 28 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 30 | 30 | |
| 31 | 31 | #include "formats/dsk_dsk.h" |
| 32 | 32 | |
| 33 | #include "formats/d88_dsk.h" | |
| 33 | 34 | #include "formats/pc_dsk.h" |
| 34 | 35 | |
| 35 | 36 | #include "formats/ap_dsk35.h" |
| r18419 | r18420 | |
| 49 | 50 | |
| 50 | 51 | FLOPPY_DSK_FORMAT, |
| 51 | 52 | |
| 53 | FLOPPY_D88_FORMAT, | |
| 52 | 54 | FLOPPY_PC_FORMAT, |
| 53 | 55 | |
| 54 | 56 | FLOPPY_DC42_FORMAT, |
| r18419 | r18420 | |
|---|---|---|
| 1 | ||
| 2 | #include "n82077aa.h" | |
| 3 | ||
| 4 | const device_type N82077AA = &device_creator<n82077aa_device>; | |
| 5 | ||
| 6 | DEVICE_ADDRESS_MAP_START(amap, 8, n82077aa_device) | |
| 7 | AM_RANGE(0x0, 0x0) AM_READ(sra_r) | |
| 8 | AM_RANGE(0x1, 0x1) AM_READ(srb_r) | |
| 9 | AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w) | |
| 10 | AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w) | |
| 11 | AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w) | |
| 12 | AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w) | |
| 13 | AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w) | |
| 14 | ADDRESS_MAP_END | |
| 15 | ||
| 16 | int n82077aa_device::rates[4] = { 500000, 300000, 250000, 1000000 }; | |
| 17 | ||
| 18 | n82077aa_device::n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, N82077AA, "N82077AA", tag, owner, clock) | |
| 19 | { | |
| 20 | } | |
| 21 | ||
| 22 | void n82077aa_device::set_mode(int _mode) | |
| 23 | { | |
| 24 | mode = _mode; | |
| 25 | } | |
| 26 | ||
| 27 | void n82077aa_device::setup_intrq_cb(line_cb cb) | |
| 28 | { | |
| 29 | intrq_cb = cb; | |
| 30 | } | |
| 31 | ||
| 32 | void n82077aa_device::setup_drq_cb(line_cb cb) | |
| 33 | { | |
| 34 | drq_cb = cb; | |
| 35 | } | |
| 36 | ||
| 37 | void n82077aa_device::device_start() | |
| 38 | { | |
| 39 | static const char *names[] = { "fd0", "fd1", "fd2", "fd3" }; | |
| 40 | for(int i=0; i != 4; i++) { | |
| 41 | flopi[i].tm = timer_alloc(i); | |
| 42 | flopi[i].id = i; | |
| 43 | floppy_connector *con = machine().device<floppy_connector>(names[i]); | |
| 44 | if(con) { | |
| 45 | flopi[i].dev = con->get_device(); | |
| 46 | flopi[i].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(n82077aa_device::index_callback), this)); | |
| 47 | } else | |
| 48 | flopi[i].dev = 0; | |
| 49 | } | |
| 50 | } | |
| 51 | ||
| 52 | void n82077aa_device::device_reset() | |
| 53 | { | |
| 54 | main_phase = PHASE_CMD; | |
| 55 | for(int i=0; i<4; i++) { | |
| 56 | flopi[i].main_state = IDLE; | |
| 57 | flopi[i].sub_state = IDLE; | |
| 58 | flopi[i].irq = false; | |
| 59 | flopi[i].live = false; | |
| 60 | } | |
| 61 | data_irq = false; | |
| 62 | dor = 0x00; | |
| 63 | fifo_pos = 0; | |
| 64 | command_pos = 0; | |
| 65 | result_pos = 0; | |
| 66 | fifocfg = 0x10; | |
| 67 | cur_live.fi = 0; | |
| 68 | cur_irq = false; | |
| 69 | drq = false; | |
| 70 | live_abort(); | |
| 71 | } | |
| 72 | ||
| 73 | READ8_MEMBER(n82077aa_device::sra_r) | |
| 74 | { | |
| 75 | UINT8 sra = 0; | |
| 76 | int fid = dor & 3; | |
| 77 | floppy_info &fi = flopi[fid]; | |
| 78 | if(fi.dir) | |
| 79 | sra |= 0x01; | |
| 80 | if(fi.index) | |
| 81 | sra |= 0x04; | |
| 82 | if((dsr & 3) == 0 || (dsr & 3) == 3) | |
| 83 | sra |= 0x08; | |
| 84 | if(fi.dev && fi.dev->trk00_r()) | |
| 85 | sra |= 0x10; | |
| 86 | if(fi.main_state == SEEK_WAIT_STEP_SIGNAL_TIME) | |
| 87 | sra |= 0x20; | |
| 88 | sra |= 0x40; | |
| 89 | if(cur_irq) | |
| 90 | sra |= 0x80; | |
| 91 | if(mode == MODE_M30) | |
| 92 | sra ^= 0x1f; | |
| 93 | return sra; | |
| 94 | } | |
| 95 | ||
| 96 | READ8_MEMBER(n82077aa_device::srb_r) | |
| 97 | { | |
| 98 | return 0; | |
| 99 | } | |
| 100 | ||
| 101 | READ8_MEMBER(n82077aa_device::dor_r) | |
| 102 | { | |
| 103 | return dor; | |
| 104 | } | |
| 105 | ||
| 106 | WRITE8_MEMBER(n82077aa_device::dor_w) | |
| 107 | { | |
| 108 | UINT8 diff = dor ^ data; | |
| 109 | dor = data; | |
| 110 | if((diff & 4) && !(data & 4)) | |
| 111 | device_reset(); | |
| 112 | else | |
| 113 | for(int i=0; i<4; i++) { | |
| 114 | floppy_info &fi = flopi[i]; | |
| 115 | if(fi.dev && (diff & (0x10 << i))) | |
| 116 | fi.dev->mon_w(!(dor & (0x10 << i))); | |
| 117 | } | |
| 118 | ||
| 119 | } | |
| 120 | ||
| 121 | READ8_MEMBER(n82077aa_device::tdr_r) | |
| 122 | { | |
| 123 | return 0; | |
| 124 | } | |
| 125 | ||
| 126 | WRITE8_MEMBER(n82077aa_device::tdr_w) | |
| 127 | { | |
| 128 | } | |
| 129 | ||
| 130 | READ8_MEMBER(n82077aa_device::msr_r) | |
| 131 | { | |
| 132 | UINT32 msr = 0; | |
| 133 | switch(main_phase) { | |
| 134 | case PHASE_CMD: | |
| 135 | msr |= 0x80; | |
| 136 | if(command_pos) | |
| 137 | msr |= 0x10; | |
| 138 | break; | |
| 139 | case PHASE_EXEC: | |
| 140 | msr |= 0x10; | |
| 141 | break; | |
| 142 | ||
| 143 | case PHASE_RESULT: | |
| 144 | msr |= 0xd0; | |
| 145 | break; | |
| 146 | } | |
| 147 | for(int i=0; i<4; i++) | |
| 148 | if(flopi[i].main_state == RECALIBRATE || flopi[i].main_state == SEEK) | |
| 149 | msr |= 1<<i; | |
| 150 | ||
| 151 | if(data_irq) { | |
| 152 | data_irq = false; | |
| 153 | check_irq(); | |
| 154 | } | |
| 155 | ||
| 156 | return msr; | |
| 157 | } | |
| 158 | ||
| 159 | WRITE8_MEMBER(n82077aa_device::dsr_w) | |
| 160 | { | |
| 161 | dsr = data; | |
| 162 | } | |
| 163 | ||
| 164 | READ8_MEMBER(n82077aa_device::fifo_r) | |
| 165 | { | |
| 166 | UINT8 r = 0; | |
| 167 | switch(main_phase) { | |
| 168 | case PHASE_RESULT: | |
| 169 | r = result[0]; | |
| 170 | result_pos--; | |
| 171 | memmove(result, result+1, result_pos); | |
| 172 | if(!result_pos) | |
| 173 | main_phase = PHASE_CMD; | |
| 174 | break; | |
| 175 | default: | |
| 176 | logerror("%s: fifo_r in phase %d\n", tag(), main_phase); | |
| 177 | // exit(1); | |
| 178 | } | |
| 179 | ||
| 180 | return r; | |
| 181 | } | |
| 182 | ||
| 183 | WRITE8_MEMBER(n82077aa_device::fifo_w) | |
| 184 | { | |
| 185 | switch(main_phase) { | |
| 186 | case PHASE_CMD: { | |
| 187 | command[command_pos++] = data; | |
| 188 | int cmd = check_command(); | |
| 189 | if(cmd == C_INCOMPLETE) | |
| 190 | break; | |
| 191 | if(cmd == C_INVALID) { | |
| 192 | logerror("%s: Invalid on %02x\n", tag(), command[0]); | |
| 193 | exit(1); | |
| 194 | command_pos = 0; | |
| 195 | return; | |
| 196 | } | |
| 197 | start_command(cmd); | |
| 198 | break; | |
| 199 | } | |
| 200 | default: | |
| 201 | logerror("%s: fifo_w in phase %d\n", tag(), main_phase); | |
| 202 | exit(1); | |
| 203 | } | |
| 204 | } | |
| 205 | ||
| 206 | READ8_MEMBER(n82077aa_device::dir_r) | |
| 207 | { | |
| 208 | return 0x78; | |
| 209 | } | |
| 210 | ||
| 211 | WRITE8_MEMBER(n82077aa_device::ccr_w) | |
| 212 | { | |
| 213 | dsr = (dsr & 0xfc) | (data & 3); | |
| 214 | } | |
| 215 | ||
| 216 | void n82077aa_device::set_drq(bool state) | |
| 217 | { | |
| 218 | if(state != drq) { | |
| 219 | drq = state; | |
| 220 | if(!drq_cb.isnull()) | |
| 221 | drq_cb(drq); | |
| 222 | } | |
| 223 | } | |
| 224 | ||
| 225 | bool n82077aa_device::get_drq() const | |
| 226 | { | |
| 227 | return drq; | |
| 228 | } | |
| 229 | ||
| 230 | void n82077aa_device::fifo_push(UINT8 data) | |
| 231 | { | |
| 232 | if(fifo_pos == 16) { | |
| 233 | logerror("%s: Overflow\n", tag()); | |
| 234 | return; | |
| 235 | } | |
| 236 | fifo[fifo_pos++] = data; | |
| 237 | fifo_expected--; | |
| 238 | if(!drq) { | |
| 239 | int thr = (fifocfg & 15)+1; | |
| 240 | if(!fifo_expected || fifo_pos >= thr || (fifocfg & 0x20)) | |
| 241 | set_drq(true); | |
| 242 | } | |
| 243 | } | |
| 244 | ||
| 245 | void n82077aa_device::fifo_expect(int size, bool write) | |
| 246 | { | |
| 247 | fifo_expected = size; | |
| 248 | fifo_write = write; | |
| 249 | } | |
| 250 | ||
| 251 | UINT8 n82077aa_device::dma_r() | |
| 252 | { | |
| 253 | if(!fifo_pos) | |
| 254 | return 0; | |
| 255 | UINT8 r = fifo[0]; | |
| 256 | fifo_pos--; | |
| 257 | memmove(fifo, fifo+1, fifo_pos); | |
| 258 | if(!fifo_pos) | |
| 259 | set_drq(false); | |
| 260 | return r; | |
| 261 | } | |
| 262 | ||
| 263 | void n82077aa_device::live_start(floppy_info &fi, int state) | |
| 264 | { | |
| 265 | cur_live.tm = machine().time(); | |
| 266 | cur_live.state = state; | |
| 267 | cur_live.next_state = -1; | |
| 268 | cur_live.fi = &fi; | |
| 269 | cur_live.shift_reg = 0; | |
| 270 | cur_live.crc = 0xffff; | |
| 271 | cur_live.bit_counter = 0; | |
| 272 | cur_live.data_separator_phase = false; | |
| 273 | cur_live.data_reg = 0; | |
| 274 | cur_live.previous_type = live_info::PT_NONE; | |
| 275 | cur_live.data_bit_context = false; | |
| 276 | cur_live.byte_counter = 0; | |
| 277 | cur_live.pll.reset(cur_live.tm); | |
| 278 | cur_live.pll.set_clock(attotime::from_hz(rates[dsr & 3]*2)); | |
| 279 | checkpoint_live = cur_live; | |
| 280 | fi.live = true; | |
| 281 | ||
| 282 | live_run(); | |
| 283 | } | |
| 284 | ||
| 285 | void n82077aa_device::checkpoint() | |
| 286 | { | |
| 287 | if(cur_live.fi) | |
| 288 | cur_live.pll.commit(cur_live.fi->dev, cur_live.tm); | |
| 289 | checkpoint_live = cur_live; | |
| 290 | } | |
| 291 | ||
| 292 | void n82077aa_device::rollback() | |
| 293 | { | |
| 294 | cur_live = checkpoint_live; | |
| 295 | } | |
| 296 | ||
| 297 | void n82077aa_device::live_delay(int state) | |
| 298 | { | |
| 299 | cur_live.next_state = state; | |
| 300 | if(cur_live.tm != machine().time()) | |
| 301 | cur_live.fi->tm->adjust(cur_live.tm - machine().time()); | |
| 302 | } | |
| 303 | ||
| 304 | void n82077aa_device::live_sync() | |
| 305 | { | |
| 306 | if(!cur_live.tm.is_never()) { | |
| 307 | if(cur_live.tm > machine().time()) { | |
| 308 | rollback(); | |
| 309 | live_run(machine().time()); | |
| 310 | cur_live.pll.commit(cur_live.fi->dev, cur_live.tm); | |
| 311 | } | |
| 312 | if(cur_live.tm == machine().time()) { | |
| 313 | cur_live.pll.commit(cur_live.fi->dev, cur_live.tm); | |
| 314 | if(cur_live.next_state != -1) { | |
| 315 | cur_live.state = cur_live.next_state; | |
| 316 | cur_live.next_state = -1; | |
| 317 | } | |
| 318 | if(cur_live.state == IDLE) { | |
| 319 | cur_live.tm = attotime::never; | |
| 320 | cur_live.fi->live = false; | |
| 321 | cur_live.fi = 0; | |
| 322 | } | |
| 323 | } | |
| 324 | cur_live.next_state = -1; | |
| 325 | checkpoint(); | |
| 326 | } | |
| 327 | } | |
| 328 | ||
| 329 | void n82077aa_device::live_abort() | |
| 330 | { | |
| 331 | ||
| 332 | if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) { | |
| 333 | rollback(); | |
| 334 | live_run(machine().time()); | |
| 335 | } | |
| 336 | ||
| 337 | if(cur_live.fi) { | |
| 338 | cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm); | |
| 339 | cur_live.fi->live = false; | |
| 340 | cur_live.fi = 0; | |
| 341 | } | |
| 342 | ||
| 343 | cur_live.tm = attotime::never; | |
| 344 | cur_live.state = IDLE; | |
| 345 | cur_live.next_state = -1; | |
| 346 | } | |
| 347 | ||
| 348 | void n82077aa_device::live_run(attotime limit) | |
| 349 | { | |
| 350 | if(cur_live.state == IDLE || cur_live.next_state != -1) | |
| 351 | return; | |
| 352 | ||
| 353 | if(limit == attotime::never) { | |
| 354 | if(cur_live.fi->dev) | |
| 355 | limit = cur_live.fi->dev->time_next_index(); | |
| 356 | if(limit == attotime::never) { | |
| 357 | // Happens when there's no disk or if the fdc is not | |
| 358 | // connected to a drive, hence no index pulse. Force a | |
| 359 | // sync from time to time in that case, so that the main | |
| 360 | // cpu timeout isn't too painful. Avoids looping into | |
| 361 | // infinity looking for data too. | |
| 362 | ||
| 363 | limit = machine().time() + attotime::from_msec(1); | |
| 364 | cur_live.fi->tm->adjust(attotime::from_msec(1)); | |
| 365 | } | |
| 366 | } | |
| 367 | ||
| 368 | for(;;) { | |
| 369 | switch(cur_live.state) { | |
| 370 | case SEARCH_ADDRESS_MARK_HEADER: | |
| 371 | if(read_one_bit(limit)) | |
| 372 | return; | |
| 373 | #if 0 | |
| 374 | fprintf(stderr, "%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 375 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 376 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 377 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 378 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 379 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 380 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 381 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 382 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 383 | cur_live.bit_counter); | |
| 384 | #endif | |
| 385 | ||
| 386 | if(cur_live.shift_reg == 0x4489) { | |
| 387 | cur_live.crc = 0x443b; | |
| 388 | cur_live.data_separator_phase = false; | |
| 389 | cur_live.bit_counter = 0; | |
| 390 | cur_live.state = READ_HEADER_BLOCK_HEADER; | |
| 391 | } | |
| 392 | break; | |
| 393 | ||
| 394 | case READ_HEADER_BLOCK_HEADER: { | |
| 395 | if(read_one_bit(limit)) | |
| 396 | return; | |
| 397 | #if 0 | |
| 398 | fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 399 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 400 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 401 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 402 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 403 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 404 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 405 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 406 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 407 | cur_live.bit_counter); | |
| 408 | #endif | |
| 409 | if(cur_live.bit_counter & 15) | |
| 410 | break; | |
| 411 | ||
| 412 | int slot = cur_live.bit_counter >> 4; | |
| 413 | ||
| 414 | if(slot < 3) { | |
| 415 | if(cur_live.shift_reg != 0x4489) | |
| 416 | cur_live.state = SEARCH_ADDRESS_MARK_HEADER; | |
| 417 | break; | |
| 418 | } | |
| 419 | if(cur_live.data_reg != 0xfe) { | |
| 420 | cur_live.state = SEARCH_ADDRESS_MARK_HEADER; | |
| 421 | break; | |
| 422 | } | |
| 423 | ||
| 424 | cur_live.bit_counter = 0; | |
| 425 | cur_live.state = READ_ID_BLOCK_TO_LOCAL; | |
| 426 | ||
| 427 | break; | |
| 428 | } | |
| 429 | ||
| 430 | case READ_ID_BLOCK_TO_LOCAL: { | |
| 431 | if(read_one_bit(limit)) | |
| 432 | return; | |
| 433 | if(cur_live.bit_counter & 15) | |
| 434 | break; | |
| 435 | int slot = (cur_live.bit_counter >> 4)-1; | |
| 436 | cur_live.idbuf[slot] = cur_live.data_reg; | |
| 437 | if(slot == 5) { | |
| 438 | live_delay(IDLE); | |
| 439 | return; | |
| 440 | } | |
| 441 | break; | |
| 442 | } | |
| 443 | ||
| 444 | case SEARCH_ADDRESS_MARK_DATA: | |
| 445 | if(read_one_bit(limit)) | |
| 446 | return; | |
| 447 | #if 0 | |
| 448 | fprintf(stderr, "%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 449 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 450 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 451 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 452 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 453 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 454 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 455 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 456 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 457 | cur_live.bit_counter >> 4, cur_live.bit_counter & 15); | |
| 458 | #endif | |
| 459 | if(cur_live.bit_counter > 43*16) { | |
| 460 | live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); | |
| 461 | return; | |
| 462 | } | |
| 463 | ||
| 464 | if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) { | |
| 465 | cur_live.crc = 0x443b; | |
| 466 | cur_live.data_separator_phase = false; | |
| 467 | cur_live.bit_counter = 0; | |
| 468 | cur_live.state = READ_DATA_BLOCK_HEADER; | |
| 469 | } | |
| 470 | break; | |
| 471 | ||
| 472 | case READ_DATA_BLOCK_HEADER: { | |
| 473 | if(read_one_bit(limit)) | |
| 474 | return; | |
| 475 | #if 0 | |
| 476 | fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 477 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 478 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 479 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 480 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 481 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 482 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 483 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 484 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 485 | cur_live.bit_counter); | |
| 486 | #endif | |
| 487 | if(cur_live.bit_counter & 15) | |
| 488 | break; | |
| 489 | ||
| 490 | int slot = cur_live.bit_counter >> 4; | |
| 491 | ||
| 492 | if(slot < 3) { | |
| 493 | if(cur_live.shift_reg != 0x4489) { | |
| 494 | live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); | |
| 495 | return; | |
| 496 | } | |
| 497 | break; | |
| 498 | } | |
| 499 | if(cur_live.data_reg != 0xfb && cur_live.data_reg != 0xfd) { | |
| 500 | live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); | |
| 501 | return; | |
| 502 | } | |
| 503 | ||
| 504 | cur_live.bit_counter = 0; | |
| 505 | cur_live.state = READ_SECTOR_DATA; | |
| 506 | break; | |
| 507 | } | |
| 508 | ||
| 509 | case SEARCH_ADDRESS_MARK_DATA_FAILED: | |
| 510 | // status |= S_RNF; | |
| 511 | cur_live.state = IDLE; | |
| 512 | return; | |
| 513 | ||
| 514 | case READ_SECTOR_DATA: { | |
| 515 | if(read_one_bit(limit)) | |
| 516 | return; | |
| 517 | if(cur_live.bit_counter & 15) | |
| 518 | break; | |
| 519 | int slot = (cur_live.bit_counter >> 4)-1; | |
| 520 | if(slot < sector_size) { | |
| 521 | // Sector data | |
| 522 | live_delay(READ_SECTOR_DATA_BYTE); | |
| 523 | return; | |
| 524 | ||
| 525 | } else if(slot < sector_size+2) { | |
| 526 | // CRC | |
| 527 | if(slot == sector_size+1) { | |
| 528 | live_delay(IDLE); | |
| 529 | return; | |
| 530 | } | |
| 531 | } | |
| 532 | ||
| 533 | break; | |
| 534 | } | |
| 535 | ||
| 536 | case READ_SECTOR_DATA_BYTE: | |
| 537 | fifo_push(cur_live.data_reg); | |
| 538 | cur_live.state = READ_SECTOR_DATA; | |
| 539 | checkpoint(); | |
| 540 | break; | |
| 541 | ||
| 542 | default: | |
| 543 | logerror("%s: Unknown live state %d\n", tts(cur_live.tm).cstr(), cur_live.state); | |
| 544 | return; | |
| 545 | } | |
| 546 | } | |
| 547 | } | |
| 548 | ||
| 549 | int n82077aa_device::check_command() | |
| 550 | { | |
| 551 | // 0.000010 read track | |
| 552 | // 00000011 specify | |
| 553 | // 00000100 sense drive status | |
| 554 | // ..000101 write data | |
| 555 | // ...00110 read data | |
| 556 | // 00000111 recalibrate | |
| 557 | // 00001000 sense interrupt status | |
| 558 | // ..001001 write deleted data | |
| 559 | // 0.001010 read id | |
| 560 | // ...01100 read deleted data | |
| 561 | // 0.001101 format track | |
| 562 | // 00001110 dumpreg | |
| 563 | // 00001111 seek | |
| 564 | // 00010000 version | |
| 565 | // ...10001 scan equal | |
| 566 | // 00010010 perpendicular mode | |
| 567 | // 00010011 configure | |
| 568 | // .0010100 lock | |
| 569 | // ...10110 verify | |
| 570 | // ...11001 scan low or equal | |
| 571 | // ...11101 scan high or equal | |
| 572 | // 1.001111 relative seek | |
| 573 | ||
| 574 | switch(command[0]) { | |
| 575 | case 0x03: | |
| 576 | return command_pos == 3 ? C_SPECIFY : C_INCOMPLETE; | |
| 577 | ||
| 578 | case 0x06: case 0x26: case 0x46: case 0x66: case 0x86: case 0xa6: case 0xc6: case 0xe6: | |
| 579 | return command_pos == 9 ? C_READ_DATA : C_INCOMPLETE; | |
| 580 | ||
| 581 | case 0x07: | |
| 582 | return command_pos == 2 ? C_RECALIBRATE : C_INCOMPLETE; | |
| 583 | ||
| 584 | case 0x08: | |
| 585 | return C_SENSE_INTERRUPT_STATUS; | |
| 586 | ||
| 587 | case 0x0a: case 0x4a: | |
| 588 | return command_pos == 2 ? C_READ_ID : C_INCOMPLETE; | |
| 589 | ||
| 590 | case 0x0f: | |
| 591 | return command_pos == 3 ? C_SEEK : C_INCOMPLETE; | |
| 592 | ||
| 593 | case 0x12: | |
| 594 | return command_pos == 2 ? C_PERPENDICULAR : C_INCOMPLETE; | |
| 595 | ||
| 596 | case 0x13: | |
| 597 | return command_pos == 4 ? C_CONFIGURE : C_INCOMPLETE; | |
| 598 | ||
| 599 | default: | |
| 600 | return C_INVALID; | |
| 601 | } | |
| 602 | } | |
| 603 | ||
| 604 | void n82077aa_device::start_command(int cmd) | |
| 605 | { | |
| 606 | command_pos = 0; | |
| 607 | result_pos = 0; | |
| 608 | main_phase = PHASE_EXEC; | |
| 609 | switch(cmd) { | |
| 610 | case C_CONFIGURE: | |
| 611 | logerror("%s: command configure %02x %02x %02x\n", | |
| 612 | tag(), | |
| 613 | command[1], command[2], command[3]); | |
| 614 | // byte 1 is ignored, byte 3 is precompensation-related | |
| 615 | fifocfg = command[2]; | |
| 616 | main_phase = PHASE_CMD; | |
| 617 | break; | |
| 618 | ||
| 619 | case C_PERPENDICULAR: | |
| 620 | logerror("%s: command perpendicular\n", tag()); | |
| 621 | main_phase = PHASE_CMD; | |
| 622 | break; | |
| 623 | ||
| 624 | case C_READ_DATA: | |
| 625 | read_data_start(flopi[command[1] & 3]); | |
| 626 | break; | |
| 627 | ||
| 628 | case C_READ_ID: | |
| 629 | read_id_start(flopi[command[1] & 3]); | |
| 630 | break; | |
| 631 | ||
| 632 | case C_RECALIBRATE: | |
| 633 | recalibrate_start(flopi[command[1] & 3]); | |
| 634 | main_phase = PHASE_CMD; | |
| 635 | break; | |
| 636 | ||
| 637 | case C_SEEK: | |
| 638 | seek_start(flopi[command[1] & 3]); | |
| 639 | main_phase = PHASE_CMD; | |
| 640 | break; | |
| 641 | ||
| 642 | case C_SENSE_INTERRUPT_STATUS: { | |
| 643 | logerror("%s: command sense interrupt status\n", tag()); | |
| 644 | main_phase = PHASE_RESULT; | |
| 645 | ||
| 646 | int fid; | |
| 647 | for(fid=0; fid<4 && !flopi[fid].irq; fid++); | |
| 648 | if(fid == 4) { | |
| 649 | result[0] = 0x80; | |
| 650 | result_pos = 1; | |
| 651 | break; | |
| 652 | } | |
| 653 | floppy_info &fi = flopi[fid]; | |
| 654 | fi.irq = false; | |
| 655 | result[0] = (fi.status << 6) | 0x20 | fid; | |
| 656 | result[1] = fi.pcn; | |
| 657 | result_pos = 2; | |
| 658 | check_irq(); | |
| 659 | break; | |
| 660 | } | |
| 661 | ||
| 662 | case C_SPECIFY: | |
| 663 | logerror("%s command specify %02x %02x\n", | |
| 664 | tag(), | |
| 665 | command[1], command[2]); | |
| 666 | spec = (command[1] << 8) | command[2]; | |
| 667 | main_phase = PHASE_CMD; | |
| 668 | break; | |
| 669 | ||
| 670 | default: | |
| 671 | fprintf(stderr, "start command %d\n", cmd); | |
| 672 | exit(1); | |
| 673 | } | |
| 674 | } | |
| 675 | ||
| 676 | void n82077aa_device::command_end(floppy_info &fi, bool data_completion, int status) | |
| 677 | { | |
| 678 | fi.main_state = fi.sub_state = IDLE; | |
| 679 | if(data_completion) | |
| 680 | data_irq = true; | |
| 681 | else | |
| 682 | fi.irq = true; | |
| 683 | fi.status = status; | |
| 684 | check_irq(); | |
| 685 | } | |
| 686 | ||
| 687 | void n82077aa_device::recalibrate_start(floppy_info &fi) | |
| 688 | { | |
| 689 | logerror("%s: command recalibrate\n", tag()); | |
| 690 | fi.main_state = RECALIBRATE; | |
| 691 | fi.sub_state = SEEK_WAIT_STEP_TIME_DONE; | |
| 692 | fi.dir = 1; | |
| 693 | seek_continue(fi); | |
| 694 | } | |
| 695 | ||
| 696 | void n82077aa_device::seek_start(floppy_info &fi) | |
| 697 | { | |
| 698 | logerror("%s: command seek %d\n", tag(), command[2]); | |
| 699 | fi.main_state = SEEK; | |
| 700 | fi.sub_state = SEEK_WAIT_STEP_TIME_DONE; | |
| 701 | fi.dir = fi.pcn > command[2] ? 1 : 0; | |
| 702 | seek_continue(fi); | |
| 703 | } | |
| 704 | ||
| 705 | void n82077aa_device::delay_cycles(emu_timer *tm, int cycles) | |
| 706 | { | |
| 707 | tm->adjust(attotime::from_double(double(cycles)/rates[dsr & 3])); | |
| 708 | } | |
| 709 | ||
| 710 | void n82077aa_device::seek_continue(floppy_info &fi) | |
| 711 | { | |
| 712 | for(;;) { | |
| 713 | switch(fi.sub_state) { | |
| 714 | case SEEK_MOVE: | |
| 715 | if(fi.dev) { | |
| 716 | fi.dev->dir_w(fi.dir); | |
| 717 | fi.dev->stp_w(0); | |
| 718 | } | |
| 719 | fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME; | |
| 720 | fi.tm->adjust(attotime::from_nsec(2500)); | |
| 721 | return; | |
| 722 | ||
| 723 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 724 | return; | |
| 725 | ||
| 726 | case SEEK_WAIT_STEP_SIGNAL_TIME_DONE: | |
| 727 | if(fi.dev) | |
| 728 | fi.dev->stp_w(1); | |
| 729 | ||
| 730 | if(fi.main_state == SEEK) { | |
| 731 | if(fi.pcn > command[2]) | |
| 732 | fi.pcn--; | |
| 733 | else | |
| 734 | fi.pcn++; | |
| 735 | } | |
| 736 | fi.sub_state = SEEK_WAIT_STEP_TIME; | |
| 737 | delay_cycles(fi.tm, 500*(16-(spec >> 12))); | |
| 738 | return; | |
| 739 | ||
| 740 | case SEEK_WAIT_STEP_TIME: | |
| 741 | return; | |
| 742 | ||
| 743 | case SEEK_WAIT_STEP_TIME_DONE: { | |
| 744 | bool done = false; | |
| 745 | switch(fi.main_state) { | |
| 746 | case RECALIBRATE: | |
| 747 | done = !fi.dev || !fi.dev->trk00_r(); | |
| 748 | if(done) | |
| 749 | fi.pcn = 0; | |
| 750 | break; | |
| 751 | case SEEK: | |
| 752 | done = fi.pcn == command[2]; | |
| 753 | break; | |
| 754 | } | |
| 755 | if(done) { | |
| 756 | command_end(fi, false, 0); | |
| 757 | return; | |
| 758 | } | |
| 759 | fi.sub_state = SEEK_MOVE; | |
| 760 | break; | |
| 761 | } | |
| 762 | } | |
| 763 | } | |
| 764 | } | |
| 765 | ||
| 766 | void n82077aa_device::read_data_start(floppy_info &fi) | |
| 767 | { | |
| 768 | fi.main_state = READ_DATA; | |
| 769 | fi.sub_state = HEAD_LOAD_DONE; | |
| 770 | ||
| 771 | logerror("%s: command read data%s%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", | |
| 772 | tag(), | |
| 773 | command[0] & 0x80 ? " mt" : "", | |
| 774 | command[0] & 0x40 ? " mfm" : "", | |
| 775 | command[0] & 0x20 ? " sk" : "", | |
| 776 | command[0], | |
| 777 | command[1], | |
| 778 | command[2], | |
| 779 | command[3], | |
| 780 | command[4], | |
| 781 | 128 << (command[5] & 7), | |
| 782 | command[6], | |
| 783 | command[7], | |
| 784 | command[8], | |
| 785 | rates[dsr & 3]); | |
| 786 | ||
| 787 | if(fi.dev) | |
| 788 | fi.dev->ss_w(command[1] & 4 ? 1 : 0); | |
| 789 | read_data_continue(fi); | |
| 790 | } | |
| 791 | ||
| 792 | void n82077aa_device::read_data_continue(floppy_info &fi) | |
| 793 | { | |
| 794 | for(;;) { | |
| 795 | switch(fi.sub_state) { | |
| 796 | case HEAD_LOAD_DONE: | |
| 797 | if(fi.pcn == command[2] || !(fifocfg & 0x40)) { | |
| 798 | fi.sub_state = SEEK_DONE; | |
| 799 | break; | |
| 800 | } | |
| 801 | if(fi.dev) { | |
| 802 | fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0); | |
| 803 | fi.dev->stp_w(0); | |
| 804 | } | |
| 805 | fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME; | |
| 806 | fi.tm->adjust(attotime::from_nsec(2500)); | |
| 807 | return; | |
| 808 | ||
| 809 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 810 | return; | |
| 811 | ||
| 812 | case SEEK_WAIT_STEP_SIGNAL_TIME_DONE: | |
| 813 | if(fi.dev) | |
| 814 | fi.dev->stp_w(1); | |
| 815 | ||
| 816 | fi.sub_state = SEEK_WAIT_STEP_TIME; | |
| 817 | delay_cycles(fi.tm, 500*(16-(spec >> 12))); | |
| 818 | return; | |
| 819 | ||
| 820 | case SEEK_WAIT_STEP_TIME: | |
| 821 | return; | |
| 822 | ||
| 823 | case SEEK_WAIT_STEP_TIME_DONE: | |
| 824 | if(fi.pcn > command[2]) | |
| 825 | fi.pcn--; | |
| 826 | else | |
| 827 | fi.pcn++; | |
| 828 | fi.sub_state = HEAD_LOAD_DONE; | |
| 829 | break; | |
| 830 | ||
| 831 | case SEEK_DONE: | |
| 832 | counter = 0; | |
| 833 | fi.sub_state = SCAN_ID; | |
| 834 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 835 | return; | |
| 836 | ||
| 837 | case SCAN_ID: | |
| 838 | if(!sector_matches()) { | |
| 839 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 840 | return; | |
| 841 | } | |
| 842 | if(cur_live.crc) { | |
| 843 | fprintf(stderr, "Header CRC error\n"); | |
| 844 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 845 | return; | |
| 846 | } | |
| 847 | sector_size = 128 << (cur_live.idbuf[3] & 3); | |
| 848 | fifo_expect(sector_size, false); | |
| 849 | fi.sub_state = SECTOR_READ; | |
| 850 | live_start(fi, SEARCH_ADDRESS_MARK_DATA); | |
| 851 | return; | |
| 852 | ||
| 853 | case SCAN_ID_FAILED: | |
| 854 | fprintf(stderr, "RNF\n"); | |
| 855 | command_end(fi, true, 1); | |
| 856 | return; | |
| 857 | ||
| 858 | case SECTOR_READ: | |
| 859 | if(cur_live.crc) { | |
| 860 | fprintf(stderr, "CRC error\n"); | |
| 861 | } | |
| 862 | if(command[4] < command[6]) { | |
| 863 | command[4]++; | |
| 864 | fi.sub_state = HEAD_LOAD_DONE; | |
| 865 | break; | |
| 866 | } | |
| 867 | ||
| 868 | main_phase = PHASE_RESULT; | |
| 869 | result[0] = 0; | |
| 870 | result[1] = 0; | |
| 871 | result[2] = 0; | |
| 872 | result[3] = command[2]; | |
| 873 | result[4] = command[3]; | |
| 874 | result[5] = command[4]; | |
| 875 | result[6] = command[5]; | |
| 876 | result_pos = 7; | |
| 877 | command_end(fi, true, 0); | |
| 878 | return; | |
| 879 | ||
| 880 | default: | |
| 881 | logerror("%s: read sector unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 882 | return; | |
| 883 | } | |
| 884 | } | |
| 885 | } | |
| 886 | ||
| 887 | void n82077aa_device::read_id_start(floppy_info &fi) | |
| 888 | { | |
| 889 | fi.main_state = READ_DATA; | |
| 890 | fi.sub_state = HEAD_LOAD_DONE; | |
| 891 | ||
| 892 | logerror("%s: command read id%s, rate=%d\n", | |
| 893 | tag(), | |
| 894 | command[0] & 0x40 ? " mfm" : "", | |
| 895 | rates[dsr & 3]); | |
| 896 | ||
| 897 | if(fi.dev) | |
| 898 | fi.dev->ss_w(command[1] & 4 ? 1 : 0); | |
| 899 | read_id_continue(fi); | |
| 900 | } | |
| 901 | ||
| 902 | void n82077aa_device::read_id_continue(floppy_info &fi) | |
| 903 | { | |
| 904 | for(;;) { | |
| 905 | switch(fi.sub_state) { | |
| 906 | case HEAD_LOAD_DONE: | |
| 907 | counter = 0; | |
| 908 | fi.sub_state = SCAN_ID; | |
| 909 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 910 | return; | |
| 911 | ||
| 912 | case SCAN_ID: | |
| 913 | if(cur_live.crc) { | |
| 914 | fprintf(stderr, "Header CRC error\n"); | |
| 915 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 916 | return; | |
| 917 | } | |
| 918 | ||
| 919 | main_phase = PHASE_RESULT; | |
| 920 | result[0] = 0; | |
| 921 | result[1] = 0; | |
| 922 | result[2] = 0; | |
| 923 | result[3] = cur_live.idbuf[0]; | |
| 924 | result[4] = cur_live.idbuf[1]; | |
| 925 | result[5] = cur_live.idbuf[2]; | |
| 926 | result[6] = cur_live.idbuf[3]; | |
| 927 | result_pos = 7; | |
| 928 | command_end(fi, true, 0); | |
| 929 | return; | |
| 930 | ||
| 931 | default: | |
| 932 | logerror("%s: read id unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 933 | return; | |
| 934 | } | |
| 935 | } | |
| 936 | } | |
| 937 | ||
| 938 | void n82077aa_device::check_irq() | |
| 939 | { | |
| 940 | bool old_irq = cur_irq; | |
| 941 | cur_irq = data_irq; | |
| 942 | for(int i=0; i<4; i++) | |
| 943 | cur_irq = cur_irq || flopi[i].irq; | |
| 944 | if(cur_irq != old_irq && !intrq_cb.isnull()) | |
| 945 | intrq_cb(cur_irq); | |
| 946 | } | |
| 947 | ||
| 948 | astring n82077aa_device::tts(attotime t) | |
| 949 | { | |
| 950 | char buf[256]; | |
| 951 | int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND; | |
| 952 | sprintf(buf, "%4d.%03d,%03d,%03d", int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000); | |
| 953 | return buf; | |
| 954 | } | |
| 955 | ||
| 956 | astring n82077aa_device::ttsn() | |
| 957 | { | |
| 958 | return tts(machine().time()); | |
| 959 | } | |
| 960 | ||
| 961 | void n82077aa_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) | |
| 962 | { | |
| 963 | live_sync(); | |
| 964 | ||
| 965 | floppy_info &fi = flopi[id]; | |
| 966 | switch(fi.sub_state) { | |
| 967 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 968 | fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME_DONE; | |
| 969 | break; | |
| 970 | case SEEK_WAIT_STEP_TIME: | |
| 971 | fi.sub_state = SEEK_WAIT_STEP_TIME_DONE; | |
| 972 | break; | |
| 973 | } | |
| 974 | ||
| 975 | general_continue(fi); | |
| 976 | } | |
| 977 | ||
| 978 | void n82077aa_device::index_callback(floppy_image_device *floppy, int state) | |
| 979 | { | |
| 980 | int fid; | |
| 981 | for(fid=0; fid<4; fid++) | |
| 982 | if(flopi[fid].dev == floppy) | |
| 983 | break; | |
| 984 | ||
| 985 | assert(fid != 4); | |
| 986 | floppy_info &fi = flopi[fid]; | |
| 987 | ||
| 988 | live_sync(); | |
| 989 | fi.index = state; | |
| 990 | ||
| 991 | if(!state) { | |
| 992 | general_continue(fi); | |
| 993 | return; | |
| 994 | } | |
| 995 | ||
| 996 | switch(fi.sub_state) { | |
| 997 | case IDLE: | |
| 998 | case SEEK_MOVE: | |
| 999 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 1000 | case SEEK_WAIT_STEP_SIGNAL_TIME_DONE: | |
| 1001 | case SEEK_WAIT_STEP_TIME: | |
| 1002 | case SEEK_WAIT_STEP_TIME_DONE: | |
| 1003 | case HEAD_LOAD_DONE: | |
| 1004 | case SCAN_ID_FAILED: | |
| 1005 | case SECTOR_READ: | |
| 1006 | break; | |
| 1007 | ||
| 1008 | case SCAN_ID: | |
| 1009 | counter++; | |
| 1010 | if(counter == 2) | |
| 1011 | fi.sub_state = SCAN_ID_FAILED; | |
| 1012 | break; | |
| 1013 | ||
| 1014 | default: | |
| 1015 | logerror("%s: Index pulse on unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 1016 | break; | |
| 1017 | } | |
| 1018 | ||
| 1019 | general_continue(fi); | |
| 1020 | } | |
| 1021 | ||
| 1022 | ||
| 1023 | void n82077aa_device::general_continue(floppy_info &fi) | |
| 1024 | { | |
| 1025 | if(fi.live && cur_live.state != IDLE) { | |
| 1026 | live_run(); | |
| 1027 | if(cur_live.state != IDLE) | |
| 1028 | return; | |
| 1029 | } | |
| 1030 | ||
| 1031 | switch(fi.main_state) { | |
| 1032 | case IDLE: | |
| 1033 | break; | |
| 1034 | ||
| 1035 | case RECALIBRATE: | |
| 1036 | case SEEK: | |
| 1037 | seek_continue(fi); | |
| 1038 | break; | |
| 1039 | ||
| 1040 | case READ_DATA: | |
| 1041 | read_data_continue(fi); | |
| 1042 | break; | |
| 1043 | ||
| 1044 | case READ_ID: | |
| 1045 | read_id_continue(fi); | |
| 1046 | break; | |
| 1047 | ||
| 1048 | default: | |
| 1049 | logerror("%s: general_continue on unknown main-state %d\n", ttsn().cstr(), fi.main_state); | |
| 1050 | break; | |
| 1051 | } | |
| 1052 | } | |
| 1053 | ||
| 1054 | bool n82077aa_device::read_one_bit(attotime limit) | |
| 1055 | { | |
| 1056 | int bit = cur_live.pll.get_next_bit(cur_live.tm, cur_live.fi->dev, limit); | |
| 1057 | if(bit < 0) | |
| 1058 | return true; | |
| 1059 | cur_live.shift_reg = (cur_live.shift_reg << 1) | bit; | |
| 1060 | cur_live.bit_counter++; | |
| 1061 | if(cur_live.data_separator_phase) { | |
| 1062 | cur_live.data_reg = (cur_live.data_reg << 1) | bit; | |
| 1063 | if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000) | |
| 1064 | cur_live.crc = (cur_live.crc << 1) ^ 0x1021; | |
| 1065 | else | |
| 1066 | cur_live.crc = cur_live.crc << 1; | |
| 1067 | } | |
| 1068 | cur_live.data_separator_phase = !cur_live.data_separator_phase; | |
| 1069 | return false; | |
| 1070 | } | |
| 1071 | ||
| 1072 | bool n82077aa_device::write_one_bit(attotime limit) | |
| 1073 | { | |
| 1074 | bool bit = cur_live.shift_reg & 0x8000; | |
| 1075 | if(cur_live.pll.write_next_bit(bit, cur_live.tm, cur_live.fi->dev, limit)) | |
| 1076 | return true; | |
| 1077 | if(cur_live.bit_counter & 1) { | |
| 1078 | if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000) | |
| 1079 | cur_live.crc = (cur_live.crc << 1) ^ 0x1021; | |
| 1080 | else | |
| 1081 | cur_live.crc = cur_live.crc << 1; | |
| 1082 | } | |
| 1083 | cur_live.shift_reg = cur_live.shift_reg << 1; | |
| 1084 | cur_live.bit_counter--; | |
| 1085 | return false; | |
| 1086 | } | |
| 1087 | ||
| 1088 | bool n82077aa_device::sector_matches() const | |
| 1089 | { | |
| 1090 | return | |
| 1091 | cur_live.idbuf[0] == command[2] && | |
| 1092 | cur_live.idbuf[1] == command[3] && | |
| 1093 | cur_live.idbuf[2] == command[4] && | |
| 1094 | cur_live.idbuf[3] == command[5]; | |
| 1095 | } | |
| 1096 | ||
| 1097 | void n82077aa_device::pll_t::set_clock(attotime _period) | |
| 1098 | { | |
| 1099 | period = _period; | |
| 1100 | period_adjust_base = period * 0.05; | |
| 1101 | min_period = period * 0.75; | |
| 1102 | max_period = period * 1.25; | |
| 1103 | } | |
| 1104 | ||
| 1105 | void n82077aa_device::pll_t::reset(attotime when) | |
| 1106 | { | |
| 1107 | ctime = when; | |
| 1108 | phase_adjust = attotime::zero; | |
| 1109 | freq_hist = 0; | |
| 1110 | write_position = 0; | |
| 1111 | write_start_time = attotime::never; | |
| 1112 | } | |
| 1113 | ||
| 1114 | void n82077aa_device::pll_t::start_writing(attotime tm) | |
| 1115 | { | |
| 1116 | write_start_time = tm; | |
| 1117 | write_position = 0; | |
| 1118 | } | |
| 1119 | ||
| 1120 | void n82077aa_device::pll_t::stop_writing(floppy_image_device *floppy, attotime tm) | |
| 1121 | { | |
| 1122 | commit(floppy, tm); | |
| 1123 | write_start_time = attotime::never; | |
| 1124 | } | |
| 1125 | ||
| 1126 | void n82077aa_device::pll_t::commit(floppy_image_device *floppy, attotime tm) | |
| 1127 | { | |
| 1128 | if(write_start_time.is_never() || tm == write_start_time) | |
| 1129 | return; | |
| 1130 | ||
| 1131 | if(floppy) | |
| 1132 | floppy->write_flux(write_start_time, tm, write_position, write_buffer); | |
| 1133 | write_start_time = tm; | |
| 1134 | write_position = 0; | |
| 1135 | } | |
| 1136 | ||
| 1137 | int n82077aa_device::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit) | |
| 1138 | { | |
| 1139 | attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never; | |
| 1140 | ||
| 1141 | attotime next = ctime + period + phase_adjust; | |
| 1142 | ||
| 1143 | #if 0 | |
| 1144 | if(!edge.is_never()) | |
| 1145 | fprintf(stderr, "transition_time=%s, next=%s\n", tts(edge).cstr(), tts(next).cstr()); | |
| 1146 | #endif | |
| 1147 | ||
| 1148 | if(next > limit) | |
| 1149 | return -1; | |
| 1150 | ||
| 1151 | ctime = next; | |
| 1152 | ||
| 1153 | if(edge.is_never() || edge >= next) { | |
| 1154 | // No transition in the window means 0 and pll in free run mode | |
| 1155 | phase_adjust = attotime::zero; | |
| 1156 | tm = next; | |
| 1157 | return 0; | |
| 1158 | } | |
| 1159 | ||
| 1160 | // Transition in the window means 1, and the pll is adjusted | |
| 1161 | ||
| 1162 | attotime delta = edge - (next - period/2); | |
| 1163 | ||
| 1164 | phase_adjust = 0.65*delta; | |
| 1165 | ||
| 1166 | if(delta < attotime::zero) { | |
| 1167 | if(freq_hist < 0) | |
| 1168 | freq_hist--; | |
| 1169 | else | |
| 1170 | freq_hist = -1; | |
| 1171 | } else if(delta > attotime::zero) { | |
| 1172 | if(freq_hist > 0) | |
| 1173 | freq_hist++; | |
| 1174 | else | |
| 1175 | freq_hist = 1; | |
| 1176 | } else | |
| 1177 | freq_hist = 0; | |
| 1178 | ||
| 1179 | if(freq_hist) { | |
| 1180 | int afh = freq_hist < 0 ? -freq_hist : freq_hist; | |
| 1181 | if(afh > 1) { | |
| 1182 | attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double()); | |
| 1183 | period += aper; | |
| 1184 | ||
| 1185 | if(period < min_period) | |
| 1186 | period = min_period; | |
| 1187 | else if(period > max_period) | |
| 1188 | period = max_period; | |
| 1189 | } | |
| 1190 | } | |
| 1191 | ||
| 1192 | return 1; | |
| 1193 | } | |
| 1194 | ||
| 1195 | bool n82077aa_device::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit) | |
| 1196 | { | |
| 1197 | if(write_start_time.is_never()) { | |
| 1198 | write_start_time = ctime; | |
| 1199 | write_position = 0; | |
| 1200 | } | |
| 1201 | ||
| 1202 | attotime etime = ctime + period; | |
| 1203 | if(etime > limit) | |
| 1204 | return true; | |
| 1205 | ||
| 1206 | if(write_position < ARRAY_LENGTH(write_buffer)) | |
| 1207 | write_buffer[write_position++] = ctime + period/2; | |
| 1208 | ||
| 1209 | tm = etime; | |
| 1210 | ctime = etime; | |
| 1211 | return false; | |
| 1212 | } |
| r18419 | r18420 | |
|---|---|---|
| 1 | #ifndef __N82077AA_H__ | |
| 2 | #define __N82077AA_H__ | |
| 3 | ||
| 4 | #include "emu.h" | |
| 5 | #include "imagedev/floppy.h" | |
| 6 | ||
| 7 | #define MCFG_N82077AA_ADD(_tag, _mode) \ | |
| 8 | MCFG_DEVICE_ADD(_tag, N82077AA, 0) \ | |
| 9 | downcast<n82077aa_device *>(device)->set_mode(_mode); | |
| 10 | ||
| 11 | class n82077aa_device : public device_t { | |
| 12 | public: | |
| 13 | typedef delegate<void (bool state)> line_cb; | |
| 14 | ||
| 15 | enum { MODE_AT, MODE_PS2, MODE_M30 }; | |
| 16 | ||
| 17 | n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 18 | void set_mode(int mode); | |
| 19 | void setup_intrq_cb(line_cb cb); | |
| 20 | void setup_drq_cb(line_cb cb); | |
| 21 | ||
| 22 | DECLARE_ADDRESS_MAP(amap, 8); | |
| 23 | ||
| 24 | DECLARE_READ8_MEMBER (sra_r); | |
| 25 | DECLARE_READ8_MEMBER (srb_r); | |
| 26 | DECLARE_READ8_MEMBER (dor_r); | |
| 27 | DECLARE_WRITE8_MEMBER(dor_w); | |
| 28 | DECLARE_READ8_MEMBER (tdr_r); | |
| 29 | DECLARE_WRITE8_MEMBER(tdr_w); | |
| 30 | DECLARE_READ8_MEMBER (msr_r); | |
| 31 | DECLARE_WRITE8_MEMBER(dsr_w); | |
| 32 | DECLARE_READ8_MEMBER (fifo_r); | |
| 33 | DECLARE_WRITE8_MEMBER(fifo_w); | |
| 34 | DECLARE_READ8_MEMBER (dir_r); | |
| 35 | DECLARE_WRITE8_MEMBER(ccr_w); | |
| 36 | ||
| 37 | UINT8 dma_r(); | |
| 38 | void dma_w(UINT8 data); | |
| 39 | bool get_drq() const; | |
| 40 | ||
| 41 | protected: | |
| 42 | virtual void device_start(); | |
| 43 | virtual void device_reset(); | |
| 44 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); | |
| 45 | ||
| 46 | private: | |
| 47 | enum { | |
| 48 | PHASE_CMD, PHASE_EXEC, PHASE_RESULT | |
| 49 | }; | |
| 50 | ||
| 51 | enum { | |
| 52 | // General "doing nothing" state | |
| 53 | IDLE, | |
| 54 | ||
| 55 | // Main states | |
| 56 | RECALIBRATE, | |
| 57 | SEEK, | |
| 58 | READ_DATA, | |
| 59 | READ_ID, | |
| 60 | ||
| 61 | // Sub-states | |
| 62 | SEEK_MOVE, | |
| 63 | SEEK_WAIT_STEP_SIGNAL_TIME, | |
| 64 | SEEK_WAIT_STEP_SIGNAL_TIME_DONE, | |
| 65 | SEEK_WAIT_STEP_TIME, | |
| 66 | SEEK_WAIT_STEP_TIME_DONE, | |
| 67 | SEEK_DONE, | |
| 68 | ||
| 69 | HEAD_LOAD_DONE, | |
| 70 | ||
| 71 | SCAN_ID, | |
| 72 | SCAN_ID_FAILED, | |
| 73 | ||
| 74 | SECTOR_READ, | |
| 75 | ||
| 76 | // Live states | |
| 77 | SEARCH_ADDRESS_MARK_HEADER, | |
| 78 | READ_HEADER_BLOCK_HEADER, | |
| 79 | READ_DATA_BLOCK_HEADER, | |
| 80 | READ_ID_BLOCK_TO_LOCAL, | |
| 81 | SEARCH_ADDRESS_MARK_DATA, | |
| 82 | SEARCH_ADDRESS_MARK_DATA_FAILED, | |
| 83 | READ_SECTOR_DATA, | |
| 84 | READ_SECTOR_DATA_BYTE, | |
| 85 | ||
| 86 | }; | |
| 87 | ||
| 88 | struct pll_t { | |
| 89 | attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust; | |
| 90 | ||
| 91 | attotime write_start_time; | |
| 92 | attotime write_buffer[32]; | |
| 93 | int write_position; | |
| 94 | int freq_hist; | |
| 95 | ||
| 96 | void set_clock(attotime period); | |
| 97 | void reset(attotime when); | |
| 98 | int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit); | |
| 99 | bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit); | |
| 100 | void start_writing(attotime tm); | |
| 101 | void commit(floppy_image_device *floppy, attotime tm); | |
| 102 | void stop_writing(floppy_image_device *floppy, attotime tm); | |
| 103 | }; | |
| 104 | ||
| 105 | struct floppy_info { | |
| 106 | emu_timer *tm; | |
| 107 | floppy_image_device *dev; | |
| 108 | int id; | |
| 109 | int main_state, sub_state; | |
| 110 | int dir, status; | |
| 111 | UINT8 pcn; | |
| 112 | bool irq, live, index; | |
| 113 | }; | |
| 114 | ||
| 115 | struct live_info { | |
| 116 | enum { PT_NONE, PT_CRC_1, PT_CRC_2 }; | |
| 117 | ||
| 118 | attotime tm; | |
| 119 | int state, next_state; | |
| 120 | floppy_info *fi; | |
| 121 | UINT16 shift_reg; | |
| 122 | UINT16 crc; | |
| 123 | int bit_counter, byte_counter, previous_type; | |
| 124 | bool data_separator_phase, data_bit_context; | |
| 125 | UINT8 data_reg; | |
| 126 | UINT8 idbuf[6]; | |
| 127 | pll_t pll; | |
| 128 | }; | |
| 129 | ||
| 130 | static int rates[4]; | |
| 131 | ||
| 132 | int mode; | |
| 133 | int main_phase; | |
| 134 | int counter; | |
| 135 | ||
| 136 | live_info cur_live, checkpoint_live; | |
| 137 | line_cb intrq_cb, drq_cb; | |
| 138 | bool cur_irq, data_irq, drq; | |
| 139 | floppy_info flopi[4]; | |
| 140 | ||
| 141 | int fifo_pos, fifo_expected, command_pos, result_pos; | |
| 142 | bool fifo_write; | |
| 143 | UINT8 dor, dsr, msr, fifo[16], command[16], result[16]; | |
| 144 | UINT8 fifocfg; | |
| 145 | UINT16 spec; | |
| 146 | int sector_size; | |
| 147 | ||
| 148 | static astring tts(attotime t); | |
| 149 | astring ttsn(); | |
| 150 | ||
| 151 | enum { | |
| 152 | C_CONFIGURE, | |
| 153 | C_PERPENDICULAR, | |
| 154 | C_READ_DATA, | |
| 155 | C_READ_ID, | |
| 156 | C_RECALIBRATE, | |
| 157 | C_SEEK, | |
| 158 | C_SENSE_INTERRUPT_STATUS, | |
| 159 | C_SPECIFY, | |
| 160 | ||
| 161 | C_INVALID, | |
| 162 | C_INCOMPLETE, | |
| 163 | }; | |
| 164 | ||
| 165 | void delay_cycles(emu_timer *tm, int cycles); | |
| 166 | void check_irq(); | |
| 167 | void fifo_expect(int size, bool write); | |
| 168 | void fifo_push(UINT8 data); | |
| 169 | void set_drq(bool state); | |
| 170 | ||
| 171 | int check_command(); | |
| 172 | void start_command(int cmd); | |
| 173 | void command_end(floppy_info &fi, bool data_completion, int status); | |
| 174 | ||
| 175 | void recalibrate_start(floppy_info &fi); | |
| 176 | void seek_start(floppy_info &fi); | |
| 177 | void seek_continue(floppy_info &fi); | |
| 178 | ||
| 179 | void read_data_start(floppy_info &fi); | |
| 180 | void read_data_continue(floppy_info &fi); | |
| 181 | ||
| 182 | void read_id_start(floppy_info &fi); | |
| 183 | void read_id_continue(floppy_info &fi); | |
| 184 | ||
| 185 | void general_continue(floppy_info &fi); | |
| 186 | void index_callback(floppy_image_device *floppy, int state); | |
| 187 | bool sector_matches() const; | |
| 188 | ||
| 189 | void live_start(floppy_info &fi, int live_state); | |
| 190 | void live_abort(); | |
| 191 | void checkpoint(); | |
| 192 | void rollback(); | |
| 193 | void live_delay(int state); | |
| 194 | void live_sync(); | |
| 195 | void live_run(attotime limit = attotime::never); | |
| 196 | ||
| 197 | bool read_one_bit(attotime limit); | |
| 198 | bool write_one_bit(attotime limit); | |
| 199 | }; | |
| 200 | ||
| 201 | extern const device_type N82077AA; | |
| 202 | ||
| 203 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 37 | 37 | #include "machine/pic8259.h" |
| 38 | 38 | |
| 39 | 39 | #include "machine/pc_fdc.h" |
| 40 | #include "formats/basicdsk.h" | |
| 40 | #include "formats/mfi_dsk.h" | |
| 41 | #include "formats/apollo_dsk.h" | |
| 41 | 42 | |
| 42 | 43 | #include "cpu/m68000/m68000.h" |
| 43 | 44 | //#include "cpu/m68000/m68kcpu.h" |
| r18419 | r18420 | |
| 526 | 527 | } |
| 527 | 528 | |
| 528 | 529 | static READ8_DEVICE_HANDLER( apollo_dma8237_fdc_dack_r ) { |
| 529 | UINT8 data = pc_fdc_dack_r(space.machine(), space); | |
| 530 | pc_fdc_at_device *fdc = space.machine().device<pc_fdc_at_device>(APOLLO_FDC_TAG); | |
| 531 | UINT8 data = fdc->dma_r(); | |
| 530 | 532 | // DLOG2(("dma fdc dack read %02x",data)); |
| 531 | 533 | |
| 532 | 534 | // hack for DN3000: select appropriate DMA channel No. |
| r18419 | r18420 | |
| 536 | 538 | } |
| 537 | 539 | |
| 538 | 540 | static WRITE8_DEVICE_HANDLER( apollo_dma8237_fdc_dack_w ) { |
| 541 | pc_fdc_at_device *fdc = space.machine().device<pc_fdc_at_device>(APOLLO_FDC_TAG); | |
| 539 | 542 | // DLOG2(("dma fdc dack write %02x", data)); |
| 540 | | |
| 543 | fdc->dma_w(data); | |
| 541 | 544 | |
| 542 | 545 | // hack for DN3000: select appropriate DMA channel No. |
| 543 | 546 | // Note: too late for this byte, but next bytes will be ok |
| r18419 | r18420 | |
| 556 | 559 | } |
| 557 | 560 | |
| 558 | 561 | static WRITE_LINE_DEVICE_HANDLER( apollo_dma8237_out_eop ) { |
| 562 | pc_fdc_at_device *fdc = device->machine().device<pc_fdc_at_device>(APOLLO_FDC_TAG); | |
| 559 | 563 | DLOG1(("dma out eop state %02x", state)); |
| 560 | | |
| 564 | fdc->tc_w(!state); | |
| 561 | 565 | sc499_set_tc_state(&device->machine(), state); |
| 562 | 566 | } |
| 563 | 567 | |
| r18419 | r18420 | |
| 1275 | 1279 | #undef VERBOSE |
| 1276 | 1280 | #define VERBOSE 0 |
| 1277 | 1281 | |
| 1278 | static device_t *apollo_fdc_device = NULL; | |
| 1279 | ||
| 1280 | static LEGACY_FLOPPY_OPTIONS_START( apollo ) | |
| 1281 | LEGACY_FLOPPY_OPTION( img2d, "afd", "Apollo floppy disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 1282 | HEADS([2]) | |
| 1283 | TRACKS([77]) | |
| 1284 | SECTORS([8]) | |
| 1285 | SECTOR_LENGTH([1024]) | |
| 1286 | FIRST_SECTOR_ID([1])) | |
| 1287 | LEGACY_FLOPPY_OPTIONS_END0 | |
| 1288 | ||
| 1289 | static const floppy_interface apollo_fdc_floppy_config = { // | |
| 1290 | DEVCB_NULL, // | |
| 1291 | DEVCB_NULL, // | |
| 1292 | DEVCB_NULL, // | |
| 1293 | DEVCB_NULL, // | |
| 1294 | DEVCB_NULL, // | |
| 1295 | FLOPPY_STANDARD_5_25_DSHD, // | |
| 1296 | LEGACY_FLOPPY_OPTIONS_NAME(apollo), // | |
| 1297 | NULL, // | |
| 1298 | NULL // | |
| 1282 | static const floppy_format_type apollo_floppy_formats[] = { | |
| 1283 | FLOPPY_APOLLO_FORMAT, | |
| 1284 | FLOPPY_MFI_FORMAT, | |
| 1285 | NULL | |
| 1299 | 1286 | }; |
| 1300 | 1287 | |
| 1301 | /************************************* | |
| 1302 | * Floppy Disk Controller | |
| 1303 | *************************************/ | |
| 1288 | static SLOT_INTERFACE_START( apollo_floppies ) | |
| 1289 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 1290 | SLOT_INTERFACE_END | |
| 1304 | 1291 | |
| 1305 | static void apollo_fdc_interrupt(running_machine &machine, int state) { | |
| 1306 | apollo_pic_set_irq_line( machine.firstcpu, APOLLO_IRQ_FDC, state); | |
| 1307 | } | |
| 1308 | 1292 | |
| 1309 | static void apollo_fdc_dma_drq(running_machine &machine, int state) { | |
| 1310 | apollo_dma_fdc_drq(machine.firstcpu, state); | |
| 1293 | void apollo_state::fdc_interrupt(bool state) { | |
| 1294 | apollo_pic_set_irq_line( machine().firstcpu, APOLLO_IRQ_FDC, state ? ASSERT_LINE : CLEAR_LINE); | |
| 1311 | 1295 | } |
| 1312 | 1296 | |
| 1313 | static device_t *apollo_fdc_get_image(running_machine &machine, | |
| 1314 | int floppy_index) { | |
| 1315 | return floppy_get_device(machine, 0); | |
| 1297 | void apollo_state::fdc_dma_drq(bool state) { | |
| 1298 | apollo_dma_fdc_drq(machine().firstcpu, state); | |
| 1316 | 1299 | } |
| 1317 | 1300 | |
| 1318 | static device_t * apollo_fdc_get_device(running_machine &machine) { | |
| 1319 | return apollo_fdc_device; | |
| 1320 | } | |
| 1321 | ||
| 1322 | static const struct pc_fdc_interface apollo_fdc_interface = { | |
| 1323 | apollo_fdc_interrupt, // | |
| 1324 | apollo_fdc_dma_drq, // | |
| 1325 | apollo_fdc_get_image, // | |
| 1326 | apollo_fdc_get_device // | |
| 1327 | }; | |
| 1328 | ||
| 1329 | /*------------------------------------------------- | |
| 1330 | FDC upd765 at 0x5f800 - 0x5f807 | |
| 1331 | -------------------------------------------------*/ | |
| 1332 | ||
| 1333 | static DEVICE_START( apollo_fdc ) { | |
| 1334 | DLOG1(("device_start_apollo_fdc")); | |
| 1335 | apollo_fdc_device = device; | |
| 1336 | pc_fdc_init(device->machine(), &apollo_fdc_interface); | |
| 1337 | } | |
| 1338 | ||
| 1339 | static DEVICE_RESET( apollo_fdc ) { | |
| 1340 | DLOG1(("device_reset_apollo_fdc")); | |
| 1341 | pc_fdc_reset(device->machine()); | |
| 1342 | } | |
| 1343 | ||
| 1344 | WRITE8_MEMBER(apollo_state::apollo_fdc_w){ | |
| 1345 | SLOG1(("writing FDC upd765 at offset %X = %02x", offset, data)); | |
| 1346 | pc_fdc_w(space, offset, data); | |
| 1347 | } | |
| 1348 | ||
| 1349 | READ8_MEMBER(apollo_state::apollo_fdc_r){ | |
| 1350 | UINT8 data = pc_fdc_r(space, offset); | |
| 1351 | SLOG1(("reading FDC upd765 at offset %X = %02x", offset, data)); | |
| 1352 | return data; | |
| 1353 | } | |
| 1354 | ||
| 1355 | 1301 | /*************************************************************************** |
| 1356 | 1302 | DN3500 3c505 DEVICE Configuration |
| 1357 | 1303 | ***************************************************************************/ |
| r18419 | r18420 | |
| 1452 | 1398 | MCFG_DUART68681_ADD( APOLLO_SIO_TAG, XTAL_3_6864MHz, apollo_sio_config ) |
| 1453 | 1399 | MCFG_DUART68681_ADD( APOLLO_SIO2_TAG, XTAL_3_6864MHz, apollo_sio2_config ) |
| 1454 | 1400 | |
| 1455 | MCFG_UPD765A_ADD(APOLLO_FDC_TAG, pc_fdc_upd765_connected_1_drive_interface) | |
| 1456 | MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, apollo_fdc_floppy_config) | |
| 1401 | MCFG_PC_FDC_XT_ADD(APOLLO_FDC_TAG) | |
| 1402 | MCFG_FLOPPY_DRIVE_ADD(APOLLO_FDC_TAG ":0", apollo_floppies, "525hd", 0, apollo_floppy_formats) | |
| 1457 | 1403 | |
| 1458 | 1404 | MCFG_OMTI8621_ADD(APOLLO_WDC_TAG, apollo_wdc_config) |
| 1459 | 1405 | MCFG_SC499_ADD(APOLLO_CTAPE_TAG, apollo_ctape_config) |
| r18419 | r18420 | |
| 1469 | 1415 | { |
| 1470 | 1416 | //MLOG1(("machine_start_apollo")); |
| 1471 | 1417 | |
| 1472 | device_start_apollo_fdc (machine().device(APOLLO_FDC_TAG)); | |
| 1418 | pc_fdc_at_device *fdc = machine().device<pc_fdc_at_device>(APOLLO_FDC_TAG); | |
| 1419 | fdc->setup_intrq_cb(pc_fdc_at_device::line_cb(FUNC(apollo_state::fdc_interrupt), this)); | |
| 1420 | fdc->setup_drq_cb(pc_fdc_at_device::line_cb(FUNC(apollo_state::fdc_dma_drq), this)); | |
| 1421 | ||
| 1473 | 1422 | device_start_apollo_ptm (machine().device(APOLLO_PTM_TAG) ); |
| 1474 | 1423 | device_start_apollo_sio(machine().device(APOLLO_SIO_TAG)); |
| 1475 | 1424 | device_start_apollo_sio2(machine().device(APOLLO_SIO2_TAG)); |
| r18419 | r18420 | |
| 1498 | 1447 | device_reset_apollo_rtc(machine().device(APOLLO_RTC_TAG)); |
| 1499 | 1448 | device_reset_apollo_sio(machine().device(APOLLO_SIO_TAG)); |
| 1500 | 1449 | device_reset_apollo_sio2(machine().device(APOLLO_SIO2_TAG)); |
| 1501 | device_reset_apollo_fdc(apollo_fdc_device); | |
| 1502 | 1450 | } |
| r18419 | r18420 | |
|---|---|---|
| 86 | 86 | }; |
| 87 | 87 | |
| 88 | 88 | |
| 89 | //------------------------------------------------- | |
| 90 | // LEGACY_FLOPPY_OPTIONS( fd2000 ) | |
| 91 | //------------------------------------------------- | |
| 92 | ||
| 93 | static LEGACY_FLOPPY_OPTIONS_START( fd2000 ) | |
| 94 | LEGACY_FLOPPY_OPTION( fd2000, "d81", "Commodore 1581 Disk Image", d81_dsk_identify, d81_dsk_construct, NULL, NULL ) | |
| 95 | //LEGACY_FLOPPY_OPTION( fd2000, "d2m", "CMD FD-2000 Disk Image", d2m_dsk_identify, d2m_dsk_construct, NULL, NULL ) | |
| 96 | LEGACY_FLOPPY_OPTIONS_END | |
| 97 | ||
| 98 | ||
| 99 | //------------------------------------------------- | |
| 100 | // floppy_interface fd2000_floppy_interface | |
| 101 | //------------------------------------------------- | |
| 102 | ||
| 103 | static const floppy_interface fd2000_floppy_interface = | |
| 104 | { | |
| 105 | DEVCB_NULL, | |
| 106 | DEVCB_NULL, | |
| 107 | DEVCB_NULL, | |
| 108 | DEVCB_NULL, | |
| 109 | DEVCB_NULL, | |
| 110 | FLOPPY_STANDARD_3_5_DSDD, | |
| 111 | LEGACY_FLOPPY_OPTIONS_NAME(fd2000), | |
| 112 | "floppy_3_5", | |
| 89 | static const floppy_format_type fd2000_floppy_formats[] = { | |
| 90 | FLOPPY_MFI_FORMAT, | |
| 113 | 91 | NULL |
| 114 | 92 | }; |
| 115 | 93 | |
| 94 | static SLOT_INTERFACE_START( fd2000_floppies ) | |
| 95 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 96 | SLOT_INTERFACE_END | |
| 116 | 97 | |
| 117 | //------------------------------------------------- | |
| 118 | // upd765_interface fdc_intf | |
| 119 | //------------------------------------------------- | |
| 120 | 98 | |
| 121 | static const struct upd765_interface fdc_intf = | |
| 122 | { | |
| 123 | DEVCB_NULL, | |
| 124 | DEVCB_NULL, | |
| 125 | NULL, | |
| 126 | UPD765_RDY_PIN_CONNECTED, | |
| 127 | { FLOPPY_0, NULL, NULL, NULL } | |
| 128 | }; | |
| 129 | ||
| 130 | ||
| 131 | 99 | //------------------------------------------------- |
| 132 | 100 | // MACHINE_DRIVER( fd2000 ) |
| 133 | 101 | //------------------------------------------------- |
| r18419 | r18420 | |
| 137 | 105 | MCFG_CPU_PROGRAM_MAP(fd2000_mem) |
| 138 | 106 | |
| 139 | 107 | MCFG_VIA6522_ADD(M6522_TAG, 2000000, via_intf) |
| 140 | MCFG_UPD765A_ADD(DP8473_TAG, | |
| 108 | MCFG_UPD765A_ADD(DP8473_TAG, true, true) | |
| 141 | 109 | |
| 142 | MCFG_ | |
| 110 | MCFG_FLOPPY_DRIVE_ADD(DP8473_TAG ":0", fd2000_floppies, "525dd", 0, fd2000_floppy_formats) | |
| 143 | 111 | MACHINE_CONFIG_END |
| 144 | 112 | |
| 145 | 113 |
| r18419 | r18420 | |
|---|---|---|
| 17 | 17 | #include "emu.h" |
| 18 | 18 | #include "cpu/m6502/m6502.h" |
| 19 | 19 | #include "imagedev/flopdrv.h" |
| 20 | #include "formats/ | |
| 20 | #include "formats/mfi_dsk.h" | |
| 21 | 21 | #include "machine/6522via.h" |
| 22 | 22 | #include "machine/cbmiec.h" |
| 23 | 23 | #include "machine/upd765.h" |
| r18419 | r18420 | |
|---|---|---|
| 13 | 13 | |
| 14 | 14 | #include "emu.h" |
| 15 | 15 | #include "machine/pc_fdc.h" |
| 16 | #include "machine/upd765.h" | |
| 17 | 16 | |
| 17 | const device_type PC_FDC_XT = &device_creator<pc_fdc_xt_device>; | |
| 18 | const device_type PC_FDC_AT = &device_creator<pc_fdc_at_device>; | |
| 19 | const device_type PC_FDC_JR = &device_creator<pc_fdc_jr_device>; | |
| 18 | 20 | |
| 21 | static MACHINE_CONFIG_FRAGMENT( cfg ) | |
| 22 | MCFG_UPD765A_ADD("upd765", false, false) | |
| 23 | MACHINE_CONFIG_END | |
| 24 | ||
| 25 | DEVICE_ADDRESS_MAP_START(map, 8, pc_fdc_family_device) | |
| 26 | ADDRESS_MAP_END | |
| 27 | ||
| 28 | // The schematics show address decoding is minimal | |
| 29 | DEVICE_ADDRESS_MAP_START(map, 8, pc_fdc_xt_device) | |
| 30 | AM_RANGE(0x0, 0x0) AM_DEVREAD("upd765", upd765a_device, msr_r) AM_WRITE(dor_w) | |
| 31 | AM_RANGE(0x1, 0x1) AM_DEVREAD("upd765", upd765a_device, fifo_r) AM_WRITE(dor_fifo_w) | |
| 32 | AM_RANGE(0x2, 0x2) AM_WRITE(dor_w) | |
| 33 | AM_RANGE(0x3, 0x3) AM_WRITE(dor_w) | |
| 34 | AM_RANGE(0x4, 0x5) AM_DEVICE("upd765", upd765a_device, map) | |
| 35 | ADDRESS_MAP_END | |
| 36 | ||
| 37 | ||
| 38 | // Decoding is through a PAL, so presumably complete | |
| 39 | DEVICE_ADDRESS_MAP_START(map, 8, pc_fdc_at_device) | |
| 40 | AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w) | |
| 41 | AM_RANGE(0x4, 0x5) AM_DEVICE("upd765", upd765a_device, map) | |
| 42 | AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w) | |
| 43 | ADDRESS_MAP_END | |
| 44 | ||
| 45 | ||
| 46 | ||
| 47 | pc_fdc_family_device::pc_fdc_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : pc_fdc_interface(mconfig, type, name, tag, owner, clock), fdc(*this, "upd765") | |
| 48 | { | |
| 49 | } | |
| 50 | ||
| 51 | void pc_fdc_family_device::setup_intrq_cb(line_cb cb) | |
| 52 | { | |
| 53 | intrq_cb = cb; | |
| 54 | } | |
| 55 | ||
| 56 | void pc_fdc_family_device::setup_drq_cb(line_cb cb) | |
| 57 | { | |
| 58 | drq_cb = cb; | |
| 59 | } | |
| 60 | ||
| 61 | void pc_fdc_family_device::tc_w(bool state) | |
| 62 | { | |
| 63 | fdc->tc_w(state); | |
| 64 | } | |
| 65 | ||
| 66 | UINT8 pc_fdc_family_device::dma_r() | |
| 67 | { | |
| 68 | return fdc->dma_r(); | |
| 69 | } | |
| 70 | ||
| 71 | void pc_fdc_family_device::dma_w(UINT8 data) | |
| 72 | { | |
| 73 | fdc->dma_w(data); | |
| 74 | } | |
| 75 | ||
| 76 | machine_config_constructor pc_fdc_family_device::device_mconfig_additions() const | |
| 77 | { | |
| 78 | return MACHINE_CONFIG_NAME(cfg); | |
| 79 | } | |
| 80 | ||
| 81 | void pc_fdc_family_device::device_start() | |
| 82 | { | |
| 83 | fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(pc_fdc_family_device::irq_w), this)); | |
| 84 | fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(pc_fdc_family_device::drq_w), this)); | |
| 85 | ||
| 86 | for(int i=0; i<4; i++) { | |
| 87 | char name[2] = {'0'+i, 0}; | |
| 88 | floppy_connector *conn = subdevice<floppy_connector>(name); | |
| 89 | floppy[i] = conn ? conn->get_device() : NULL; | |
| 90 | } | |
| 91 | ||
| 92 | irq = drq = false; | |
| 93 | fdc_irq = fdc_drq = false; | |
| 94 | dor = 0x00; | |
| 95 | } | |
| 96 | ||
| 97 | void pc_fdc_family_device::device_reset() | |
| 98 | { | |
| 99 | } | |
| 100 | ||
| 101 | // Bits 0-1 select one of the 4 drives, but only if the associated | |
| 102 | // motor bit is on | |
| 103 | ||
| 104 | // Bit 2 is tied to the upd765 reset line | |
| 105 | ||
| 106 | // Bit 3 enables the irq and drq lines | |
| 107 | ||
| 108 | // Bit 4-7 control the drive motors | |
| 109 | ||
| 110 | WRITE8_MEMBER( pc_fdc_family_device::dor_w ) | |
| 111 | { | |
| 112 | logerror("%s: dor = %02x\n", tag(), data); | |
| 113 | UINT8 pdor = dor; | |
| 114 | dor = data; | |
| 115 | ||
| 116 | for(int i=0; i<4; i++) | |
| 117 | if(floppy[i]) | |
| 118 | floppy[i]->mon_w(!(dor & (0x10 << i))); | |
| 119 | ||
| 120 | int fid = dor & 3; | |
| 121 | if(dor & (0x10 << fid)) | |
| 122 | fdc->set_floppy(floppy[fid]); | |
| 123 | else | |
| 124 | fdc->set_floppy(NULL); | |
| 125 | ||
| 126 | check_irq(); | |
| 127 | check_drq(); | |
| 128 | if((pdor^dor) & 4) | |
| 129 | fdc->reset(); | |
| 130 | } | |
| 131 | ||
| 132 | READ8_MEMBER( pc_fdc_family_device::dor_r ) | |
| 133 | { | |
| 134 | return dor; | |
| 135 | } | |
| 136 | ||
| 137 | READ8_MEMBER( pc_fdc_family_device::dir_r ) | |
| 138 | { | |
| 139 | return do_dir_r(); | |
| 140 | } | |
| 141 | ||
| 142 | WRITE8_MEMBER( pc_fdc_family_device::ccr_w ) | |
| 143 | { | |
| 144 | static const int rates[4] = { 500000, 300000, 250000, 1000000 }; | |
| 145 | logerror("%s: ccr = %02x\n", tag(), data); | |
| 146 | fdc->set_rate(rates[data & 3]); | |
| 147 | } | |
| 148 | ||
| 149 | UINT8 pc_fdc_family_device::do_dir_r() | |
| 150 | { | |
| 151 | if(floppy[dor & 3]) | |
| 152 | return floppy[dor & 3]->dskchg_r() ? 0x00 : 0x80; | |
| 153 | return 0x00; | |
| 154 | } | |
| 155 | ||
| 156 | WRITE8_MEMBER( pc_fdc_xt_device::dor_fifo_w) | |
| 157 | { | |
| 158 | fdc->fifo_w(space, 0, data, mem_mask); | |
| 159 | dor_w(space, 0, data, mem_mask); | |
| 160 | } | |
| 161 | ||
| 162 | void pc_fdc_family_device::irq_w(bool state) | |
| 163 | { | |
| 164 | fdc_irq = state; | |
| 165 | check_irq(); | |
| 166 | } | |
| 167 | ||
| 168 | void pc_fdc_family_device::drq_w(bool state) | |
| 169 | { | |
| 170 | fdc_drq = state; | |
| 171 | check_drq(); | |
| 172 | } | |
| 173 | ||
| 174 | void pc_fdc_family_device::check_irq() | |
| 175 | { | |
| 176 | bool pirq = irq; | |
| 177 | irq = fdc_irq && (dor & 4) && (dor & 8); | |
| 178 | if(irq != pirq && !intrq_cb.isnull()) { | |
| 179 | logerror("%s: pc_irq = %d\n", tag(), irq); | |
| 180 | intrq_cb(irq); | |
| 181 | } | |
| 182 | } | |
| 183 | ||
| 184 | void pc_fdc_family_device::check_drq() | |
| 185 | { | |
| 186 | bool pdrq = drq; | |
| 187 | drq = fdc_drq && (dor & 4) && (dor & 8); | |
| 188 | if(drq != pdrq && !drq_cb.isnull()) | |
| 189 | drq_cb(drq); | |
| 190 | } | |
| 191 | ||
| 192 | pc_fdc_xt_device::pc_fdc_xt_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : pc_fdc_family_device(mconfig, PC_FDC_XT, "PC FDC XT", tag, owner, clock) | |
| 193 | { | |
| 194 | m_shortname = "pc_fdc_xt"; | |
| 195 | } | |
| 196 | ||
| 197 | pc_fdc_at_device::pc_fdc_at_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : pc_fdc_family_device(mconfig, PC_FDC_AT, "PC FDC AT", tag, owner, clock) | |
| 198 | { | |
| 199 | m_shortname = "pc_fdc_at"; | |
| 200 | } | |
| 201 | ||
| 202 | pc_fdc_jr_device::pc_fdc_jr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : pc_fdc_family_device(mconfig, PC_FDC_JR, "PC FDC JR", tag, owner, clock) | |
| 203 | { | |
| 204 | m_shortname = "pc_fdc_jr"; | |
| 205 | } | |
| 206 | ||
| 207 | #if 0 | |
| 208 | ||
| 209 | ||
| 19 | 210 | /* if not 1, DACK and TC inputs to FDC are disabled, and DRQ and IRQ are held |
| 20 | 211 | * at high impedance i.e they are not affective */ |
| 21 | 212 | #define PC_FDC_FLAGS_DOR_DMA_ENABLED (1<<3) |
| r18419 | r18420 | |
| 579 | 770 | } |
| 580 | 771 | } |
| 581 | 772 | |
| 773 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 8 | 8 | #define PC_FDC_H |
| 9 | 9 | |
| 10 | 10 | #include "emu.h" |
| 11 | #include "machine/upd765.h" | |
| 11 | #include "imagedev/floppy.h" | |
| 12 | #include "upd765.h" | |
| 12 | 13 | |
| 14 | #define MCFG_PC_FDC_XT_ADD(_tag) \ | |
| 15 | MCFG_DEVICE_ADD(_tag, PC_FDC_XT, 0) | |
| 16 | ||
| 17 | #define MCFG_PC_FDC_AT_ADD(_tag) \ | |
| 18 | MCFG_DEVICE_ADD(_tag, PC_FDC_AT, 0) | |
| 19 | ||
| 20 | #define MCFG_PC_FDC_JR_ADD(_tag) \ | |
| 21 | MCFG_DEVICE_ADD(_tag, PC_FDC_JR, 0) | |
| 22 | ||
| 23 | ||
| 24 | class pc_fdc_family_device : public pc_fdc_interface { | |
| 25 | public: | |
| 26 | pc_fdc_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 27 | ||
| 28 | required_device<upd765a_device> fdc; | |
| 29 | ||
| 30 | virtual void setup_intrq_cb(line_cb cb); | |
| 31 | virtual void setup_drq_cb(line_cb cb); | |
| 32 | ||
| 33 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 34 | ||
| 35 | virtual void tc_w(bool state); | |
| 36 | virtual UINT8 dma_r(); | |
| 37 | virtual void dma_w(UINT8 data); | |
| 38 | virtual UINT8 do_dir_r(); | |
| 39 | ||
| 40 | READ8_MEMBER(dor_r); | |
| 41 | WRITE8_MEMBER(dor_w); | |
| 42 | READ8_MEMBER(dir_r); | |
| 43 | WRITE8_MEMBER(ccr_w); | |
| 44 | ||
| 45 | protected: | |
| 46 | virtual void device_start(); | |
| 47 | virtual void device_reset(); | |
| 48 | virtual machine_config_constructor device_mconfig_additions() const; | |
| 49 | ||
| 50 | line_cb intrq_cb, drq_cb; | |
| 51 | bool irq, drq, fdc_drq, fdc_irq; | |
| 52 | UINT8 dor; | |
| 53 | ||
| 54 | floppy_image_device *floppy[4]; | |
| 55 | ||
| 56 | void irq_w(bool state); | |
| 57 | void drq_w(bool state); | |
| 58 | void check_irq(); | |
| 59 | void check_drq(); | |
| 60 | }; | |
| 61 | ||
| 62 | class pc_fdc_xt_device : public pc_fdc_family_device { | |
| 63 | public: | |
| 64 | pc_fdc_xt_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 65 | ||
| 66 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 67 | WRITE8_MEMBER(dor_fifo_w); | |
| 68 | }; | |
| 69 | ||
| 70 | class pc_fdc_at_device : public pc_fdc_family_device { | |
| 71 | public: | |
| 72 | pc_fdc_at_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 73 | ||
| 74 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 75 | }; | |
| 76 | ||
| 77 | class pc_fdc_jr_device : public pc_fdc_family_device { | |
| 78 | public: | |
| 79 | pc_fdc_jr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 80 | }; | |
| 81 | ||
| 82 | ||
| 83 | extern const device_type PC_FDC_XT; | |
| 84 | extern const device_type PC_FDC_AT; | |
| 85 | extern const device_type PC_FDC_JR; | |
| 86 | ||
| 87 | ||
| 88 | #if 0 | |
| 13 | 89 | /* interface has been seperated, so that it can be used in the super i/o chip */ |
| 14 | 90 | |
| 15 | 91 | #define PC_FDC_STATUS_REGISTER_A 0 |
| r18419 | r18420 | |
| 47 | 123 | DECLARE_WRITE8_HANDLER(pc_fdc_w); |
| 48 | 124 | DECLARE_WRITE8_HANDLER ( pcjr_fdc_w ); |
| 49 | 125 | |
| 126 | #endif | |
| 50 | 127 | #endif /* PC_FDC_H */ |
| 51 | 128 | |
| 52 | 129 |
| r18419 | r18420 | |
|---|---|---|
| 215 | 215 | } |
| 216 | 216 | |
| 217 | 217 | |
| 218 | ||
| 218 | void amstrad_state::aleste_interrupt(bool state) | |
| 219 | 219 | { |
| 220 | if(state == CLEAR_LINE) | |
| 221 | m_aleste_fdc_int = 0; | |
| 222 | else | |
| 223 | m_aleste_fdc_int = 1; | |
| 220 | m_aleste_fdc_int = state; | |
| 224 | 221 | } |
| 225 | 222 | |
| 226 | 223 | |
| r18419 | r18420 | |
| 1857 | 1854 | |
| 1858 | 1855 | READ8_MEMBER(amstrad_state::amstrad_cpc_io_r) |
| 1859 | 1856 | { |
| 1860 | device_t *fdc = m_fdc; | |
| 1861 | 1857 | mc6845_device *mc6845 = m_crtc; |
| 1862 | 1858 | |
| 1863 | 1859 | unsigned char data = 0xFF; |
| r18419 | r18420 | |
| 1951 | 1947 | switch (b8b0) |
| 1952 | 1948 | { |
| 1953 | 1949 | case 0x02: |
| 1954 | data = | |
| 1950 | data = m_fdc->msr_r(space, 0); | |
| 1955 | 1951 | break; |
| 1956 | 1952 | case 0x03: |
| 1957 | data = | |
| 1953 | data = m_fdc->fifo_r(space, 0); | |
| 1958 | 1954 | break; |
| 1959 | 1955 | default: |
| 1960 | 1956 | break; |
| r18419 | r18420 | |
| 1993 | 1989 | /* Offset handler for write */ |
| 1994 | 1990 | WRITE8_MEMBER(amstrad_state::amstrad_cpc_io_w) |
| 1995 | 1991 | { |
| 1996 | device_t *fdc = m_fdc; | |
| 1997 | 1992 | mc6845_device *mc6845 = m_crtc; |
| 1998 | 1993 | cpc_multiface2_device* mface2; |
| 1999 | 1994 | |
| r18419 | r18420 | |
| 2118 | 2113 | |
| 2119 | 2114 | switch (b8b0) |
| 2120 | 2115 | { |
| 2121 | case 0x00: | |
| 2116 | case 0x00: { | |
| 2122 | 2117 | /* FDC Motor Control - Bit 0 defines the state of the FDD motor: |
| 2123 | 2118 | * "1" the FDD motor will be active. |
| 2124 | 2119 | * "0" the FDD motor will be in-active.*/ |
| 2125 | floppy_mon_w(floppy_get_device(machine(), 0), !BIT(data, 0)); | |
| 2126 | floppy_mon_w(floppy_get_device(machine(), 1), !BIT(data, 0)); | |
| 2127 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 1,1); | |
| 2128 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 1,1); | |
| 2120 | floppy_image_device *floppy; | |
| 2121 | floppy = machine().device<floppy_connector>(":upd765a:0")->get_device(); | |
| 2122 | if(floppy) | |
| 2123 | floppy->mon_w(!BIT(data, 0)); | |
| 2124 | floppy = machine().device<floppy_connector>(":upd765a:1")->get_device(); | |
| 2125 | if(floppy) | |
| 2126 | floppy->mon_w(!BIT(data, 0)); | |
| 2129 | 2127 | break; |
| 2128 | } | |
| 2130 | 2129 | |
| 2131 | 2130 | case 0x03: /* Write Data register of FDC */ |
| 2132 | | |
| 2131 | m_fdc->fifo_w(space, 0,data); | |
| 2133 | 2132 | break; |
| 2134 | 2133 | |
| 2135 | 2134 | default: |
| r18419 | r18420 | |
| 3267 | 3266 | auto_free(image.device().machine(), temp_copy); |
| 3268 | 3267 | return IMAGE_INIT_PASS; |
| 3269 | 3268 | } |
| 3270 | ||
| 3271 | ||
| 3272 | #if 0 | |
| 3273 | static DEVICE_IMAGE_LOAD( aleste ) | |
| 3274 | { | |
| 3275 | if (device_load_basicdsk_floppy(image)==IMAGE_INIT_PASS) | |
| 3276 | { | |
| 3277 | basicdsk_set_geometry(image, 80, 2, 9, 512, 0x01, 0, FALSE); | |
| 3278 | return IMAGE_INIT_PASS; | |
| 3279 | } | |
| 3280 | return IMAGE_INIT_FAIL; | |
| 3281 | } | |
| 3282 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 8 | 8 | |
| 9 | 9 | #include "emu.h" |
| 10 | 10 | #include "kc_d004.h" |
| 11 | #include "formats/mfi_dsk.h" | |
| 12 | #include "formats/kc85_dsk.h" | |
| 11 | 13 | |
| 12 | 14 | #define Z80_TAG "disk" |
| 13 | 15 | #define Z80CTC_TAG "z80ctc" |
| r18419 | r18420 | |
| 26 | 28 | static ADDRESS_MAP_START(kc_d004_io, AS_IO, 8, kc_d004_device) |
| 27 | 29 | ADDRESS_MAP_UNMAP_HIGH |
| 28 | 30 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 29 | AM_RANGE(0xf0, 0xf0) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) | |
| 30 | AM_RANGE(0xf1, 0xf1) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) | |
| 31 | AM_RANGE(0xf2, 0xf3) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_dack_r, upd765_dack_w) | |
| 31 | AM_RANGE(0xf0, 0xf1) AM_DEVICE(UPD765_TAG, upd765a_device, map) | |
| 32 | AM_RANGE(0xf2, 0xf3) AM_DEVREADWRITE(UPD765_TAG, upd765a_device, mdma_r, mdma_w) | |
| 32 | 33 | AM_RANGE(0xf4, 0xf4) AM_READ(hw_input_gate_r) |
| 33 | 34 | AM_RANGE(0xf6, 0xf7) AM_WRITE(fdd_select_w) |
| 34 | 35 | AM_RANGE(0xf8, 0xf9) AM_WRITE(hw_terminal_count_w) |
| r18419 | r18420 | |
| 37 | 38 | |
| 38 | 39 | static ADDRESS_MAP_START(kc_d004_gide_io, AS_IO, 8, kc_d004_gide_device) |
| 39 | 40 | ADDRESS_MAP_UNMAP_HIGH |
| 40 | AM_RANGE(0x00f0, 0x00f0) AM_MIRROR(0xff00) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) | |
| 41 | AM_RANGE(0x00f1, 0x00f1) AM_MIRROR(0xff00) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) | |
| 42 | AM_RANGE(0x00f2, 0x00f3) AM_MIRROR(0xff00) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_dack_r, upd765_dack_w) | |
| 41 | AM_RANGE(0x00f0, 0x00f1) AM_MIRROR(0xff00) AM_DEVICE(UPD765_TAG, upd765a_device, map) | |
| 42 | AM_RANGE(0x00f2, 0x00f3) AM_MIRROR(0xff00) AM_DEVREADWRITE(UPD765_TAG, upd765a_device, mdma_r, mdma_w) | |
| 43 | 43 | AM_RANGE(0x00f4, 0x00f4) AM_MIRROR(0xff00) AM_READ(hw_input_gate_r) |
| 44 | 44 | AM_RANGE(0x00f6, 0x00f7) AM_MIRROR(0xff00) AM_WRITE(fdd_select_w) |
| 45 | 45 | AM_RANGE(0x00f8, 0x00f9) AM_MIRROR(0xff00) AM_WRITE(hw_terminal_count_w) |
| r18419 | r18420 | |
| 47 | 47 | AM_RANGE(0x0000, 0xffff) AM_READWRITE(gide_r, gide_w) |
| 48 | 48 | ADDRESS_MAP_END |
| 49 | 49 | |
| 50 | static LEGACY_FLOPPY_OPTIONS_START(kc_d004) | |
| 51 | LEGACY_FLOPPY_OPTION(kc85, "img", "KC85 disk image 800KB", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 52 | HEADS([2]) | |
| 53 | TRACKS([80]) | |
| 54 | SECTORS([5]) | |
| 55 | SECTOR_LENGTH([1024]) | |
| 56 | FIRST_SECTOR_ID([1])) | |
| 57 | LEGACY_FLOPPY_OPTION(kc85, "img", "KC85 disk image 720KB", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 58 | HEADS([2]) | |
| 59 | TRACKS([80]) | |
| 60 | SECTORS([9]) | |
| 61 | SECTOR_LENGTH([512]) | |
| 62 | FIRST_SECTOR_ID([1])) | |
| 63 | LEGACY_FLOPPY_OPTION(kc85, "img", "KC85 disk image 640KB", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 64 | HEADS([2]) | |
| 65 | TRACKS([80]) | |
| 66 | SECTORS([16]) | |
| 67 | SECTOR_LENGTH([256]) | |
| 68 | FIRST_SECTOR_ID([1])) | |
| 69 | LEGACY_FLOPPY_OPTIONS_END | |
| 70 | ||
| 71 | static const floppy_interface kc_d004_floppy_interface = | |
| 72 | { | |
| 73 | DEVCB_NULL, | |
| 74 | DEVCB_NULL, | |
| 75 | DEVCB_NULL, | |
| 76 | DEVCB_NULL, | |
| 77 | DEVCB_NULL, | |
| 78 | FLOPPY_STANDARD_5_25_DSHD, | |
| 79 | LEGACY_FLOPPY_OPTIONS_NAME(kc_d004), | |
| 80 | "floppy_5_25", | |
| 50 | static const floppy_format_type kc_d004_floppy_formats[] = { | |
| 51 | FLOPPY_KC85_FORMAT, | |
| 52 | FLOPPY_MFI_FORMAT, | |
| 81 | 53 | NULL |
| 82 | 54 | }; |
| 83 | 55 | |
| 84 | static device_t *kc_d004_get_fdd(device_t *device, int floppy_index) | |
| 85 | { | |
| 86 | kc_d004_device* owner = dynamic_cast<kc_d004_device *>(device->owner()); | |
| 87 | return owner->get_active_fdd(); | |
| 88 | } | |
| 56 | static SLOT_INTERFACE_START( kc_d004_floppies ) | |
| 57 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 58 | SLOT_INTERFACE_END | |
| 89 | 59 | |
| 90 | static const upd765_interface kc_d004_interface = | |
| 91 | { | |
| 92 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, kc_d004_device, fdc_interrupt), | |
| 93 | DEVCB_DEVICE_LINE_MEMBER(DEVICE_SELF_OWNER, kc_d004_device, fdc_dma_request), | |
| 94 | kc_d004_get_fdd, | |
| 95 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 96 | {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} | |
| 97 | }; | |
| 98 | ||
| 99 | 60 | static const z80_daisy_config kc_d004_daisy_chain[] = |
| 100 | 61 | { |
| 101 | 62 | { Z80CTC_TAG }, |
| r18419 | r18420 | |
| 118 | 79 | |
| 119 | 80 | MCFG_Z80CTC_ADD( Z80CTC_TAG, XTAL_8MHz/2, kc_d004_ctc_intf ) |
| 120 | 81 | |
| 121 | MCFG_UPD765A_ADD(UPD765_TAG, kc_d004_interface) | |
| 122 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(kc_d004_floppy_interface) | |
| 82 | MCFG_UPD765A_ADD(UPD765_TAG, false, false) | |
| 83 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", kc_d004_floppies, "525hd", 0, kc_d004_floppy_formats) | |
| 84 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", kc_d004_floppies, "525hd", 0, kc_d004_floppy_formats) | |
| 85 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":2", kc_d004_floppies, "525hd", 0, kc_d004_floppy_formats) | |
| 86 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":3", kc_d004_floppies, "525hd", 0, kc_d004_floppy_formats) | |
| 123 | 87 | MACHINE_CONFIG_END |
| 124 | 88 | |
| 125 | 89 | static const ide_config ide_intf = |
| r18419 | r18420 | |
| 202 | 166 | |
| 203 | 167 | m_reset_timer = timer_alloc(TIMER_RESET); |
| 204 | 168 | m_tc_clear_timer = timer_alloc(TIMER_TC_CLEAR); |
| 169 | ||
| 170 | m_fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(kc_d004_device::fdc_irq), this)); | |
| 171 | m_fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(kc_d004_device::fdc_drq), this)); | |
| 205 | 172 | } |
| 206 | 173 | |
| 207 | 174 | //------------------------------------------------- |
| r18419 | r18420 | |
| 212 | 179 | { |
| 213 | 180 | m_rom_base = 0xc000; |
| 214 | 181 | m_enabled = m_connected = 0; |
| 215 | m_floppy = | |
| 182 | m_floppy = subdevice<floppy_connector>(UPD765_TAG ":0")->get_device(); | |
| 216 | 183 | |
| 217 | 184 | // hold cpu at reset |
| 218 | 185 | m_reset_timer->adjust(attotime::zero); |
| r18419 | r18420 | |
| 248 | 215 | m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 249 | 216 | break; |
| 250 | 217 | case TIMER_TC_CLEAR: |
| 251 | | |
| 218 | m_fdc->tc_w(false); | |
| 252 | 219 | break; |
| 253 | 220 | } |
| 254 | 221 | } |
| r18419 | r18420 | |
| 369 | 336 | |
| 370 | 337 | */ |
| 371 | 338 | |
| 372 | if (floppy | |
| 339 | if (m_floppy->ready_r()) | |
| 373 | 340 | m_hw_input_gate |= 0x20; |
| 374 | 341 | else |
| 375 | 342 | m_hw_input_gate &= ~0x20; |
| 376 | 343 | |
| 377 | if (floppy | |
| 344 | if (m_floppy->idx_r()) | |
| 378 | 345 | m_hw_input_gate &= ~0x10; |
| 379 | 346 | else |
| 380 | 347 | m_hw_input_gate |= 0x10; |
| r18419 | r18420 | |
| 385 | 352 | WRITE8_MEMBER(kc_d004_device::fdd_select_w) |
| 386 | 353 | { |
| 387 | 354 | if (data & 0x01) |
| 388 | m_floppy = | |
| 355 | m_floppy = subdevice<floppy_connector>(UPD765_TAG ":0")->get_device(); | |
| 389 | 356 | else if (data & 0x02) |
| 390 | m_floppy = | |
| 357 | m_floppy = subdevice<floppy_connector>(UPD765_TAG ":1")->get_device(); | |
| 391 | 358 | else if (data & 0x04) |
| 392 | m_floppy = | |
| 359 | m_floppy = subdevice<floppy_connector>(UPD765_TAG ":2")->get_device(); | |
| 393 | 360 | else if (data & 0x08) |
| 394 | m_floppy = downcast<device_t *>(subdevice(FLOPPY_3)); | |
| 361 | m_floppy = subdevice<floppy_connector>(UPD765_TAG ":3")->get_device(); | |
| 362 | else | |
| 363 | m_floppy = NULL; | |
| 364 | m_fdc->set_floppy(m_floppy); | |
| 395 | 365 | } |
| 396 | 366 | |
| 397 | 367 | WRITE8_MEMBER(kc_d004_device::hw_terminal_count_w) |
| 398 | 368 | { |
| 399 | | |
| 369 | m_fdc->tc_w(false); | |
| 400 | 370 | |
| 401 | 371 | m_tc_clear_timer->adjust(attotime::from_nsec(200)); |
| 402 | 372 | } |
| 403 | 373 | |
| 404 | ||
| 374 | void kc_d004_device::fdc_irq(bool state) | |
| 405 | 375 | { |
| 406 | 376 | if (state) |
| 407 | 377 | m_hw_input_gate &= ~0x40; |
| r18419 | r18420 | |
| 409 | 379 | m_hw_input_gate |= 0x40; |
| 410 | 380 | } |
| 411 | 381 | |
| 412 | ||
| 382 | void kc_d004_device::fdc_drq(bool state) | |
| 413 | 383 | { |
| 414 | 384 | if (state) |
| 415 | 385 | m_hw_input_gate &= ~0x80; |
| r18419 | r18420 | |
|---|---|---|
| 48 | 48 | virtual void io_write(offs_t offset, UINT8 data); |
| 49 | 49 | |
| 50 | 50 | public: |
| 51 | device_t* get_active_fdd() { return m_floppy; } | |
| 52 | 51 | DECLARE_READ8_MEMBER(hw_input_gate_r); |
| 53 | 52 | DECLARE_WRITE8_MEMBER(fdd_select_w); |
| 54 | 53 | DECLARE_WRITE8_MEMBER(hw_terminal_count_w); |
| 55 | DECLARE_WRITE_LINE_MEMBER(fdc_interrupt); | |
| 56 | DECLARE_WRITE_LINE_MEMBER(fdc_dma_request); | |
| 57 | 54 | |
| 55 | void fdc_irq(bool state); | |
| 56 | void fdc_drq(bool state); | |
| 57 | ||
| 58 | 58 | private: |
| 59 | 59 | static const device_timer_id TIMER_RESET = 0; |
| 60 | 60 | static const device_timer_id TIMER_TC_CLEAR = 1; |
| 61 | 61 | |
| 62 | 62 | required_device<cpu_device> m_cpu; |
| 63 | required_device<device | |
| 63 | required_device<upd765a_device> m_fdc; | |
| 64 | 64 | required_shared_ptr<UINT8> m_koppel_ram; |
| 65 | 65 | |
| 66 | 66 | // internal state |
| r18419 | r18420 | |
| 73 | 73 | UINT8 m_enabled; |
| 74 | 74 | UINT8 m_connected; |
| 75 | 75 | UINT8 m_active_fdd; |
| 76 | device_t * m_floppy; | |
| 76 | ||
| 77 | floppy_image_device *m_floppy; | |
| 77 | 78 | }; |
| 78 | 79 | |
| 79 | 80 |
| r18419 | r18420 | |
|---|---|---|
| 6 | 6 | |
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "iq151_disc2.h" |
| 9 | #include "formats/mfi_dsk.h" | |
| 10 | #include "formats/iq151_dsk.h" | |
| 9 | 11 | |
| 10 | 12 | |
| 11 | 13 | /*************************************************************************** |
| 12 | 14 | IMPLEMENTATION |
| 13 | 15 | ***************************************************************************/ |
| 14 | 16 | |
| 15 | static LEGACY_FLOPPY_OPTIONS_START( iq151_disc2 ) | |
| 16 | LEGACY_FLOPPY_OPTION( iq151_disk, "iqd", "IQ-151 disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 17 | HEADS([1]) | |
| 18 | TRACKS([77]) | |
| 19 | SECTORS([26]) | |
| 20 | SECTOR_LENGTH([128]) | |
| 21 | FIRST_SECTOR_ID([1])) | |
| 22 | LEGACY_FLOPPY_OPTIONS_END | |
| 23 | ||
| 24 | static const floppy_interface iq151_disc2_intf = | |
| 25 | { | |
| 26 | DEVCB_NULL, | |
| 27 | DEVCB_NULL, | |
| 28 | DEVCB_NULL, | |
| 29 | DEVCB_NULL, | |
| 30 | DEVCB_NULL, | |
| 31 | FLOPPY_STANDARD_8_SSSD, | |
| 32 | LEGACY_FLOPPY_OPTIONS_NAME(iq151_disc2), | |
| 33 | "floppy_8", | |
| 17 | static const floppy_format_type iq151_disc2_floppy_formats[] = { | |
| 18 | FLOPPY_IQ151_FORMAT, | |
| 19 | FLOPPY_MFI_FORMAT, | |
| 34 | 20 | NULL |
| 35 | 21 | }; |
| 36 | 22 | |
| 37 | static const upd765_interface iq151_disc2_fdc_intf = | |
| 38 | { | |
| 39 | DEVCB_NULL, | |
| 40 | DEVCB_NULL, | |
| 41 | NULL, | |
| 42 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 43 | { NULL, FLOPPY_0, FLOPPY_1, NULL } | |
| 44 | }; | |
| 23 | static SLOT_INTERFACE_START( iq151_disc2_floppies ) | |
| 24 | SLOT_INTERFACE( "8sssd", FLOPPY_8_SSSD ) | |
| 25 | SLOT_INTERFACE_END | |
| 45 | 26 | |
| 46 | 27 | static MACHINE_CONFIG_FRAGMENT( iq151_disc2 ) |
| 47 | MCFG_UPD72065_ADD("fdc", iq151_disc2_fdc_intf) | |
| 48 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(iq151_disc2_intf) | |
| 28 | MCFG_UPD72065_ADD("fdc", false, true) | |
| 29 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", iq151_disc2_floppies, "8sssd", 0, iq151_disc2_floppy_formats) | |
| 30 | MCFG_FLOPPY_DRIVE_ADD("fdc:2", iq151_disc2_floppies, "8sssd", 0, iq151_disc2_floppy_formats) | |
| 49 | 31 | MACHINE_CONFIG_END |
| 50 | 32 | |
| 51 | 33 | ROM_START( iq151_disc2 ) |
| r18419 | r18420 | |
| 129 | 111 | |
| 130 | 112 | void iq151_disc2_device::io_read(offs_t offset, UINT8 &data) |
| 131 | 113 | { |
| 114 | /* This is gross */ | |
| 115 | address_space *space = NULL; | |
| 132 | 116 | if (offset == 0xaa) |
| 133 | data = | |
| 117 | data = m_fdc->msr_r(*space, 0, 0xff); | |
| 134 | 118 | else if (offset == 0xab) |
| 135 | data = | |
| 119 | data = m_fdc->fifo_r(*space, 0, 0xff); | |
| 136 | 120 | } |
| 137 | 121 | |
| 138 | 122 | //------------------------------------------------- |
| r18419 | r18420 | |
| 141 | 125 | |
| 142 | 126 | void iq151_disc2_device::io_write(offs_t offset, UINT8 data) |
| 143 | 127 | { |
| 128 | address_space *space = NULL; | |
| 144 | 129 | if (offset == 0xab) |
| 145 | | |
| 130 | m_fdc->fifo_w(*space, 0, data, 0xff); | |
| 146 | 131 | else if (offset == 0xac) |
| 147 | 132 | m_rom_enabled = (data == 0x01); |
| 148 | 133 | } |
| r18419 | r18420 | |
|---|---|---|
| 6 | 6 | #include "emu.h" |
| 7 | 7 | #include "machine/iq151cart.h" |
| 8 | 8 | #include "machine/upd765.h" |
| 9 | #include "formats/basicdsk.h" | |
| 10 | 9 | |
| 11 | 10 | //************************************************************************** |
| 12 | 11 | // TYPE DEFINITIONS |
| r18419 | r18420 | |
| 39 | 38 | |
| 40 | 39 | private: |
| 41 | 40 | |
| 42 | required_device<device | |
| 41 | required_device<upd765a_device> m_fdc; | |
| 43 | 42 | UINT8 * m_rom; |
| 44 | 43 | bool m_rom_enabled; |
| 45 | 44 | }; |
| r18419 | r18420 | |
|---|---|---|
| 1 | ||
| 1 | #include "debugger.h" | |
| 2 | 2 | |
| 3 | ||
| 3 | #include "upd765.h" | |
| 4 | 4 | |
| 5 | Functions to emulate a UPD765/Intel 8272 compatible floppy disk controller | |
| 5 | const device_type UPD765A = &device_creator<upd765a_device>; | |
| 6 | const device_type UPD765B = &device_creator<upd765b_device>; | |
| 7 | const device_type I8272A = &device_creator<i8272a_device>; | |
| 8 | const device_type UPD72065 = &device_creator<upd72065_device>; | |
| 9 | const device_type SMC37C78 = &device_creator<smc37c78_device>; | |
| 10 | const device_type N82077AA = &device_creator<n82077aa_device>; | |
| 11 | const device_type PC_FDC_SUPERIO = &device_creator<pc_fdc_superio_device>; | |
| 6 | 12 | |
| 7 | Code by Kevin Thacker. | |
| 13 | DEVICE_ADDRESS_MAP_START(map, 8, upd765a_device) | |
| 14 | AM_RANGE(0x0, 0x0) AM_READ(msr_r) | |
| 15 | AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w) | |
| 16 | ADDRESS_MAP_END | |
| 8 | 17 | |
| 9 | TODO: | |
| 18 | DEVICE_ADDRESS_MAP_START(map, 8, upd765b_device) | |
| 19 | AM_RANGE(0x0, 0x0) AM_READ(msr_r) | |
| 20 | AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w) | |
| 21 | ADDRESS_MAP_END | |
| 10 | 22 | |
| 11 | - overrun condition | |
| 12 | - Scan Commands | |
| 13 | - crc error in id field and crc error in data field errors | |
| 14 | - disc not present, and no sectors on track for data, deleted data, write, write deleted, | |
| 15 | read a track etc | |
| 16 | - end of cylinder condition - almost working, needs fixing with | |
| 17 | PCW and PC drivers | |
| 18 | - resolve "ready" state stuff (ready state when reset for PC, ready state change while processing command AND | |
| 19 | while idle) | |
| 23 | DEVICE_ADDRESS_MAP_START(map, 8, i8272a_device) | |
| 24 | AM_RANGE(0x0, 0x0) AM_READ(msr_r) | |
| 25 | AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w) | |
| 26 | ADDRESS_MAP_END | |
| 20 | 27 | |
| 21 | Changes: | |
| 22 | 091006 (Mariusz Wojcieszek, changes needed by QX-10): | |
| 23 | - allowed "Sense Interrupt Status" command when Seek is active | |
| 24 | - DIO bit in status register (0x40) is cleared when "Read Data" command is executed, | |
| 25 | it is later set during result phase. | |
| 28 | DEVICE_ADDRESS_MAP_START(map, 8, upd72065_device) | |
| 29 | AM_RANGE(0x0, 0x0) AM_READ(msr_r) | |
| 30 | AM_RANGE(0x1, 0x1) AM_READWRITE(fifo_r, fifo_w) | |
| 31 | ADDRESS_MAP_END | |
| 26 | 32 | |
| 27 | ***************************************************************************/ | |
| 33 | DEVICE_ADDRESS_MAP_START(map, 8, smc37c78_device) | |
| 34 | AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w) | |
| 35 | AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w) | |
| 36 | AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w) | |
| 37 | AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w) | |
| 38 | AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w) | |
| 39 | ADDRESS_MAP_END | |
| 28 | 40 | |
| 29 | #include "emu.h" | |
| 30 | #include "machine/upd765.h" | |
| 41 | DEVICE_ADDRESS_MAP_START(map, 8, n82077aa_device) | |
| 42 | AM_RANGE(0x0, 0x0) AM_READ(sra_r) | |
| 43 | AM_RANGE(0x1, 0x1) AM_READ(srb_r) | |
| 44 | AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w) | |
| 45 | AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w) | |
| 46 | AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w) | |
| 47 | AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w) | |
| 48 | AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w) | |
| 49 | ADDRESS_MAP_END | |
| 31 | 50 | |
| 51 | DEVICE_ADDRESS_MAP_START(map, 8, pc_fdc_superio_device) | |
| 52 | AM_RANGE(0x0, 0x0) AM_READ(sra_r) | |
| 53 | AM_RANGE(0x1, 0x1) AM_READ(srb_r) | |
| 54 | AM_RANGE(0x2, 0x2) AM_READWRITE(dor_r, dor_w) | |
| 55 | AM_RANGE(0x3, 0x3) AM_READWRITE(tdr_r, tdr_w) | |
| 56 | AM_RANGE(0x4, 0x4) AM_READWRITE(msr_r, dsr_w) | |
| 57 | AM_RANGE(0x5, 0x5) AM_READWRITE(fifo_r, fifo_w) | |
| 58 | AM_RANGE(0x7, 0x7) AM_READWRITE(dir_r, ccr_w) | |
| 59 | ADDRESS_MAP_END | |
| 32 | 60 | |
| 33 | enum UPD765_PHASE | |
| 61 | ||
| 62 | int upd765_family_device::rates[4] = { 500000, 300000, 250000, 1000000 }; | |
| 63 | ||
| 64 | upd765_family_device::upd765_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : pc_fdc_interface(mconfig, type, name, tag, owner, clock) | |
| 34 | 65 | { |
| 35 | UPD765_COMMAND_PHASE_FIRST_BYTE, | |
| 36 | UPD765_COMMAND_PHASE_BYTES, | |
| 37 | UPD765_RESULT_PHASE, | |
| 38 | UPD765_EXECUTION_PHASE_READ, | |
| 39 | UPD765_EXECUTION_PHASE_WRITE | |
| 40 | }; | |
| 66 | ready_polled = true; | |
| 67 | ready_connected = true; | |
| 68 | select_connected = true; | |
| 69 | external_ready = true; | |
| 70 | dor_reset = 0x00; | |
| 71 | } | |
| 41 | 72 | |
| 42 | /* supported versions */ | |
| 43 | enum UPD765_VERSION | |
| 73 | void upd765_family_device::set_ready_line_connected(bool _ready) | |
| 44 | 74 | { |
| 45 | TYPE_UPD765A = 0, | |
| 46 | TYPE_UPD765B = 1, | |
| 47 | TYPE_SMC37C78 = 2, | |
| 48 | TYPE_UPD72065 = 3 | |
| 49 | }; | |
| 75 | ready_connected = _ready; | |
| 76 | } | |
| 50 | 77 | |
| 78 | void upd765_family_device::set_select_lines_connected(bool _select) | |
| 79 | { | |
| 80 | select_connected = _select; | |
| 81 | } | |
| 51 | 82 | |
| 52 | /* uncomment the following line for verbose information */ | |
| 53 | #define LOG_VERBOSE 0 | |
| 54 | #define LOG_COMMAND 0 | |
| 55 | #define LOG_EXTRA 0 | |
| 56 | #define LOG_INTERRUPT 0 | |
| 83 | void upd765_family_device::set_mode(int _mode) | |
| 84 | { | |
| 85 | // TODO | |
| 86 | } | |
| 57 | 87 | |
| 58 | /* uncomment this to not allow end of cylinder "error" */ | |
| 59 | #define NO_END_OF_CYLINDER | |
| 88 | void upd765_family_device::setup_intrq_cb(line_cb cb) | |
| 89 | { | |
| 90 | intrq_cb = cb; | |
| 91 | } | |
| 60 | 92 | |
| 93 | void upd765_family_device::setup_drq_cb(line_cb cb) | |
| 94 | { | |
| 95 | drq_cb = cb; | |
| 96 | } | |
| 61 | 97 | |
| 62 | ||
| 63 | /* state of upd765 Interrupt (INT) output */ | |
| 64 | #define UPD765_INT 0x02 | |
| 65 | /* data rate for floppy discs (MFM data) */ | |
| 66 | #define UPD765_DATA_RATE 32 | |
| 67 | /* state of upd765 terminal count input*/ | |
| 68 | #define UPD765_TC 0x04 | |
| 69 | ||
| 70 | #define UPD765_DMA_MODE 0x08 | |
| 71 | ||
| 72 | #define UPD765_SEEK_OPERATION_IS_RECALIBRATE 0x01 | |
| 73 | ||
| 74 | #define UPD765_SEEK_ACTIVE 0x010 | |
| 75 | /* state of upd765 DMA DRQ output */ | |
| 76 | #define UPD765_DMA_DRQ 0x020 | |
| 77 | /* state of upd765 FDD READY input */ | |
| 78 | #define UPD765_FDD_READY 0x040 | |
| 79 | ||
| 80 | #define UPD765_MF 0x40 | |
| 81 | #define UPD765_MT 0x80 | |
| 82 | ||
| 83 | #define UPD765_RESET 0x080 | |
| 84 | ||
| 85 | #define UPD765_BAD_MEDIA 0x100 | |
| 86 | ||
| 87 | struct upd765_t | |
| 98 | void upd765_family_device::device_start() | |
| 88 | 99 | { |
| 89 | devcb_resolved_write_line out_int_func; | |
| 90 | devcb_resolved_write_line out_drq_func; | |
| 100 | for(int i=0; i != 4; i++) { | |
| 101 | char name[2]; | |
| 102 | flopi[i].tm = timer_alloc(i); | |
| 103 | flopi[i].id = i; | |
| 104 | if(select_connected) { | |
| 105 | name[0] = '0'+i; | |
| 106 | name[1] = 0; | |
| 107 | floppy_connector *con = subdevice<floppy_connector>(name); | |
| 108 | if(con) { | |
| 109 | flopi[i].dev = con->get_device(); | |
| 110 | flopi[i].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(upd765_family_device::index_callback), this)); | |
| 111 | } else | |
| 112 | flopi[i].dev = NULL; | |
| 113 | } else | |
| 114 | flopi[i].dev = NULL; | |
| 115 | } | |
| 116 | cur_rate = 250000; | |
| 117 | tc = false; | |
| 91 | 118 | |
| 92 | unsigned long sector_counter; | |
| 93 | /* version of fdc to emulate */ | |
| 94 | UPD765_VERSION version; | |
| 119 | // reset at upper levels may cause a write to tc ending up with | |
| 120 | // live_sync, which will crash if the live structure isn't | |
| 121 | // initialized enough | |
| 95 | 122 | |
| 96 | /* main status register */ | |
| 97 | unsigned char FDC_main; | |
| 98 | /* data register */ | |
| 99 | unsigned char upd765_data_reg; | |
| 123 | cur_live.tm = attotime::never; | |
| 124 | cur_live.state = IDLE; | |
| 125 | cur_live.next_state = -1; | |
| 126 | cur_live.fi = NULL; | |
| 100 | 127 | |
| 101 | unsigned char c,h,r,n; | |
| 128 | if(ready_polled) { | |
| 129 | poll_timer = timer_alloc(TIMER_DRIVE_READY_POLLING); | |
| 130 | poll_timer->adjust(attotime::from_usec(1024), 0, attotime::from_usec(1024)); | |
| 131 | } else | |
| 132 | poll_timer = NULL; | |
| 102 | 133 | |
| 103 | int sector_id; | |
| 134 | cur_irq = false; | |
| 135 | } | |
| 104 | 136 | |
| 105 | int data_type; | |
| 106 | ||
| 107 | char format_data[4]; | |
| 108 | ||
| 109 | UPD765_PHASE upd765_phase; | |
| 110 | unsigned int upd765_command_bytes[16]; | |
| 111 | unsigned int upd765_result_bytes[16]; | |
| 112 | unsigned int upd765_transfer_bytes_remaining; | |
| 113 | unsigned int upd765_transfer_bytes_count; | |
| 114 | unsigned int upd765_status[4]; | |
| 115 | /* present cylinder number per drive */ | |
| 116 | unsigned int pcn[4]; | |
| 117 | ||
| 118 | /* drive being accessed. drive outputs from fdc */ | |
| 119 | unsigned int drive; | |
| 120 | /* side being accessed: side output from fdc */ | |
| 121 | unsigned int side; | |
| 122 | ||
| 123 | ||
| 124 | /* step rate time in us */ | |
| 125 | unsigned long srt_in_ms; | |
| 126 | ||
| 127 | unsigned int ncn; | |
| 128 | ||
| 129 | // unsigned int upd765_id_index; | |
| 130 | char *execution_phase_data; | |
| 131 | unsigned int upd765_flags; | |
| 132 | ||
| 133 | // unsigned char specify[2]; | |
| 134 | // unsigned char perpendicular_mode[1]; | |
| 135 | ||
| 136 | int command; | |
| 137 | ||
| 138 | UINT8 ready_changed; | |
| 139 | ||
| 140 | emu_timer *seek_timer; | |
| 141 | emu_timer *timer; | |
| 142 | int timer_type; | |
| 143 | ||
| 144 | emu_timer *command_timer; | |
| 145 | ||
| 146 | char *data_buffer; | |
| 147 | const upd765_interface *intf; | |
| 148 | ||
| 149 | bool pool; | |
| 150 | }; | |
| 151 | ||
| 152 | //static void upd765_setup_data_request(unsigned char Data); | |
| 153 | static void upd765_setup_command(device_t *device); | |
| 154 | static TIMER_CALLBACK(upd765_continue_command); | |
| 155 | static int upd765_sector_count_complete(device_t *device); | |
| 156 | static void upd765_increment_sector(device_t *device); | |
| 157 | static void upd765_update_state(device_t *device); | |
| 158 | static void upd765_set_dma_drq(device_t *device,int state); | |
| 159 | static void upd765_set_int(device_t *device,int state); | |
| 160 | ||
| 161 | static const INT8 upd765_cmd_size[32] = | |
| 137 | void upd765_family_device::device_reset() | |
| 162 | 138 | { |
| 163 | 1,1,9,3,2,9,9,2,1,9,2,1,9,6,1,3, | |
| 164 | 1,9,1,1,1,1,9,1,1,9,1,1,1,9,1,1 | |
| 165 | }; | |
| 139 | main_phase = PHASE_CMD; | |
| 140 | for(int i=0; i<4; i++) { | |
| 141 | flopi[i].main_state = IDLE; | |
| 142 | flopi[i].sub_state = IDLE; | |
| 143 | flopi[i].irq_seek = false; | |
| 144 | flopi[i].live = false; | |
| 145 | flopi[i].ready = !ready_polled; | |
| 146 | flopi[i].irq_polled = false; | |
| 147 | } | |
| 148 | data_irq = false; | |
| 149 | internal_drq = false; | |
| 150 | fifo_pos = 0; | |
| 151 | command_pos = 0; | |
| 152 | result_pos = 0; | |
| 153 | fifocfg = FIF_DIS; | |
| 154 | cur_live.fi = 0; | |
| 155 | drq = false; | |
| 156 | cur_live.tm = attotime::never; | |
| 157 | cur_live.state = IDLE; | |
| 158 | cur_live.next_state = -1; | |
| 159 | cur_live.fi = NULL; | |
| 160 | tc_done = false; | |
| 161 | st0 = st1 = st2 = st3 = 0x00; | |
| 162 | dor = dor_reset; | |
| 166 | 163 | |
| 167 | INLINE upd765_t *get_safe_token(device_t *device) | |
| 168 | { | |
| 169 | assert(device != NULL); | |
| 170 | assert(device->type() == UPD765A || device->type() == UPD765B || | |
| 171 | device->type() == SMC37C78 || device->type() == UPD72065); | |
| 172 | ||
| 173 | return (upd765_t *)downcast<upd765a_device *>(device)->token(); | |
| 164 | check_irq(); | |
| 165 | if(ready_polled) | |
| 166 | poll_timer->adjust(attotime::from_usec(1024), 0, attotime::from_usec(1024)); | |
| 174 | 167 | } |
| 175 | 168 | |
| 176 | ||
| 169 | void upd765_family_device::tc_w(bool _tc) | |
| 177 | 170 | { |
| 178 | device_t *image = NULL; | |
| 179 | upd765_t *fdc = get_safe_token(device); | |
| 180 | ||
| 181 | if (!fdc->intf->get_image) | |
| 182 | { | |
| 183 | if (fdc->intf->floppy_drive_tags[fdc->drive] != NULL) | |
| 184 | { | |
| 185 | if (device->owner() != NULL) | |
| 186 | image = device->owner()->subdevice(fdc->intf->floppy_drive_tags[fdc->drive]); | |
| 187 | else | |
| 188 | image = device->machine().device(fdc->intf->floppy_drive_tags[fdc->drive]); | |
| 189 | } | |
| 190 | } | |
| 191 | else | |
| 192 | { | |
| 193 | image = fdc->intf->get_image(device, fdc->drive); | |
| 194 | } | |
| 195 | return image; | |
| 171 | logerror("%s: tc=%d\n", tag(), _tc); | |
| 172 | if(tc != _tc && _tc) { | |
| 173 | live_sync(); | |
| 174 | tc_done = true; | |
| 175 | tc = _tc; | |
| 176 | if(cur_live.fi) | |
| 177 | general_continue(*cur_live.fi); | |
| 178 | } else | |
| 179 | tc = _tc; | |
| 196 | 180 | } |
| 197 | 181 | |
| 198 | ||
| 182 | void upd765_family_device::ready_w(bool _ready) | |
| 199 | 183 | { |
| 200 | upd765_t *fdc = get_safe_token(device); | |
| 201 | /* drive index upd765 sees */ | |
| 202 | fdc->drive = fdc->upd765_command_bytes[1] & 0x03; | |
| 203 | /* side index upd765 sees */ | |
| 204 | fdc->side = (fdc->upd765_command_bytes[1]>>2) & 0x01; | |
| 184 | external_ready = _ready; | |
| 205 | 185 | } |
| 206 | 186 | |
| 207 | ||
| 208 | /* setup status register 0 based on data in status register 1 and 2 */ | |
| 209 | static void upd765_setup_st0(device_t *device) | |
| 187 | bool upd765_family_device::get_ready(int fid) | |
| 210 | 188 | { |
| 211 | upd765_t *fdc = get_safe_token(device); | |
| 212 | /* clear completition status bits, drive bits and side bits */ | |
| 213 | fdc->upd765_status[0] &= ~((1<<7) | (1<<6) | (1<<2) | (1<<1) | (1<<0)); | |
| 214 | /* fill in drive */ | |
| 215 | fdc->upd765_status[0] |= fdc->drive | (fdc->side<<2); | |
| 189 | if(ready_connected) | |
| 190 | return flopi[fid].dev ? flopi[fid].dev->ready_r() : false; | |
| 191 | return external_ready; | |
| 192 | } | |
| 216 | 193 | |
| 217 | /* fill in completion status bits based on bits in st0, st1, st2 */ | |
| 218 | /* no error bits set */ | |
| 219 | if ((fdc->upd765_status[1] | fdc->upd765_status[2])==0) | |
| 220 | { | |
| 221 | return; | |
| 194 | void upd765_family_device::set_floppy(floppy_image_device *flop) | |
| 195 | { | |
| 196 | for(int fid=0; fid<4; fid++) { | |
| 197 | if(flopi[fid].dev) | |
| 198 | flopi[fid].dev->setup_index_pulse_cb(floppy_image_device::index_pulse_cb()); | |
| 199 | flopi[fid].dev = flop; | |
| 222 | 200 | } |
| 223 | ||
| 224 | fdc->upd765_status[0] |= 0x040; | |
| 201 | if(flop) | |
| 202 | flop->setup_index_pulse_cb(floppy_image_device::index_pulse_cb(FUNC(upd765_family_device::index_callback), this)); | |
| 225 | 203 | } |
| 226 | 204 | |
| 227 | ||
| 228 | static int upd765_n_to_bytes(int n) | |
| 205 | READ8_MEMBER(upd765_family_device::sra_r) | |
| 229 | 206 | { |
| 230 | /* 0-> 128 bytes, 1->256 bytes, 2->512 bytes etc */ | |
| 231 | /* data_size = ((1<<(N+7)) */ | |
| 232 | return 1<<(n+7); | |
| 207 | UINT8 sra = 0; | |
| 208 | int fid = dor & 3; | |
| 209 | floppy_info &fi = flopi[fid]; | |
| 210 | if(fi.dir) | |
| 211 | sra |= 0x01; | |
| 212 | if(fi.index) | |
| 213 | sra |= 0x04; | |
| 214 | if(cur_rate >= 500000) | |
| 215 | sra |= 0x08; | |
| 216 | if(fi.dev && fi.dev->trk00_r()) | |
| 217 | sra |= 0x10; | |
| 218 | if(fi.main_state == SEEK_WAIT_STEP_SIGNAL_TIME) | |
| 219 | sra |= 0x20; | |
| 220 | sra |= 0x40; | |
| 221 | if(cur_irq) | |
| 222 | sra |= 0x80; | |
| 223 | if(mode == MODE_M30) | |
| 224 | sra ^= 0x1f; | |
| 225 | return sra; | |
| 233 | 226 | } |
| 234 | 227 | |
| 235 | ||
| 228 | READ8_MEMBER(upd765_family_device::srb_r) | |
| 236 | 229 | { |
| 237 | upd765_t *fdc = get_safe_token(device); | |
| 238 | fdc->FDC_main |= 0x080; | |
| 230 | return 0; | |
| 239 | 231 | } |
| 240 | 232 | |
| 241 | ||
| 233 | READ8_MEMBER(upd765_family_device::dor_r) | |
| 242 | 234 | { |
| 243 | upd765_t *fdc = get_safe_token(device); | |
| 244 | fdc->FDC_main &= ~0x080; | |
| 235 | return dor; | |
| 245 | 236 | } |
| 246 | 237 | |
| 247 | ||
| 238 | WRITE8_MEMBER(upd765_family_device::dor_w) | |
| 248 | 239 | { |
| 249 | upd765_t *fdc = get_safe_token(device); | |
| 240 | logerror("%s: dor = %02x\n", tag(), data); | |
| 241 | UINT8 diff = dor ^ data; | |
| 242 | dor = data; | |
| 243 | if(diff & 4) { | |
| 244 | UINT8 tmp = dor_reset; | |
| 245 | dor_reset = dor; | |
| 246 | device_reset(); | |
| 247 | dor_reset = tmp; | |
| 248 | } | |
| 250 | 249 | |
| 251 | if (fdc->intf->rdy_pin == UPD765_RDY_PIN_CONNECTED) | |
| 252 | { | |
| 253 | device_t *img = current_image(device); | |
| 254 | if (img!=NULL) { | |
| 255 | return floppy_drive_get_flag_state(img, FLOPPY_DRIVE_READY); | |
| 256 | } else { | |
| 257 | return 0; | |
| 258 | } | |
| 250 | for(int i=0; i<4; i++) { | |
| 251 | floppy_info &fi = flopi[i]; | |
| 252 | if(fi.dev) | |
| 253 | fi.dev->mon_w(!(dor & (0x10 << i))); | |
| 259 | 254 | } |
| 260 | else | |
| 261 | return 1; | |
| 255 | check_irq(); | |
| 262 | 256 | } |
| 263 | 257 | |
| 264 | ||
| 258 | READ8_MEMBER(upd765_family_device::tdr_r) | |
| 265 | 259 | { |
| 266 | /* tested on Amstrad CPC */ | |
| 260 | return 0; | |
| 261 | } | |
| 267 | 262 | |
| 268 | /* if a seek is done without drive connected: */ | |
| 269 | /* abnormal termination of command, | |
| 270 | seek complete, | |
| 271 | not ready | |
| 272 | */ | |
| 263 | WRITE8_MEMBER(upd765_family_device::tdr_w) | |
| 264 | { | |
| 265 | } | |
| 273 | 266 | |
| 274 | /* if a seek is done with drive connected, but disc missing: */ | |
| 275 | /* abnormal termination of command, | |
| 276 | seek complete, | |
| 277 | not ready */ | |
| 267 | READ8_MEMBER(upd765_family_device::msr_r) | |
| 268 | { | |
| 269 | UINT32 msr = 0; | |
| 270 | switch(main_phase) { | |
| 271 | case PHASE_CMD: | |
| 272 | msr |= MSR_RQM; | |
| 273 | if(command_pos) | |
| 274 | msr |= MSR_CB; | |
| 275 | break; | |
| 276 | case PHASE_EXEC: | |
| 277 | msr |= MSR_CB; | |
| 278 | if(spec & SPEC_ND) | |
| 279 | msr |= MSR_EXM; | |
| 280 | if(internal_drq) | |
| 281 | msr |= MSR_RQM; | |
| 282 | break; | |
| 278 | 283 | |
| 279 | /* if a seek is done with drive connected and disc in drive */ | |
| 280 | /* seek complete */ | |
| 284 | case PHASE_RESULT: | |
| 285 | msr |= MSR_RQM|MSR_DIO|MSR_CB; | |
| 286 | break; | |
| 287 | } | |
| 288 | for(int i=0; i<4; i++) | |
| 289 | if(flopi[i].main_state == RECALIBRATE || flopi[i].main_state == SEEK) | |
| 290 | msr |= 1<<i; | |
| 281 | 291 | |
| 282 | ||
| 283 | /* On the PC however, it appears that recalibrates and seeks can be performed without | |
| 284 | a disc in the drive. */ | |
| 285 | ||
| 286 | /* Therefore, the above output is dependant on the state of the drive */ | |
| 287 | ||
| 288 | /* In the Amstrad CPC, the drive select is provided by the UPD765. A single port is also | |
| 289 | assigned for setting the drive motor state. The motor state controls the motor of the selected | |
| 290 | drive */ | |
| 291 | ||
| 292 | /* On the PC the drive can be selected with the DIGITAL OUTPUT REGISTER, and the motor of each | |
| 293 | of the 4 possible drives is also settable using the same register */ | |
| 294 | ||
| 295 | /* Assumption for PC: (NOT TESTED - NEEDS VERIFICATION) */ | |
| 296 | ||
| 297 | /* If a seek is done without drive connected: */ | |
| 298 | /* abnormal termination of command, | |
| 299 | seek complete, | |
| 300 | fault | |
| 301 | */ | |
| 302 | ||
| 303 | /* if a seek is done with drive connected, but disc missing: */ | |
| 304 | /* seek complete */ | |
| 305 | ||
| 306 | /* if a seek is done with drive connected and disc in drive: */ | |
| 307 | /* seek complete */ | |
| 308 | ||
| 309 | /* On Amstrad CPC: | |
| 310 | If drive not connected, or drive connected but disc not in drive, not ready! | |
| 311 | If drive connected and drive motor on, ready! | |
| 312 | On PC: | |
| 313 | Drive is always ready! | |
| 314 | ||
| 315 | In 37c78 docs, the ready bits of the upd765 are marked as unused. | |
| 316 | This indicates it is always ready!!!!! | |
| 317 | */ | |
| 318 | ||
| 319 | device_t *img = current_image(device); | |
| 320 | upd765_t *fdc = get_safe_token(device); | |
| 321 | ||
| 322 | fdc->pcn[fdc->drive] = fdc->ncn; | |
| 323 | ||
| 324 | fdc->upd765_status[0] = 0x20; | |
| 325 | ||
| 326 | /* drive ready? */ | |
| 327 | if (img != NULL && upd765_get_rdy(device)) | |
| 328 | { | |
| 329 | /* recalibrate? */ | |
| 330 | if (fdc->upd765_flags & UPD765_SEEK_OPERATION_IS_RECALIBRATE) | |
| 331 | { | |
| 332 | /* not at track 0? */ | |
| 333 | if (fdc->pcn[fdc->drive] != 0) | |
| 334 | /* no, track 0 failed after 77 steps */ | |
| 335 | fdc->upd765_status[0] |= 0x40 | 0x10; | |
| 336 | } | |
| 292 | if(data_irq) { | |
| 293 | data_irq = false; | |
| 294 | check_irq(); | |
| 337 | 295 | } |
| 338 | else | |
| 339 | { | |
| 340 | /* abnormal termination, not ready */ | |
| 341 | fdc->upd765_status[0] |= 0x40 | 0x08; | |
| 342 | } | |
| 343 | 296 | |
| 344 | /* set drive and side. note: commented out side to avoid problems with the tf20 */ | |
| 345 | fdc->upd765_status[0] |= fdc->drive; //| (fdc->side<<2); | |
| 346 | ||
| 347 | upd765_set_int(device,0); | |
| 348 | upd765_set_int(device,1); | |
| 349 | ||
| 350 | fdc->upd765_flags &= ~UPD765_SEEK_ACTIVE; | |
| 351 | ||
| 352 | upd765_idle(device); | |
| 297 | return msr; | |
| 353 | 298 | } |
| 354 | 299 | |
| 355 | ||
| 300 | WRITE8_MEMBER(upd765_family_device::dsr_w) | |
| 356 | 301 | { |
| 357 | device_t *device = (device_t *)ptr; | |
| 358 | upd765_t *fdc = get_safe_token(device); | |
| 359 | /* seek complete */ | |
| 360 | upd765_seek_complete(device); | |
| 302 | dsr = data; | |
| 303 | cur_rate = rates[dsr & 3]; | |
| 304 | } | |
| 361 | 305 | |
| 362 | fdc->seek_timer->reset(); | |
| 306 | void upd765_family_device::set_rate(int rate) | |
| 307 | { | |
| 308 | cur_rate = rate; | |
| 363 | 309 | } |
| 364 | 310 | |
| 365 | ||
| 311 | READ8_MEMBER(upd765_family_device::fifo_r) | |
| 366 | 312 | { |
| 367 | upd765_t *fdc = get_safe_token(device); | |
| 368 | /* type 0 = data transfer mode in execution phase */ | |
| 369 | if (fdc->timer_type == 0) | |
| 370 | { | |
| 371 | /* set data request */ | |
| 372 | upd765_set_data_request(device); | |
| 313 | UINT8 r = 0; | |
| 314 | switch(main_phase) { | |
| 315 | case PHASE_EXEC: | |
| 316 | if(internal_drq) | |
| 317 | return fifo_pop(false); | |
| 318 | logerror("%s: fifo_r in phase %d\n", tag(), main_phase); | |
| 319 | break; | |
| 373 | 320 | |
| 374 | fdc->timer_type = 4; | |
| 375 | ||
| 376 | if (!(fdc->upd765_flags & UPD765_DMA_MODE)) | |
| 377 | { | |
| 378 | if (fdc->upd765_command_bytes[0] & UPD765_MF) | |
| 379 | { | |
| 380 | /* MFM */ | |
| 381 | fdc->timer->reset(attotime::from_usec(13)); | |
| 382 | } | |
| 383 | else | |
| 384 | { | |
| 385 | /* FM */ | |
| 386 | fdc->timer->reset(attotime::from_usec(27)); | |
| 387 | } | |
| 388 | } | |
| 389 | else | |
| 390 | { | |
| 391 | upd765_timer_func(device, fdc->timer_type); | |
| 392 | } | |
| 321 | case PHASE_RESULT: | |
| 322 | r = result[0]; | |
| 323 | result_pos--; | |
| 324 | memmove(result, result+1, result_pos); | |
| 325 | if(!result_pos) | |
| 326 | main_phase = PHASE_CMD; | |
| 327 | break; | |
| 328 | default: | |
| 329 | logerror("%s: fifo_r in phase %d\n", tag(), main_phase); | |
| 330 | break; | |
| 393 | 331 | } |
| 394 | else if (fdc->timer_type==2) | |
| 395 | { | |
| 396 | /* result phase begin */ | |
| 397 | 332 | |
| 398 | /* generate a int for specific commands */ | |
| 399 | switch (fdc->command) { | |
| 400 | case 2: /* read a track */ | |
| 401 | case 5: /* write data */ | |
| 402 | case 6: /* read data */ | |
| 403 | case 9: /* write deleted data */ | |
| 404 | case 10: /* read id */ | |
| 405 | case 12: /* read deleted data */ | |
| 406 | case 13: /* format at track */ | |
| 407 | case 17: /* scan equal */ | |
| 408 | case 19: /* scan low or equal */ | |
| 409 | case 29: /* scan high or equal */ | |
| 410 | upd765_set_int(device,1); | |
| 411 | break; | |
| 333 | return r; | |
| 334 | } | |
| 412 | 335 | |
| 413 | default: | |
| 336 | WRITE8_MEMBER(upd765_family_device::fifo_w) | |
| 337 | { | |
| 338 | switch(main_phase) { | |
| 339 | case PHASE_CMD: { | |
| 340 | command[command_pos++] = data; | |
| 341 | int cmd = check_command(); | |
| 342 | if(cmd == C_INCOMPLETE) | |
| 414 | 343 | break; |
| 344 | if(cmd == C_INVALID) { | |
| 345 | logerror("%s: Invalid on %02x\n", tag(), command[0]); | |
| 346 | exit(1); | |
| 347 | command_pos = 0; | |
| 348 | return; | |
| 415 | 349 | } |
| 416 | ||
| 417 | upd765_set_data_request(device); | |
| 418 | ||
| 419 | fdc->timer->reset(); | |
| 350 | start_command(cmd); | |
| 351 | break; | |
| 420 | 352 | } |
| 421 | else if (fdc->timer_type == 4) | |
| 422 | { | |
| 423 | /* if in dma mode, a int is not generated per byte. If not in DMA mode | |
| 424 | a int is generated per byte */ | |
| 425 | if (fdc->upd765_flags & UPD765_DMA_MODE) | |
| 426 | { | |
| 427 | upd765_set_dma_drq(device,1); | |
| 353 | case PHASE_EXEC: | |
| 354 | if(internal_drq) { | |
| 355 | fifo_push(data, false); | |
| 356 | return; | |
| 428 | 357 | } |
| 429 | else | |
| 430 | { | |
| 431 | if (fdc->FDC_main & (1<<7)) | |
| 432 | { | |
| 433 | /* set int to indicate data is ready */ | |
| 434 | upd765_set_int(device,1); | |
| 435 | } | |
| 436 | } | |
| 358 | logerror("%s: fifo_w in phase %d\n", tag(), main_phase); | |
| 359 | break; | |
| 437 | 360 | |
| 438 | fdc->timer->reset(); | |
| 361 | default: | |
| 362 | logerror("%s: fifo_w in phase %d\n", tag(), main_phase); | |
| 363 | break; | |
| 439 | 364 | } |
| 440 | 365 | } |
| 441 | 366 | |
| 442 | ||
| 367 | UINT8 upd765_family_device::do_dir_r() | |
| 443 | 368 | { |
| 444 | device_t *device = (device_t *)ptr; | |
| 445 | upd765_timer_func(device,param); | |
| 369 | floppy_info &fi = flopi[dor & 3]; | |
| 370 | if(fi.dev) | |
| 371 | return fi.dev->dskchg_r() ? 0x00 : 0x80; | |
| 372 | return 0x00; | |
| 446 | 373 | } |
| 447 | 374 | |
| 448 | /* after (32-27) the DRQ is set, then 27 us later, the int is set. | |
| 449 | I don't know if this is correct, but it is required for the PCW driver. | |
| 450 | In this driver, the first NMI calls the handler function, furthur NMI's are | |
| 451 | effectively disabled by reading the data before the NMI int can be set. | |
| 452 | */ | |
| 453 | ||
| 454 | static void upd765_setup_timed_generic(device_t *device, int timer_type, attotime duration) | |
| 375 | READ8_MEMBER(upd765_family_device::dir_r) | |
| 455 | 376 | { |
| 456 | upd765_t *fdc = get_safe_token(device); | |
| 457 | ||
| 458 | fdc->timer_type = timer_type; | |
| 459 | ||
| 460 | if (!(fdc->upd765_flags & UPD765_DMA_MODE)) | |
| 461 | { | |
| 462 | fdc->timer->adjust(duration); | |
| 463 | } | |
| 464 | else | |
| 465 | { | |
| 466 | upd765_timer_func(device,fdc->timer_type); | |
| 467 | fdc->timer->reset(); | |
| 468 | } | |
| 377 | return do_dir_r(); | |
| 469 | 378 | } |
| 470 | 379 | |
| 471 | /* setup data request */ | |
| 472 | static void upd765_setup_timed_data_request(device_t *device, int bytes) | |
| 380 | WRITE8_MEMBER(upd765_family_device::ccr_w) | |
| 473 | 381 | { |
| 474 | /* setup timer to trigger in UPD765_DATA_RATE us */ | |
| 475 | upd765_setup_timed_generic(device, 0, attotime::from_usec(32-27) /*UPD765_DATA_RATE)*bytes*/); | |
| 382 | dsr = (dsr & 0xfc) | (data & 3); | |
| 383 | cur_rate = rates[data & 3]; | |
| 476 | 384 | } |
| 477 | 385 | |
| 478 | /* setup result data request */ | |
| 479 | static void upd765_setup_timed_result_data_request(device_t *device) | |
| 386 | void upd765_family_device::set_drq(bool state) | |
| 480 | 387 | { |
| 481 | upd765_setup_timed_generic(device, 2, attotime::from_usec(UPD765_DATA_RATE*2)); | |
| 388 | if(state != drq) { | |
| 389 | drq = state; | |
| 390 | if(!drq_cb.isnull()) | |
| 391 | drq_cb(drq); | |
| 392 | } | |
| 482 | 393 | } |
| 483 | 394 | |
| 484 | ||
| 485 | /* sets up a timer to issue a seek complete in signed_tracks time */ | |
| 486 | static void upd765_setup_timed_int(device_t *device,int signed_tracks) | |
| 395 | bool upd765_family_device::get_drq() const | |
| 487 | 396 | { |
| 488 | upd765_t *fdc = get_safe_token(device); | |
| 489 | /* setup timer to signal after seek time is complete */ | |
| 490 | fdc->seek_timer->adjust(attotime::from_double(fdc->srt_in_ms*abs(signed_tracks)*0.001)); | |
| 397 | return drq; | |
| 491 | 398 | } |
| 492 | 399 | |
| 493 | ||
| 400 | void upd765_family_device::enable_transfer() | |
| 494 | 401 | { |
| 495 | device_t *img; | |
| 496 | int signed_tracks; | |
| 497 | upd765_t *fdc = get_safe_token(device); | |
| 498 | ||
| 499 | fdc->upd765_flags |= UPD765_SEEK_ACTIVE; | |
| 500 | ||
| 501 | if (is_recalibrate) | |
| 502 | { | |
| 503 | /* head cannot be specified with recalibrate */ | |
| 504 | fdc->upd765_command_bytes[1] &=~0x04; | |
| 505 | } | |
| 506 | ||
| 507 | upd765_setup_drive_and_side(device); | |
| 508 | ||
| 509 | img = current_image(device); | |
| 510 | ||
| 511 | fdc->FDC_main |= (1<<fdc->drive); | |
| 512 | fdc->FDC_main |= 0x20; // execution phase | |
| 513 | fdc->FDC_main &= ~0x10; // not busy, can send another seek/recalibrate | |
| 514 | // for a different drive, or sense int status | |
| 515 | ||
| 516 | /* recalibrate command? */ | |
| 517 | if (is_recalibrate) | |
| 518 | { | |
| 519 | fdc->upd765_flags |= UPD765_SEEK_OPERATION_IS_RECALIBRATE; | |
| 520 | ||
| 521 | fdc->ncn = 0; | |
| 522 | ||
| 523 | /* if drive is already at track 0, or drive is not ready */ | |
| 524 | if (img == NULL || floppy_tk00_r(img) == CLEAR_LINE || (!upd765_get_rdy(device))) | |
| 525 | { | |
| 526 | /* seek completed */ | |
| 527 | // upd765_seek_complete(device); | |
| 528 | // delay for the time of 1 step, the PCW does not like immediate recalibrates | |
| 529 | upd765_setup_timed_int(device,1); | |
| 402 | if(spec & SPEC_ND) { | |
| 403 | // PIO | |
| 404 | if(!internal_drq) { | |
| 405 | internal_drq = true; | |
| 406 | check_irq(); | |
| 530 | 407 | } |
| 531 | else | |
| 532 | { | |
| 533 | /* is drive present? */ | |
| 534 | if (1) //image_slotexists(img)) //fix me | |
| 535 | { | |
| 536 | /* yes - calculate real number of tracks to seek */ | |
| 537 | 408 | |
| 538 | int current_track; | |
| 539 | ||
| 540 | /* get current track */ | |
| 541 | current_track = floppy_drive_get_current_track(img); | |
| 542 | ||
| 543 | /* get number of tracks to seek */ | |
| 544 | signed_tracks = -current_track; | |
| 545 | } | |
| 546 | else | |
| 547 | { | |
| 548 | /* no, seek 77 tracks and then stop */ | |
| 549 | /* true for UPD765A, but not for other variants */ | |
| 550 | signed_tracks = -77; | |
| 551 | } | |
| 552 | ||
| 553 | /* perform seek - if drive isn't present it will not do anything */ | |
| 554 | floppy_drive_seek(img, signed_tracks); | |
| 555 | ||
| 556 | if (signed_tracks!=0) | |
| 557 | { | |
| 558 | upd765_setup_timed_int(device,signed_tracks); | |
| 559 | } | |
| 560 | else | |
| 561 | { | |
| 562 | upd765_seek_complete(device); | |
| 563 | } | |
| 564 | } | |
| 409 | } else { | |
| 410 | // DMA | |
| 411 | if(!drq) | |
| 412 | set_drq(true); | |
| 565 | 413 | } |
| 566 | else | |
| 567 | { | |
| 568 | ||
| 569 | fdc->upd765_flags &= ~UPD765_SEEK_OPERATION_IS_RECALIBRATE; | |
| 570 | ||
| 571 | fdc->ncn = fdc->upd765_command_bytes[2]; | |
| 572 | ||
| 573 | /* get signed tracks */ | |
| 574 | signed_tracks = fdc->ncn - fdc->pcn[fdc->drive]; | |
| 575 | ||
| 576 | /* perform seek - if drive isn't present it will not do anything */ | |
| 577 | floppy_drive_seek(img, signed_tracks); | |
| 578 | ||
| 579 | /* if no tracks to seek, or drive is not ready, seek is complete */ | |
| 580 | if (img == NULL || (signed_tracks==0) || (!upd765_get_rdy(device))) | |
| 581 | { | |
| 582 | upd765_seek_complete(device); | |
| 583 | } | |
| 584 | else | |
| 585 | { | |
| 586 | /* seek complete - issue an interrupt */ | |
| 587 | upd765_setup_timed_int(device,signed_tracks); | |
| 588 | } | |
| 589 | } | |
| 590 | // upd765_idle(device); | |
| 591 | 414 | } |
| 592 | 415 | |
| 593 | ||
| 594 | ||
| 595 | static void upd765_setup_execution_phase_read(device_t *device, char *ptr, int size) | |
| 416 | void upd765_family_device::disable_transfer() | |
| 596 | 417 | { |
| 597 | upd765_t *fdc = get_safe_token(device); | |
| 598 | ||
| 599 | // fdc->FDC_main &= ~0x040; /* FDC->CPU */ | |
| 600 | fdc->FDC_main |= 0x040; /* FDC->CPU */ | |
| 601 | ||
| 602 | fdc->upd765_transfer_bytes_count = 0; | |
| 603 | fdc->upd765_transfer_bytes_remaining = size; | |
| 604 | fdc->execution_phase_data = ptr; | |
| 605 | fdc->upd765_phase = UPD765_EXECUTION_PHASE_READ; | |
| 606 | ||
| 607 | upd765_setup_timed_data_request(device, 1); | |
| 418 | if(spec & SPEC_ND) { | |
| 419 | internal_drq = false; | |
| 420 | check_irq(); | |
| 421 | } else | |
| 422 | set_drq(false); | |
| 608 | 423 | } |
| 609 | 424 | |
| 610 | ||
| 425 | void upd765_family_device::fifo_push(UINT8 data, bool internal) | |
| 611 | 426 | { |
| 612 | upd765_t *fdc = get_safe_token(device); | |
| 613 | ||
| 614 | fdc->FDC_main &= ~0x040; /* FDC->CPU */ | |
| 615 | ||
| 616 | fdc->upd765_transfer_bytes_count = 0; | |
| 617 | fdc->upd765_transfer_bytes_remaining = size; | |
| 618 | fdc->execution_phase_data = ptr; | |
| 619 | fdc->upd765_phase = UPD765_EXECUTION_PHASE_WRITE; | |
| 620 | ||
| 621 | /* setup a data request with first byte */ | |
| 622 | upd765_setup_timed_data_request(device,1); | |
| 427 | if(fifo_pos == 16) { | |
| 428 | if(internal) | |
| 429 | st1 |= ST1_OR; | |
| 430 | return; | |
| 431 | } | |
| 432 | fifo[fifo_pos++] = data; | |
| 433 | fifo_expected--; | |
| 434 | ||
| 435 | int thr = (fifocfg & FIF_THR)+1; | |
| 436 | if(!fifo_write && (!fifo_expected || fifo_pos >= thr || (fifocfg & FIF_DIS))) | |
| 437 | enable_transfer(); | |
| 438 | if(fifo_write && (fifo_pos == 16 || !fifo_expected)) | |
| 439 | disable_transfer(); | |
| 623 | 440 | } |
| 624 | 441 | |
| 625 | 442 | |
| 626 | ||
| 443 | UINT8 upd765_family_device::fifo_pop(bool internal) | |
| 627 | 444 | { |
| 628 | upd765_t *fdc = get_safe_token(device); | |
| 629 | ||
| 630 | fdc->FDC_main |= 0x040; /* FDC->CPU */ | |
| 631 | fdc->FDC_main &= ~0x020; /* not execution phase */ | |
| 632 | ||
| 633 | fdc->upd765_transfer_bytes_count = 0; | |
| 634 | fdc->upd765_transfer_bytes_remaining = byte_count; | |
| 635 | fdc->upd765_phase = UPD765_RESULT_PHASE; | |
| 636 | ||
| 637 | upd765_setup_timed_result_data_request(device); | |
| 445 | if(!fifo_pos) { | |
| 446 | if(internal) | |
| 447 | st1 |= ST1_OR; | |
| 448 | return 0; | |
| 449 | } | |
| 450 | UINT8 r = fifo[0]; | |
| 451 | fifo_pos--; | |
| 452 | memmove(fifo, fifo+1, fifo_pos); | |
| 453 | if(!fifo_write && !fifo_pos) | |
| 454 | disable_transfer(); | |
| 455 | int thr = fifocfg & 15; | |
| 456 | if(fifo_write && fifo_expected && (fifo_pos <= thr || (fifocfg & 0x20))) | |
| 457 | enable_transfer(); | |
| 458 | return r; | |
| 638 | 459 | } |
| 639 | 460 | |
| 640 | void upd765_i | |
| 461 | void upd765_family_device::fifo_expect(int size, bool write) | |
| 641 | 462 | { |
| 642 | upd765_t *fdc = get_safe_token(device); | |
| 643 | ||
| 644 | fdc->FDC_main &= ~0x040; /* CPU->FDC */ | |
| 645 | fdc->FDC_main &= ~0x020; /* not execution phase */ | |
| 646 | fdc->FDC_main &= ~0x010; /* not busy */ | |
| 647 | fdc->upd765_phase = UPD765_COMMAND_PHASE_FIRST_BYTE; | |
| 648 | ||
| 649 | upd765_set_data_request(device); | |
| 463 | fifo_expected = size; | |
| 464 | fifo_write = write; | |
| 465 | if(fifo_write) | |
| 466 | enable_transfer(); | |
| 650 | 467 | } |
| 651 | 468 | |
| 652 | ||
| 653 | ||
| 654 | /* change flags */ | |
| 655 | static void upd765_change_flags(device_t *device,unsigned int flags, unsigned int mask) | |
| 469 | READ8_MEMBER(upd765_family_device::mdma_r) | |
| 656 | 470 | { |
| 657 | unsigned int new_flags; | |
| 658 | unsigned int changed_flags; | |
| 659 | upd765_t *fdc = get_safe_token(device); | |
| 660 | ||
| 661 | assert((flags & ~mask) == 0); | |
| 662 | ||
| 663 | /* compute the new flags and which ones have changed */ | |
| 664 | new_flags = fdc->upd765_flags & ~mask; | |
| 665 | new_flags |= flags; | |
| 666 | changed_flags = fdc->upd765_flags ^ new_flags; | |
| 667 | fdc->upd765_flags = new_flags; | |
| 668 | ||
| 669 | /* if interrupt changed, call the handler */ | |
| 670 | if (changed_flags & UPD765_INT) | |
| 671 | fdc->out_int_func((fdc->upd765_flags & UPD765_INT) ? 1 : 0); | |
| 672 | ||
| 673 | /* if DRQ changed, call the handler */ | |
| 674 | if (changed_flags & UPD765_DMA_DRQ) | |
| 675 | fdc->out_drq_func((fdc->upd765_flags & UPD765_DMA_DRQ) ? 1 : 0); | |
| 471 | return dma_r(); | |
| 676 | 472 | } |
| 677 | 473 | |
| 678 | ||
| 679 | ||
| 680 | /* set int output */ | |
| 681 | static void upd765_set_int(device_t *device, int state) | |
| 474 | WRITE8_MEMBER(upd765_family_device::mdma_w) | |
| 682 | 475 | { |
| 683 | if (LOG_INTERRUPT) | |
| 684 | logerror("upd765_set_int(): state=%d\n", state); | |
| 685 | upd765_change_flags(device, state ? UPD765_INT : 0, UPD765_INT); | |
| 476 | dma_w(data); | |
| 686 | 477 | } |
| 687 | 478 | |
| 688 | ||
| 689 | ||
| 690 | /* set dma request output */ | |
| 691 | static void upd765_set_dma_drq(device_t *device, int state) | |
| 479 | UINT8 upd765_family_device::dma_r() | |
| 692 | 480 | { |
| 693 | u | |
| 481 | return fifo_pop(false); | |
| 694 | 482 | } |
| 695 | 483 | |
| 696 | ||
| 484 | void upd765_family_device::dma_w(UINT8 data) | |
| 697 | 485 | { |
| 698 | upd765_t *fdc = get_safe_token(device); | |
| 699 | ||
| 700 | return (fdc->upd765_flags & UPD765_INT) ? 1 : 0; | |
| 486 | fifo_push(data, false); | |
| 701 | 487 | } |
| 702 | 488 | |
| 703 | ||
| 489 | void upd765_family_device::live_start(floppy_info &fi, int state) | |
| 704 | 490 | { |
| 705 | upd765_t *fdc = get_safe_token(device); | |
| 491 | cur_live.tm = machine().time(); | |
| 492 | cur_live.state = state; | |
| 493 | cur_live.next_state = -1; | |
| 494 | cur_live.fi = &fi; | |
| 495 | cur_live.shift_reg = 0; | |
| 496 | cur_live.crc = 0xffff; | |
| 497 | cur_live.bit_counter = 0; | |
| 498 | cur_live.data_separator_phase = false; | |
| 499 | cur_live.data_reg = 0; | |
| 500 | cur_live.previous_type = live_info::PT_NONE; | |
| 501 | cur_live.data_bit_context = false; | |
| 502 | cur_live.byte_counter = 0; | |
| 503 | cur_live.pll.reset(cur_live.tm); | |
| 504 | cur_live.pll.set_clock(attotime::from_hz(cur_rate*2)); | |
| 505 | checkpoint_live = cur_live; | |
| 506 | fi.live = true; | |
| 706 | 507 | |
| 707 | | |
| 508 | live_run(); | |
| 708 | 509 | } |
| 709 | 510 | |
| 710 | ||
| 711 | /* Drive ready */ | |
| 712 | ||
| 713 | /* | |
| 714 | ||
| 715 | A drive will report ready if: | |
| 716 | - drive is selected | |
| 717 | - disc is in the drive | |
| 718 | - disk is rotating at a constant speed (normally 300rpm) | |
| 719 | ||
| 720 | On more modern PCs, a ready signal is not provided by the drive. | |
| 721 | This signal is not used in the PC design and was eliminated to save costs | |
| 722 | If you look at the datasheets for the modern UPD765 variants, you will see the Ready | |
| 723 | signal is not mentioned. | |
| 724 | ||
| 725 | On the original UPD765A, ready signal is required, and some commands will fail if the drive | |
| 726 | is not ready. | |
| 727 | ||
| 728 | ||
| 729 | ||
| 730 | ||
| 731 | */ | |
| 732 | ||
| 733 | ||
| 734 | ||
| 735 | ||
| 736 | /* done when ready state of drive changes */ | |
| 737 | /* this ignores if command is active, in which case command should terminate immediatly | |
| 738 | with error */ | |
| 739 | static void upd765_set_ready_change_callback(device_t *controller, device_t *img, int state) | |
| 511 | void upd765_family_device::checkpoint() | |
| 740 | 512 | { |
| 741 | upd765_t *fdc = get_safe_token(controller); | |
| 742 | int drive = floppy_get_drive(img); | |
| 743 | ||
| 744 | if (LOG_EXTRA) | |
| 745 | logerror("upd765: ready state change\n"); | |
| 746 | ||
| 747 | /* drive that changed state */ | |
| 748 | fdc->upd765_status[0] = 0x0c0 | drive; | |
| 749 | ||
| 750 | /* not ready */ | |
| 751 | if (state==0 && fdc->intf->rdy_pin == UPD765_RDY_PIN_CONNECTED ) | |
| 752 | fdc->upd765_status[0] |= 8; | |
| 753 | ||
| 754 | /* trigger an int */ | |
| 755 | upd765_set_int(controller, 1); | |
| 513 | if(cur_live.fi) | |
| 514 | cur_live.pll.commit(cur_live.fi->dev, cur_live.tm); | |
| 515 | checkpoint_live = cur_live; | |
| 756 | 516 | } |
| 757 | 517 | |
| 758 | ||
| 759 | /* terminal count input */ | |
| 760 | WRITE_LINE_DEVICE_HANDLER( upd765_tc_w ) | |
| 518 | void upd765_family_device::rollback() | |
| 761 | 519 | { |
| 762 | int old_state; | |
| 763 | upd765_t *fdc = get_safe_token(device); | |
| 764 | ||
| 765 | old_state = fdc->upd765_flags; | |
| 766 | ||
| 767 | /* clear drq */ | |
| 768 | upd765_set_dma_drq(device, 0); | |
| 769 | ||
| 770 | fdc->upd765_flags &= ~UPD765_TC; | |
| 771 | if (state) | |
| 772 | { | |
| 773 | fdc->upd765_flags |= UPD765_TC; | |
| 774 | } | |
| 775 | ||
| 776 | /* changed state? */ | |
| 777 | if (((fdc->upd765_flags^old_state) & UPD765_TC)!=0) | |
| 778 | { | |
| 779 | /* now set? */ | |
| 780 | if ((fdc->upd765_flags & UPD765_TC)!=0) | |
| 781 | { | |
| 782 | /* yes */ | |
| 783 | if (fdc->timer) | |
| 784 | { | |
| 785 | if (fdc->timer_type==0) | |
| 786 | { | |
| 787 | fdc->timer->reset(); | |
| 788 | ||
| 789 | ||
| 790 | } | |
| 791 | } | |
| 792 | ||
| 793 | #ifdef NO_END_OF_CYLINDER | |
| 794 | fdc->command_timer->adjust(attotime::zero); | |
| 795 | #else | |
| 796 | upd765_update_state(device); | |
| 797 | #endif | |
| 798 | } | |
| 799 | } | |
| 520 | cur_live = checkpoint_live; | |
| 800 | 521 | } |
| 801 | 522 | |
| 802 | ||
| 523 | void upd765_family_device::live_delay(int state) | |
| 803 | 524 | { |
| 804 | upd765_t *fdc = get_safe_token(device); | |
| 805 | if (LOG_EXTRA) | |
| 806 | logerror("%s: upd765_status_r: %02x\n", space.machine().describe_context(), fdc->FDC_main); | |
| 807 | return fdc->FDC_main; | |
| 525 | cur_live.next_state = state; | |
| 526 | if(cur_live.tm != machine().time()) | |
| 527 | cur_live.fi->tm->adjust(cur_live.tm - machine().time()); | |
| 528 | else | |
| 529 | live_sync(); | |
| 808 | 530 | } |
| 809 | 531 | |
| 810 | ||
| 811 | /* control mark handling code */ | |
| 812 | ||
| 813 | /* if SK==1, and we are executing a read data command, and a deleted data mark is found, | |
| 814 | skip it. | |
| 815 | if SK==1, and we are executing a read deleted data command, and a data mark is found, | |
| 816 | skip it. */ | |
| 817 | ||
| 818 | static int upd765_read_skip_sector(device_t *device) | |
| 532 | void upd765_family_device::live_sync() | |
| 819 | 533 | { |
| 820 | upd765_t *fdc = get_safe_token(device); | |
| 821 | /* skip set? */ | |
| 822 | if ((fdc->upd765_command_bytes[0] & (1<<5))!=0) | |
| 823 | { | |
| 824 | /* read data? */ | |
| 825 | if (fdc->command == 0x06) | |
| 826 | { | |
| 827 | /* did we just find a sector with deleted data mark? */ | |
| 828 | if (fdc->data_type == UPD765_DAM_DELETED_DATA) | |
| 829 | { | |
| 830 | /* skip it */ | |
| 831 | return TRUE; | |
| 534 | if(!cur_live.tm.is_never()) { | |
| 535 | if(cur_live.tm > machine().time()) { | |
| 536 | rollback(); | |
| 537 | live_run(machine().time()); | |
| 538 | cur_live.pll.commit(cur_live.fi->dev, cur_live.tm); | |
| 539 | } else { | |
| 540 | cur_live.pll.commit(cur_live.fi->dev, cur_live.tm); | |
| 541 | if(cur_live.next_state != -1) { | |
| 542 | cur_live.state = cur_live.next_state; | |
| 543 | cur_live.next_state = -1; | |
| 832 | 544 | } |
| 833 | } | |
| 834 | /* deleted data? */ | |
| 835 | else | |
| 836 | if (fdc->command == 0x0c) | |
| 837 | { | |
| 838 | /* did we just find a sector with data mark ? */ | |
| 839 | if (fdc->data_type == UPD765_DAM_DATA) | |
| 840 | { | |
| 841 | /* skip it */ | |
| 842 | return TRUE; | |
| 545 | if(cur_live.state == IDLE) { | |
| 546 | cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm); | |
| 547 | cur_live.tm = attotime::never; | |
| 548 | cur_live.fi->live = false; | |
| 549 | cur_live.fi = 0; | |
| 843 | 550 | } |
| 844 | 551 | } |
| 552 | cur_live.next_state = -1; | |
| 553 | checkpoint(); | |
| 845 | 554 | } |
| 846 | ||
| 847 | /* do not skip */ | |
| 848 | return FALSE; | |
| 849 | 555 | } |
| 850 | 556 | |
| 851 | /* this is much closer to how the upd765 actually gets sectors */ | |
| 852 | /* used by read data, read deleted data, write data, write deleted data */ | |
| 853 | /* What the upd765 does: | |
| 854 | ||
| 855 | - get next sector id from disc | |
| 856 | - if sector id matches id specified in command, it will | |
| 857 | search for next data block and read data from it. | |
| 858 | ||
| 859 | - if the index is seen twice while it is searching for a sector, then the sector cannot be found | |
| 860 | */ | |
| 861 | ||
| 862 | static void upd765_get_next_id(device_t *device, chrn_id *id) | |
| 557 | void upd765_family_device::live_abort() | |
| 863 | 558 | { |
| 864 | upd765_t *fdc = get_safe_token(device); | |
| 865 | device_t *img = current_image(device); | |
| 559 | if(!cur_live.tm.is_never() && cur_live.tm > machine().time()) { | |
| 560 | rollback(); | |
| 561 | live_run(machine().time()); | |
| 562 | } | |
| 866 | 563 | |
| 867 | /* get next id from disc */ | |
| 868 | floppy_drive_get_next_id(img, fdc->side,id); | |
| 869 | ||
| 870 | fdc->sector_id = id->data_id; | |
| 871 | ||
| 872 | /* set correct data type */ | |
| 873 | fdc->data_type = UPD765_DAM_DATA; | |
| 874 | if (id->flags & ID_FLAG_DELETED_DATA) | |
| 875 | { | |
| 876 | fdc->data_type = UPD765_DAM_DELETED_DATA; | |
| 564 | if(cur_live.fi) { | |
| 565 | cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm); | |
| 566 | cur_live.fi->live = false; | |
| 567 | cur_live.fi = 0; | |
| 877 | 568 | } |
| 569 | ||
| 570 | cur_live.tm = attotime::never; | |
| 571 | cur_live.state = IDLE; | |
| 572 | cur_live.next_state = -1; | |
| 878 | 573 | } |
| 879 | 574 | |
| 880 | ||
| 575 | void upd765_family_device::live_run(attotime limit) | |
| 881 | 576 | { |
| 882 | upd765_t *fdc = get_safe_token(device); | |
| 883 | device_t *img = current_image(device); | |
| 884 | chrn_id id; | |
| 577 | if(cur_live.state == IDLE || cur_live.next_state != -1) | |
| 578 | return; | |
| 885 | 579 | |
| 886 | /* number of times we have seen index hole */ | |
| 887 | int index_count = 0; | |
| 580 | if(limit == attotime::never) { | |
| 581 | if(cur_live.fi->dev) | |
| 582 | limit = cur_live.fi->dev->time_next_index(); | |
| 583 | if(limit == attotime::never) { | |
| 584 | // Happens when there's no disk or if the fdc is not | |
| 585 | // connected to a drive, hence no index pulse. Force a | |
| 586 | // sync from time to time in that case, so that the main | |
| 587 | // cpu timeout isn't too painful. Avoids looping into | |
| 588 | // infinity looking for data too. | |
| 888 | 589 | |
| 889 | if (fdc->upd765_flags & UPD765_BAD_MEDIA) { | |
| 890 | fdc->upd765_status[1] |= 1; | |
| 891 | return FALSE; | |
| 590 | limit = machine().time() + attotime::from_msec(1); | |
| 591 | cur_live.fi->tm->adjust(attotime::from_msec(1)); | |
| 592 | } | |
| 892 | 593 | } |
| 893 | 594 | |
| 894 | /* get sector id's */ | |
| 895 | do | |
| 896 | { | |
| 897 | upd765_get_next_id(device, &id); | |
| 595 | for(;;) { | |
| 898 | 596 | |
| 899 | /* tested on Amstrad CPC - All bytes must match, otherwise | |
| 900 | a NO DATA error is reported */ | |
| 901 | if (id.R == fdc->upd765_command_bytes[4]) | |
| 902 | { | |
| 903 | if (id.C == fdc->upd765_command_bytes[2]) | |
| 904 | { | |
| 905 | if (id.H == fdc->upd765_command_bytes[3]) | |
| 906 | { | |
| 907 | if (id.N == fdc->upd765_command_bytes[5]) | |
| 908 | { | |
| 909 | /* end of cylinder is set if: | |
| 910 | 1. sector data is read completely (i.e. no other errors occur like | |
| 911 | no data. | |
| 912 | 2. sector being read is same specified by EOT | |
| 913 | 3. terminal count is not received */ | |
| 914 | if (fdc->upd765_command_bytes[4]==fdc->upd765_command_bytes[6]) | |
| 915 | { | |
| 916 | /* set end of cylinder */ | |
| 917 | fdc->upd765_status[1] |= UPD765_ST1_END_OF_CYLINDER; | |
| 918 | } | |
| 597 | switch(cur_live.state) { | |
| 598 | case SEARCH_ADDRESS_MARK_HEADER: | |
| 599 | if(read_one_bit(limit)) | |
| 600 | return; | |
| 601 | #if 0 | |
| 602 | fprintf(stderr, "%s: shift = %04x data=%02x c=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 603 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 604 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 605 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 606 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 607 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 608 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 609 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 610 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 611 | cur_live.bit_counter); | |
| 612 | #endif | |
| 919 | 613 | |
| 920 | return TRUE; | |
| 921 | } | |
| 922 | } | |
| 614 | if(cur_live.shift_reg == 0x4489) { | |
| 615 | cur_live.crc = 0x443b; | |
| 616 | cur_live.data_separator_phase = false; | |
| 617 | cur_live.bit_counter = 0; | |
| 618 | cur_live.state = READ_HEADER_BLOCK_HEADER; | |
| 923 | 619 | } |
| 924 | else | |
| 925 | { | |
| 926 | /* the specified sector ID was found, however, the C value specified | |
| 927 | in the read/write command did not match the C value read from the disc */ | |
| 620 | break; | |
| 928 | 621 | |
| 929 | /* no data - checked on Amstrad CPC */ | |
| 930 | fdc->upd765_status[1] |= UPD765_ST1_NO_DATA; | |
| 931 | /* bad C value */ | |
| 932 | fdc->upd765_status[2] |= UPD765_ST2_WRONG_CYLINDER; | |
| 622 | case READ_HEADER_BLOCK_HEADER: { | |
| 623 | if(read_one_bit(limit)) | |
| 624 | return; | |
| 625 | #if 0 | |
| 626 | fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 627 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 628 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 629 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 630 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 631 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 632 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 633 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 634 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 635 | cur_live.bit_counter); | |
| 636 | #endif | |
| 637 | if(cur_live.bit_counter & 15) | |
| 638 | break; | |
| 933 | 639 | |
| 934 | if (id.C == 0x0ff) | |
| 935 | { | |
| 936 | /* the C value is 0x0ff which indicates a bad track in the IBM soft-sectored | |
| 937 | format */ | |
| 938 | fdc->upd765_status[2] |= UPD765_ST2_BAD_CYLINDER; | |
| 939 | } | |
| 640 | int slot = cur_live.bit_counter >> 4; | |
| 940 | 641 | |
| 941 | return FALSE; | |
| 642 | if(slot < 3) { | |
| 643 | if(cur_live.shift_reg != 0x4489) | |
| 644 | cur_live.state = SEARCH_ADDRESS_MARK_HEADER; | |
| 645 | break; | |
| 942 | 646 | } |
| 647 | if(cur_live.data_reg != 0xfe) { | |
| 648 | cur_live.state = SEARCH_ADDRESS_MARK_HEADER; | |
| 649 | break; | |
| 650 | } | |
| 651 | ||
| 652 | cur_live.bit_counter = 0; | |
| 653 | cur_live.state = READ_ID_BLOCK; | |
| 654 | ||
| 655 | break; | |
| 943 | 656 | } |
| 944 | 657 | |
| 945 | /* index set? */ | |
| 946 | if (floppy_drive_get_flag_state(img, FLOPPY_DRIVE_INDEX)) | |
| 947 | { | |
| 948 | index_count++; | |
| 658 | case READ_ID_BLOCK: { | |
| 659 | if(read_one_bit(limit)) | |
| 660 | return; | |
| 661 | if(cur_live.bit_counter & 15) | |
| 662 | break; | |
| 663 | int slot = (cur_live.bit_counter >> 4)-1; | |
| 664 | ||
| 665 | if(0) | |
| 666 | fprintf(stderr, "%s: slot=%d data=%02x crc=%04x\n", tts(cur_live.tm).cstr(), slot, cur_live.data_reg, cur_live.crc); | |
| 667 | cur_live.idbuf[slot] = cur_live.data_reg; | |
| 668 | if(slot == 5) { | |
| 669 | live_delay(IDLE); | |
| 670 | return; | |
| 671 | } | |
| 672 | break; | |
| 949 | 673 | } |
| 950 | 674 | |
| 951 | } | |
| 952 | while (index_count!=2); | |
| 675 | case SEARCH_ADDRESS_MARK_DATA: | |
| 676 | if(read_one_bit(limit)) | |
| 677 | return; | |
| 678 | #if 0 | |
| 679 | fprintf(stderr, "%s: shift = %04x data=%02x c=%d.%x\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 680 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 681 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 682 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 683 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 684 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 685 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 686 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 687 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 688 | cur_live.bit_counter >> 4, cur_live.bit_counter & 15); | |
| 689 | #endif | |
| 690 | // Large tolerance due to perpendicular recording at extended density | |
| 691 | if(cur_live.bit_counter > 62*16) { | |
| 692 | live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); | |
| 693 | return; | |
| 694 | } | |
| 953 | 695 | |
| 954 | if (fdc->upd765_command_bytes[4] != fdc->upd765_command_bytes[6]) | |
| 955 | { | |
| 956 | /* no data - specified sector ID was not found */ | |
| 957 | fdc->upd765_status[1] |= UPD765_ST1_NO_DATA; | |
| 958 | } | |
| 696 | if(cur_live.bit_counter >= 28*16 && cur_live.shift_reg == 0x4489) { | |
| 697 | cur_live.crc = 0x443b; | |
| 698 | cur_live.data_separator_phase = false; | |
| 699 | cur_live.bit_counter = 0; | |
| 700 | cur_live.state = READ_DATA_BLOCK_HEADER; | |
| 701 | } | |
| 702 | break; | |
| 959 | 703 | |
| 960 | return 0; | |
| 961 | } | |
| 962 | ||
| 963 | static void upd765_read_complete(device_t *device) | |
| 964 | { | |
| 965 | upd765_t *fdc = get_safe_token(device); | |
| 966 | /* causes problems!!! - need to fix */ | |
| 967 | #ifdef NO_END_OF_CYLINDER | |
| 968 | /* set end of cylinder */ | |
| 969 | fdc->upd765_status[1] &= ~UPD765_ST1_END_OF_CYLINDER; | |
| 970 | #else | |
| 971 | /* completed read command */ | |
| 972 | ||
| 973 | /* end of cylinder is set when: | |
| 974 | - a whole sector has been read | |
| 975 | - terminal count input is not set | |
| 976 | - AND the the sector specified by EOT was read | |
| 977 | */ | |
| 978 | ||
| 979 | /* if end of cylinder is set, and we did receive a terminal count, then clear it */ | |
| 980 | if ((fdc->upd765_flags & UPD765_TC)!=0) | |
| 981 | { | |
| 982 | /* set end of cylinder */ | |
| 983 | fdc->upd765_status[1] &= ~UPD765_ST1_END_OF_CYLINDER; | |
| 984 | } | |
| 704 | case READ_DATA_BLOCK_HEADER: { | |
| 705 | if(read_one_bit(limit)) | |
| 706 | return; | |
| 707 | #if 0 | |
| 708 | fprintf(stderr, "%s: shift = %04x data=%02x counter=%d\n", tts(cur_live.tm).cstr(), cur_live.shift_reg, | |
| 709 | (cur_live.shift_reg & 0x4000 ? 0x80 : 0x00) | | |
| 710 | (cur_live.shift_reg & 0x1000 ? 0x40 : 0x00) | | |
| 711 | (cur_live.shift_reg & 0x0400 ? 0x20 : 0x00) | | |
| 712 | (cur_live.shift_reg & 0x0100 ? 0x10 : 0x00) | | |
| 713 | (cur_live.shift_reg & 0x0040 ? 0x08 : 0x00) | | |
| 714 | (cur_live.shift_reg & 0x0010 ? 0x04 : 0x00) | | |
| 715 | (cur_live.shift_reg & 0x0004 ? 0x02 : 0x00) | | |
| 716 | (cur_live.shift_reg & 0x0001 ? 0x01 : 0x00), | |
| 717 | cur_live.bit_counter); | |
| 985 | 718 | #endif |
| 719 | if(cur_live.bit_counter & 15) | |
| 720 | break; | |
| 986 | 721 | |
| 987 | | |
| 722 | int slot = cur_live.bit_counter >> 4; | |
| 988 | 723 | |
| 989 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 990 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 991 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 992 | fdc->upd765_result_bytes[3] = fdc->upd765_command_bytes[2]; /* C */ | |
| 993 | fdc->upd765_result_bytes[4] = fdc->upd765_command_bytes[3]; /* H */ | |
| 994 | fdc->upd765_result_bytes[5] = fdc->upd765_command_bytes[4]; /* R */ | |
| 995 | fdc->upd765_result_bytes[6] = fdc->upd765_command_bytes[5]; /* N */ | |
| 996 | ||
| 997 | upd765_setup_result_phase(device,7); | |
| 998 | } | |
| 999 | ||
| 1000 | static void upd765_read_data(device_t *device) | |
| 1001 | { | |
| 1002 | upd765_t *fdc = get_safe_token(device); | |
| 1003 | device_t *img = current_image(device); | |
| 1004 | ||
| 1005 | if (!upd765_get_rdy(device)) | |
| 1006 | { | |
| 1007 | fdc->upd765_status[0] = 0x0c0 | (1<<4) | fdc->drive | (fdc->side<<2); | |
| 1008 | fdc->upd765_status[1] = 0x00; | |
| 1009 | fdc->upd765_status[2] = 0x00; | |
| 1010 | ||
| 1011 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 1012 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 1013 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 1014 | fdc->upd765_result_bytes[3] = fdc->upd765_command_bytes[2]; /* C */ | |
| 1015 | fdc->upd765_result_bytes[4] = fdc->upd765_command_bytes[3]; /* H */ | |
| 1016 | fdc->upd765_result_bytes[5] = fdc->upd765_command_bytes[4]; /* R */ | |
| 1017 | fdc->upd765_result_bytes[6] = fdc->upd765_command_bytes[5]; /* N */ | |
| 1018 | upd765_setup_result_phase(device,7); | |
| 1019 | return; | |
| 1020 | } | |
| 1021 | ||
| 1022 | if (LOG_VERBOSE) | |
| 1023 | logerror("sector c: %02x h: %02x r: %02x n: %02x\n",fdc->upd765_command_bytes[2], fdc->upd765_command_bytes[3],fdc->upd765_command_bytes[4], fdc->upd765_command_bytes[5]); | |
| 1024 | ||
| 1025 | /* find a sector to read data from */ | |
| 1026 | { | |
| 1027 | int found_sector_to_read; | |
| 1028 | ||
| 1029 | found_sector_to_read = 0; | |
| 1030 | /* check for finished reading sectors */ | |
| 1031 | do | |
| 1032 | { | |
| 1033 | /* get matching sector */ | |
| 1034 | if (upd765_get_matching_sector(device)) | |
| 1035 | { | |
| 1036 | ||
| 1037 | /* skip it? */ | |
| 1038 | if (upd765_read_skip_sector(device)) | |
| 1039 | { | |
| 1040 | /* yes */ | |
| 1041 | ||
| 1042 | /* check that we haven't finished reading all sectors */ | |
| 1043 | if (upd765_sector_count_complete(device)) | |
| 1044 | { | |
| 1045 | /* read complete */ | |
| 1046 | upd765_read_complete(device); | |
| 1047 | return; | |
| 1048 | } | |
| 1049 | ||
| 1050 | /* read not finished */ | |
| 1051 | ||
| 1052 | /* increment sector count */ | |
| 1053 | upd765_increment_sector(device); | |
| 724 | if(slot < 3) { | |
| 725 | if(cur_live.shift_reg != 0x4489) { | |
| 726 | live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); | |
| 727 | return; | |
| 1054 | 728 | } |
| 1055 | else | |
| 1056 | { | |
| 1057 | /* found a sector to read */ | |
| 1058 | found_sector_to_read = 1; | |
| 1059 | } | |
| 729 | break; | |
| 1060 | 730 | } |
| 1061 | else | |
| 1062 | { | |
| 1063 | /* error in finding sector */ | |
| 1064 | upd765_read_complete(device); | |
| 731 | if(cur_live.data_reg != 0xfb && cur_live.data_reg != 0xfd) { | |
| 732 | live_delay(SEARCH_ADDRESS_MARK_DATA_FAILED); | |
| 1065 | 733 | return; |
| 1066 | 734 | } |
| 735 | ||
| 736 | cur_live.bit_counter = 0; | |
| 737 | cur_live.state = READ_SECTOR_DATA; | |
| 738 | break; | |
| 1067 | 739 | } |
| 1068 | while (found_sector_to_read==0); | |
| 1069 | } | |
| 1070 | 740 | |
| 1071 | { | |
| 1072 | int data_size; | |
| 741 | case SEARCH_ADDRESS_MARK_DATA_FAILED: | |
| 742 | st1 |= ST1_MA; | |
| 743 | st2 |= ST2_MD; | |
| 744 | cur_live.state = IDLE; | |
| 745 | return; | |
| 1073 | 746 | |
| 1074 | data_size = upd765_n_to_bytes(fdc->upd765_command_bytes[5]); | |
| 747 | case READ_SECTOR_DATA: { | |
| 748 | if(read_one_bit(limit)) | |
| 749 | return; | |
| 750 | if(cur_live.bit_counter & 15) | |
| 751 | break; | |
| 752 | int slot = (cur_live.bit_counter >> 4)-1; | |
| 753 | if(slot < sector_size) { | |
| 754 | // Sector data | |
| 755 | live_delay(READ_SECTOR_DATA_BYTE); | |
| 756 | return; | |
| 1075 | 757 | |
| 1076 | floppy_drive_read_sector_data(img, fdc->side, fdc->sector_id,fdc->data_buffer,data_size); | |
| 758 | } else if(slot < sector_size+2) { | |
| 759 | // CRC | |
| 760 | if(slot == sector_size+1) { | |
| 761 | live_delay(IDLE); | |
| 762 | return; | |
| 763 | } | |
| 764 | } | |
| 765 | break; | |
| 766 | } | |
| 1077 | 767 | |
| 1078 | upd765_setup_execution_phase_read(device,fdc->data_buffer, data_size); | |
| 1079 | } | |
| 1080 | } | |
| 768 | case READ_SECTOR_DATA_BYTE: | |
| 769 | if(!tc_done) | |
| 770 | fifo_push(cur_live.data_reg, true); | |
| 771 | cur_live.state = READ_SECTOR_DATA; | |
| 772 | checkpoint(); | |
| 773 | break; | |
| 1081 | 774 | |
| 775 | case WRITE_SECTOR_SKIP_GAP2: | |
| 776 | cur_live.bit_counter = 0; | |
| 777 | cur_live.byte_counter = 0; | |
| 778 | cur_live.state = WRITE_SECTOR_SKIP_GAP2_BYTE; | |
| 779 | checkpoint(); | |
| 780 | break; | |
| 1082 | 781 | |
| 1083 | static void upd765_format_track(device_t *device) | |
| 1084 | { | |
| 1085 | upd765_t *fdc = get_safe_token(device); | |
| 1086 | device_t *img = current_image(device); | |
| 782 | case WRITE_SECTOR_SKIP_GAP2_BYTE: | |
| 783 | if(read_one_bit(limit)) | |
| 784 | return; | |
| 785 | if(cur_live.bit_counter != 22*16) | |
| 786 | break; | |
| 787 | cur_live.bit_counter = 0; | |
| 788 | cur_live.byte_counter = 0; | |
| 789 | live_delay(WRITE_SECTOR_DATA); | |
| 790 | return; | |
| 1087 | 791 | |
| 1088 | /* write protected? */ | |
| 1089 | if (floppy_wpt_r(img) == CLEAR_LINE) | |
| 1090 | { | |
| 1091 | fdc->upd765_status[1] |= UPD765_ST1_NOT_WRITEABLE; | |
| 792 | case WRITE_SECTOR_DATA: | |
| 793 | if(cur_live.byte_counter < 12) | |
| 794 | live_write_mfm(0x00); | |
| 795 | else if(cur_live.byte_counter < 15) | |
| 796 | live_write_raw(0x4489); | |
| 797 | else if(cur_live.byte_counter < 16) { | |
| 798 | cur_live.crc = 0xcdb4; | |
| 799 | live_write_mfm(command[0] & 0x08 ? 0xf8 : 0xfb); | |
| 800 | } else if(cur_live.byte_counter < 16+sector_size) | |
| 801 | live_write_mfm(tc_done && !fifo_pos? 0x00 : fifo_pop(true)); | |
| 802 | else if(cur_live.byte_counter < 16+sector_size+2) | |
| 803 | live_write_mfm(cur_live.crc >> 8); | |
| 804 | else if(cur_live.byte_counter < 16+sector_size+2+command[7]) | |
| 805 | live_write_mfm(0x4e); | |
| 806 | else { | |
| 807 | cur_live.pll.stop_writing(cur_live.fi->dev, cur_live.tm); | |
| 808 | cur_live.state = IDLE; | |
| 809 | return; | |
| 810 | } | |
| 811 | cur_live.state = WRITE_SECTOR_DATA_BYTE; | |
| 812 | cur_live.bit_counter = 16; | |
| 813 | checkpoint(); | |
| 814 | break; | |
| 1092 | 815 | |
| 1093 | upd765_setup_st0(device); | |
| 1094 | /* TODO: Check result is correct */ | |
| 1095 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 1096 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 1097 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 1098 | fdc->upd765_result_bytes[3] = fdc->format_data[0]; | |
| 1099 | fdc->upd765_result_bytes[4] = fdc->format_data[1]; | |
| 1100 | fdc->upd765_result_bytes[5] = fdc->format_data[2]; | |
| 1101 | fdc->upd765_result_bytes[6] = fdc->format_data[3]; | |
| 1102 | upd765_setup_result_phase(device,7); | |
| 816 | case WRITE_TRACK_PRE_SECTORS: | |
| 817 | if(!cur_live.byte_counter && command[3]) | |
| 818 | fifo_expect(4, true); | |
| 819 | if(cur_live.byte_counter < 80) | |
| 820 | live_write_mfm(0x4e); | |
| 821 | else if(cur_live.byte_counter < 92) | |
| 822 | live_write_mfm(0x00); | |
| 823 | else if(cur_live.byte_counter < 95) | |
| 824 | live_write_raw(0x5224); | |
| 825 | else if(cur_live.byte_counter < 96) | |
| 826 | live_write_mfm(0xfc); | |
| 827 | else if(cur_live.byte_counter < 146) | |
| 828 | live_write_mfm(0x4e); | |
| 829 | else { | |
| 830 | cur_live.state = WRITE_TRACK_SECTOR; | |
| 831 | cur_live.byte_counter = 0; | |
| 832 | break; | |
| 833 | } | |
| 834 | cur_live.state = WRITE_TRACK_PRE_SECTORS_BYTE; | |
| 835 | cur_live.bit_counter = 16; | |
| 836 | checkpoint(); | |
| 837 | break; | |
| 1103 | 838 | |
| 1104 | return; | |
| 1105 | } | |
| 839 | case WRITE_TRACK_SECTOR: | |
| 840 | if(!cur_live.byte_counter) { | |
| 841 | command[3]--; | |
| 842 | if(command[3]) | |
| 843 | fifo_expect(4, true); | |
| 844 | } | |
| 845 | if(cur_live.byte_counter < 12) | |
| 846 | live_write_mfm(0x00); | |
| 847 | else if(cur_live.byte_counter < 15) | |
| 848 | live_write_raw(0x4489); | |
| 849 | else if(cur_live.byte_counter < 16) { | |
| 850 | cur_live.crc = 0xcdb4; | |
| 851 | live_write_mfm(0xfe); | |
| 852 | } else if(cur_live.byte_counter < 20) | |
| 853 | live_write_mfm(fifo_pop(true)); | |
| 854 | else if(cur_live.byte_counter < 22) | |
| 855 | live_write_mfm(cur_live.crc >> 8); | |
| 856 | else if(cur_live.byte_counter < 44) | |
| 857 | live_write_mfm(0x4e); | |
| 858 | else if(cur_live.byte_counter < 56) | |
| 859 | live_write_mfm(0x00); | |
| 860 | else if(cur_live.byte_counter < 59) | |
| 861 | live_write_raw(0x4489); | |
| 862 | else if(cur_live.byte_counter < 60) { | |
| 863 | cur_live.crc = 0xcdb4; | |
| 864 | live_write_mfm(0xfb); | |
| 865 | } else if(cur_live.byte_counter < 60+sector_size) | |
| 866 | live_write_mfm(command[5]); | |
| 867 | else if(cur_live.byte_counter < 62+sector_size) | |
| 868 | live_write_mfm(cur_live.crc >> 8); | |
| 869 | else if(cur_live.byte_counter < 62+sector_size+command[4]) | |
| 870 | live_write_mfm(0x4e); | |
| 871 | else { | |
| 872 | cur_live.byte_counter = 0; | |
| 873 | cur_live.state = command[3] ? WRITE_TRACK_SECTOR : WRITE_TRACK_POST_SECTORS; | |
| 874 | break; | |
| 875 | } | |
| 876 | cur_live.state = WRITE_TRACK_SECTOR_BYTE; | |
| 877 | cur_live.bit_counter = 16; | |
| 878 | checkpoint(); | |
| 879 | break; | |
| 1106 | 880 | |
| 1107 | upd765_setup_execution_phase_write(device, &fdc->format_data[0], 4); | |
| 1108 | } | |
| 881 | case WRITE_TRACK_POST_SECTORS: | |
| 882 | live_write_mfm(0x4e); | |
| 883 | cur_live.state = WRITE_TRACK_POST_SECTORS_BYTE; | |
| 884 | cur_live.bit_counter = 16; | |
| 885 | checkpoint(); | |
| 886 | break; | |
| 1109 | 887 | |
| 1110 | static void upd765_read_a_track(device_t *device) | |
| 1111 | { | |
| 1112 | upd765_t *fdc = get_safe_token(device); | |
| 1113 | int data_size; | |
| 1114 | ||
| 1115 | /* SKIP not allowed with this command! */ | |
| 1116 | ||
| 1117 | /* get next id */ | |
| 1118 | chrn_id id; | |
| 1119 | ||
| 1120 | upd765_get_next_id(device, &id); | |
| 1121 | ||
| 1122 | /* TO BE CONFIRMED! */ | |
| 1123 | /* check id from disc */ | |
| 1124 | if (id.C==fdc->upd765_command_bytes[2]) | |
| 1125 | { | |
| 1126 | if (id.H==fdc->upd765_command_bytes[3]) | |
| 1127 | { | |
| 1128 | if (id.R==fdc->upd765_command_bytes[4]) | |
| 1129 | { | |
| 1130 | if (id.N==fdc->upd765_command_bytes[5]) | |
| 1131 | { | |
| 1132 | /* if ID found, then no data is not set */ | |
| 1133 | /* otherwise no data will remain set */ | |
| 1134 | fdc->upd765_status[1] &=~UPD765_ST1_NO_DATA; | |
| 1135 | } | |
| 888 | case WRITE_TRACK_PRE_SECTORS_BYTE: | |
| 889 | case WRITE_TRACK_SECTOR_BYTE: | |
| 890 | case WRITE_TRACK_POST_SECTORS_BYTE: | |
| 891 | case WRITE_SECTOR_DATA_BYTE: | |
| 892 | if(write_one_bit(limit)) | |
| 893 | return; | |
| 894 | if(cur_live.bit_counter == 0) { | |
| 895 | cur_live.byte_counter++; | |
| 896 | live_delay(cur_live.state-1); | |
| 897 | return; | |
| 1136 | 898 | } |
| 899 | break; | |
| 900 | ||
| 901 | default: | |
| 902 | logerror("%s: Unknown live state %d\n", tts(cur_live.tm).cstr(), cur_live.state); | |
| 903 | return; | |
| 1137 | 904 | } |
| 1138 | 905 | } |
| 1139 | ||
| 1140 | ||
| 1141 | data_size = upd765_n_to_bytes(id.N); | |
| 1142 | ||
| 1143 | floppy_drive_read_sector_data(current_image(device), fdc->side, fdc->sector_id,fdc->data_buffer,data_size); | |
| 1144 | ||
| 1145 | upd765_setup_execution_phase_read(device,fdc->data_buffer, data_size); | |
| 1146 | 906 | } |
| 1147 | 907 | |
| 1148 | ||
| 908 | int upd765_family_device::check_command() | |
| 1149 | 909 | { |
| 1150 | if (floppy_drive_get_flag_state(current_image(device), FLOPPY_DRIVE_INDEX)) | |
| 1151 | return 1; | |
| 1152 | return 0; | |
| 1153 | } | |
| 910 | // 0.000010 read track | |
| 911 | // 00000011 specify | |
| 912 | // 00000100 sense drive status | |
| 913 | // ..000101 write data | |
| 914 | // ...00110 read data | |
| 915 | // 00000111 recalibrate | |
| 916 | // 00001000 sense interrupt status | |
| 917 | // ..001001 write deleted data | |
| 918 | // 0.001010 read id | |
| 919 | // ...01100 read deleted data | |
| 920 | // 0.001101 format track | |
| 921 | // 00001110 dumpreg | |
| 922 | // 00001111 seek | |
| 923 | // 00010000 version | |
| 924 | // ...10001 scan equal | |
| 925 | // 00010010 perpendicular mode | |
| 926 | // 00010011 configure | |
| 927 | // .0010100 lock | |
| 928 | // ...10110 verify | |
| 929 | // ...11001 scan low or equal | |
| 930 | // ...11101 scan high or equal | |
| 931 | // 1.001111 relative seek | |
| 1154 | 932 | |
| 1155 | static void upd765_write_complete(device_t *device) | |
| 1156 | { | |
| 1157 | upd765_t *fdc = get_safe_token(device); | |
| 933 | // MSDOS 6.22 format uses 0xcd to format a track, which makes one | |
| 934 | // think only the bottom 5 bits are decoded. | |
| 1158 | 935 | |
| 1159 | /* causes problems!!! - need to fix */ | |
| 1160 | #ifdef NO_END_OF_CYLINDER | |
| 1161 | /* set end of cylinder */ | |
| 1162 | fdc->upd765_status[1] &= ~UPD765_ST1_END_OF_CYLINDER; | |
| 1163 | #else | |
| 1164 | /* completed read command */ | |
| 936 | switch(command[0] & 0x1f) { | |
| 937 | case 0x02: | |
| 938 | return command_pos == 9 ? C_READ_TRACK : C_INCOMPLETE; | |
| 1165 | 939 | |
| 1166 | /* end of cylinder is set when: | |
| 1167 | - a whole sector has been read | |
| 1168 | - terminal count input is not set | |
| 1169 | - AND the the sector specified by EOT was read | |
| 1170 | */ | |
| 940 | case 0x03: | |
| 941 | return command_pos == 3 ? C_SPECIFY : C_INCOMPLETE; | |
| 1171 | 942 | |
| 1172 | /* if end of cylinder is set, and we did receive a terminal count, then clear it */ | |
| 1173 | if ((fdc->upd765_flags & UPD765_TC)!=0) | |
| 1174 | { | |
| 1175 | /* set end of cylinder */ | |
| 1176 | fdc->upd765_status[1] &= ~UPD765_ST1_END_OF_CYLINDER; | |
| 1177 | } | |
| 1178 | #endif | |
| 943 | case 0x04: | |
| 944 | return command_pos == 2 ? C_SENSE_DRIVE_STATUS : C_INCOMPLETE; | |
| 1179 | 945 | |
| 1180 | upd765_setup_st0(device); | |
| 946 | case 0x05: | |
| 947 | case 0x09: | |
| 948 | return command_pos == 9 ? C_WRITE_DATA : C_INCOMPLETE; | |
| 1181 | 949 | |
| 1182 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 1183 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 1184 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 1185 | fdc->upd765_result_bytes[3] = fdc->upd765_command_bytes[2]; /* C */ | |
| 1186 | fdc->upd765_result_bytes[4] = fdc->upd765_command_bytes[3]; /* H */ | |
| 1187 | fdc->upd765_result_bytes[5] = fdc->upd765_command_bytes[4]; /* R */ | |
| 1188 | fdc->upd765_result_bytes[6] = fdc->upd765_command_bytes[5]; /* N */ | |
| 950 | case 0x06: | |
| 951 | case 0x0c: | |
| 952 | return command_pos == 9 ? C_READ_DATA : C_INCOMPLETE; | |
| 1189 | 953 | |
| 1190 | upd765_setup_result_phase(device,7); | |
| 1191 | } | |
| 954 | case 0x07: | |
| 955 | return command_pos == 2 ? C_RECALIBRATE : C_INCOMPLETE; | |
| 1192 | 956 | |
| 957 | case 0x08: | |
| 958 | return C_SENSE_INTERRUPT_STATUS; | |
| 1193 | 959 | |
| 1194 | static void upd765_write_data(device_t *device) | |
| 1195 | { | |
| 1196 | upd765_t *fdc = get_safe_token(device); | |
| 1197 | if (!upd765_get_rdy(device)) | |
| 1198 | { | |
| 1199 | fdc->upd765_status[0] = 0x0c0 | (1<<4) | fdc->drive | (fdc->side<<2); | |
| 1200 | fdc->upd765_status[1] = 0x00; | |
| 1201 | fdc->upd765_status[2] = 0x00; | |
| 960 | case 0x0a: | |
| 961 | return command_pos == 2 ? C_READ_ID : C_INCOMPLETE; | |
| 1202 | 962 | |
| 1203 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 1204 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 1205 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 1206 | fdc->upd765_result_bytes[3] = fdc->upd765_command_bytes[2]; /* C */ | |
| 1207 | fdc->upd765_result_bytes[4] = fdc->upd765_command_bytes[3]; /* H */ | |
| 1208 | fdc->upd765_result_bytes[5] = fdc->upd765_command_bytes[4]; /* R */ | |
| 1209 | fdc->upd765_result_bytes[6] = fdc->upd765_command_bytes[5]; /* N */ | |
| 1210 | upd765_setup_result_phase(device,7); | |
| 1211 | return; | |
| 1212 | } | |
| 963 | case 0x0d: | |
| 964 | return command_pos == 6 ? C_FORMAT_TRACK : C_INCOMPLETE; | |
| 1213 | 965 | |
| 1214 | /* write protected? */ | |
| 1215 | if (floppy_wpt_r(current_image(device)) == CLEAR_LINE) | |
| 1216 | { | |
| 1217 | fdc->upd765_status[1] |= UPD765_ST1_NOT_WRITEABLE; | |
| 966 | case 0x0f: | |
| 967 | return command_pos == 3 ? C_SEEK : C_INCOMPLETE; | |
| 1218 | 968 | |
| 1219 | upd765_write_complete(device); | |
| 1220 | return; | |
| 1221 | } | |
| 969 | case 0x12: | |
| 970 | return command_pos == 2 ? C_PERPENDICULAR : C_INCOMPLETE; | |
| 1222 | 971 | |
| 1223 | if (upd765_get_matching_sector(device)) | |
| 1224 | { | |
| 1225 | int data_size; | |
| 972 | case 0x13: | |
| 973 | return command_pos == 4 ? C_CONFIGURE : C_INCOMPLETE; | |
| 1226 | 974 | |
| 1227 | data_size = upd765_n_to_bytes(fdc->upd765_command_bytes[5]); | |
| 1228 | ||
| 1229 | upd765_setup_execution_phase_write(device,fdc->data_buffer, data_size); | |
| 975 | default: | |
| 976 | return C_INVALID; | |
| 1230 | 977 | } |
| 1231 | else | |
| 1232 | { | |
| 1233 | upd765_setup_result_phase(device,7); | |
| 1234 | } | |
| 1235 | 978 | } |
| 1236 | 979 | |
| 1237 | ||
| 1238 | /* return true if we have read all sectors, false if not */ | |
| 1239 | static int upd765_sector_count_complete(device_t *device) | |
| 980 | void upd765_family_device::start_command(int cmd) | |
| 1240 | 981 | { |
| 1241 | upd765_t *fdc = get_safe_token(device); | |
| 1242 | /* this is not correct?? */ | |
| 1243 | #if 1 | |
| 1244 | /* if terminal count has been set - yes */ | |
| 1245 | if (fdc->upd765_flags & UPD765_TC) | |
| 1246 | { | |
| 1247 | /* completed */ | |
| 1248 | return 1; | |
| 1249 | } | |
| 982 | command_pos = 0; | |
| 983 | result_pos = 0; | |
| 984 | main_phase = PHASE_EXEC; | |
| 985 | tc_done = false; | |
| 986 | switch(cmd) { | |
| 987 | case C_CONFIGURE: | |
| 988 | logerror("%s: command configure %02x %02x %02x\n", | |
| 989 | tag(), | |
| 990 | command[1], command[2], command[3]); | |
| 991 | // byte 1 is ignored, byte 3 is precompensation-related | |
| 992 | fifocfg = command[2]; | |
| 993 | main_phase = PHASE_CMD; | |
| 994 | break; | |
| 1250 | 995 | |
| 996 | case C_FORMAT_TRACK: | |
| 997 | format_track_start(flopi[command[1] & 3]); | |
| 998 | break; | |
| 1251 | 999 | |
| 1000 | case C_PERPENDICULAR: | |
| 1001 | logerror("%s: command perpendicular\n", tag()); | |
| 1002 | main_phase = PHASE_CMD; | |
| 1003 | break; | |
| 1252 | 1004 | |
| 1253 | /* multi-track? */ | |
| 1254 | if (fdc->upd765_command_bytes[0] & UPD765_MT) | |
| 1255 | { | |
| 1256 | /* it appears that in multi-track mode, | |
| 1257 | the EOT parameter of the command is ignored!? - | |
| 1258 | or is it ignored the first time and not the next, so that | |
| 1259 | if it is started on side 0, it will end at EOT on side 1, | |
| 1260 | but if started on side 1 it will end at end of track???? | |
| 1005 | case C_READ_DATA: | |
| 1006 | read_data_start(flopi[command[1] & 3]); | |
| 1007 | break; | |
| 1261 | 1008 | |
| 1262 | PC driver requires this to end at last sector on side 1, and | |
| 1263 | ignore EOT parameter. | |
| 1009 | case C_READ_ID: | |
| 1010 | read_id_start(flopi[command[1] & 3]); | |
| 1011 | break; | |
| 1264 | 1012 | |
| 1265 | To be checked!!!! | |
| 1266 | */ | |
| 1013 | case C_READ_TRACK: | |
| 1014 | read_track_start(flopi[command[1] & 3]); | |
| 1015 | break; | |
| 1267 | 1016 | |
| 1268 | /* if just read last sector and on side 1 - finish */ | |
| 1269 | if (upd765_just_read_last_sector_on_track(device)) | |
| 1270 | { | |
| 1271 | if (floppy_get_heads_per_disk(flopimg_get_image(current_image(device)))==1) { | |
| 1272 | return 2; | |
| 1273 | } else { | |
| 1274 | if (fdc->side==1) | |
| 1275 | return 2; | |
| 1276 | return 1; // do not advance to next cylinder | |
| 1277 | } | |
| 1278 | } | |
| 1017 | case C_RECALIBRATE: | |
| 1018 | recalibrate_start(flopi[command[1] & 3]); | |
| 1019 | main_phase = PHASE_CMD; | |
| 1020 | break; | |
| 1279 | 1021 | |
| 1280 | /* if not on second side then we haven't finished yet */ | |
| 1281 | if (fdc->side!=1) | |
| 1282 | { | |
| 1283 | /* haven't finished yet */ | |
| 1284 | return 0; | |
| 1285 | } | |
| 1286 | } | |
| 1287 | else | |
| 1288 | { | |
| 1289 | /* sector id == EOT? */ | |
| 1290 | if (fdc->upd765_command_bytes[4]==fdc->upd765_command_bytes[6]) | |
| 1291 | { | |
| 1022 | case C_SEEK: | |
| 1023 | seek_start(flopi[command[1] & 3]); | |
| 1024 | main_phase = PHASE_CMD; | |
| 1025 | break; | |
| 1292 | 1026 | |
| 1293 | /* completed */ | |
| 1294 | return 2; | |
| 1295 | } | |
| 1027 | case C_SENSE_DRIVE_STATUS: { | |
| 1028 | floppy_info &fi = flopi[command[1] & 3]; | |
| 1029 | main_phase = PHASE_RESULT; | |
| 1030 | result[0] = 0x08; | |
| 1031 | if(get_ready(fi.id)) | |
| 1032 | result[0] |= 0x20; | |
| 1033 | if(fi.dev) | |
| 1034 | result[0] |= | |
| 1035 | (fi.dev->wpt_r() ? 0x40 : 0x00) | | |
| 1036 | (fi.dev->trk00_r() ? 0x00 : 0x10) | | |
| 1037 | (fi.dev->ss_r() ? 0x04 : 0x00) | | |
| 1038 | (command[1] & 3); | |
| 1039 | logerror("%s: command sense drive status (%02x)\n", tag(), result[0]); | |
| 1040 | result_pos = 1; | |
| 1041 | break; | |
| 1296 | 1042 | } |
| 1297 | #else | |
| 1298 | 1043 | |
| 1299 | /* if terminal count has been set - yes */ | |
| 1300 | if (fdc->upd765_flags & UPD765_TC) | |
| 1301 | { | |
| 1302 | /* completed */ | |
| 1303 | return 1; | |
| 1304 | } | |
| 1044 | case C_SENSE_INTERRUPT_STATUS: { | |
| 1045 | main_phase = PHASE_RESULT; | |
| 1305 | 1046 | |
| 1306 | /* Multi-Track operation: | |
| 1047 | int fid; | |
| 1048 | for(fid=0; fid<4 && !flopi[fid].irq_seek; fid++); | |
| 1049 | if(fid == 4) | |
| 1050 | for(fid=0; fid<4 && !flopi[fid].irq_polled; fid++); | |
| 1051 | if(fid == 4) { | |
| 1052 | st0 = ST0_UNK; | |
| 1053 | result[0] = st0; | |
| 1054 | result[1] = 0x00; | |
| 1055 | result_pos = 2; | |
| 1056 | logerror("%s: command sense interrupt status (%02x %02x)\n", tag(), result[0], result[1]); | |
| 1057 | break; | |
| 1058 | } | |
| 1059 | floppy_info &fi = flopi[fid]; | |
| 1060 | if(fi.irq_seek) | |
| 1061 | fi.irq_seek = false; | |
| 1307 | 1062 | |
| 1308 | Verified on Amstrad CPC. | |
| 1063 | else if(fi.irq_polled) { | |
| 1064 | // Documentation is somewhat contradictory w.r.t polling | |
| 1065 | // and irq. PC bios, especially 5150, requires that only | |
| 1066 | // one irq happens. That's also wait the ns82077a doc | |
| 1067 | // says it does. OTOH, a number of docs says you need to | |
| 1068 | // call SIS 4 times, once per drive... | |
| 1069 | // | |
| 1070 | // Let's take the option that allows PC to boot. | |
| 1309 | 1071 | |
| 1310 | disc format used: | |
| 1311 | 9 sectors per track | |
| 1312 | 2 sides | |
| 1313 | Sector IDs: &01, &02, &03, &04, &05, &06, &07, &08, &09 | |
| 1072 | for(int i=0; i<4; i++) | |
| 1073 | flopi[i].irq_polled = false; | |
| 1314 | 1074 | |
| 1315 | Command specified: | |
| 1316 | SIDE = 0, | |
| 1317 | C = 0,H = 0,R = 1, N = 2, EOT = 1 | |
| 1318 | Sectors read: | |
| 1319 | Sector 1 side 0 | |
| 1320 | Sector 1 side 1 | |
| 1075 | st0 = ST0_ABRT | fid; | |
| 1076 | } else { | |
| 1077 | abort(); | |
| 1078 | } | |
| 1079 | result[0] = st0; | |
| 1080 | result[1] = fi.pcn; | |
| 1081 | logerror("%s: command sense interrupt status (fid=%d %02x %02x)\n", tag(), fid, result[0], result[1]); | |
| 1082 | result_pos = 2; | |
| 1321 | 1083 | |
| 1322 | Command specified: | |
| 1323 | SIDE = 0, | |
| 1324 | C = 0,H = 0,R = 1, N = 2, EOT = 3 | |
| 1325 | Sectors read: | |
| 1326 | Sector 1 side 0 | |
| 1327 | Sector 2 side 0 | |
| 1328 | Sector 3 side 0 | |
| 1329 | Sector 1 side 1 | |
| 1330 | Sector 2 side 1 | |
| 1331 | Sector 3 side 1 | |
| 1084 | check_irq(); | |
| 1085 | break; | |
| 1086 | } | |
| 1332 | 1087 | |
| 1088 | case C_SPECIFY: | |
| 1089 | logerror("%s: command specify %02x %02x\n", | |
| 1090 | tag(), | |
| 1091 | command[1], command[2]); | |
| 1092 | spec = (command[1] << 8) | command[2]; | |
| 1093 | main_phase = PHASE_CMD; | |
| 1094 | break; | |
| 1333 | 1095 | |
| 1334 | Command specified: | |
| 1335 | SIDE = 0, | |
| 1336 | C = 0, H = 0, R = 7, N = 2, EOT = 3 | |
| 1337 | Sectors read: | |
| 1338 | Sector 7 side 0 | |
| 1339 | Sector 8 side 0 | |
| 1340 | Sector 9 side 0 | |
| 1341 | Sector 10 not found. Error "No Data" | |
| 1096 | case C_WRITE_DATA: | |
| 1097 | write_data_start(flopi[command[1] & 3]); | |
| 1098 | break; | |
| 1342 | 1099 | |
| 1343 | Command specified: | |
| 1344 | SIDE = 1, | |
| 1345 | C = 0, H = 1, R = 1, N = 2, EOT = 1 | |
| 1346 | Sectors read: | |
| 1347 | Sector 1 side 1 | |
| 1348 | ||
| 1349 | Command specified: | |
| 1350 | SIDE = 1, | |
| 1351 | C = 0, H = 1, R = 1, N = 2, EOT = 2 | |
| 1352 | Sectors read: | |
| 1353 | Sector 1 side 1 | |
| 1354 | Sector 1 side 2 | |
| 1355 | ||
| 1356 | */ | |
| 1357 | ||
| 1358 | /* sector id == EOT? */ | |
| 1359 | if ((fdc->upd765_command_bytes[4]==fdc->upd765_command_bytes[6])) | |
| 1360 | { | |
| 1361 | /* multi-track? */ | |
| 1362 | if (fdc->upd765_command_bytes[0] & 0x080) | |
| 1363 | { | |
| 1364 | /* if we have reached EOT (fdc->upd765_command_bytes[6]) | |
| 1365 | on side 1, then read is complete */ | |
| 1366 | if (fdc->side==1) | |
| 1367 | return 1; | |
| 1368 | ||
| 1369 | return 0; | |
| 1370 | ||
| 1371 | } | |
| 1372 | ||
| 1373 | /* completed */ | |
| 1374 | return 1; | |
| 1100 | default: | |
| 1101 | fprintf(stderr, "start command %d\n", cmd); | |
| 1102 | exit(1); | |
| 1375 | 1103 | } |
| 1376 | #endif | |
| 1377 | /* not complete */ | |
| 1378 | return 0; | |
| 1379 | 1104 | } |
| 1380 | 1105 | |
| 1381 | ||
| 1106 | void upd765_family_device::command_end(floppy_info &fi, bool data_completion) | |
| 1382 | 1107 | { |
| 1383 | upd765_t *fdc = get_safe_token(device); | |
| 1384 | ||
| 1385 | /* multi-track? */ | |
| 1386 | if (fdc->upd765_command_bytes[0] & UPD765_MT) | |
| 1387 | { | |
| 1388 | /* reached EOT? */ | |
| 1389 | if (fdc->upd765_command_bytes[4] == fdc->upd765_command_bytes[6]) | |
| 1390 | { | |
| 1391 | if (fdc->side == 1) | |
| 1392 | { | |
| 1393 | fdc->upd765_command_bytes[2]++; | |
| 1394 | } | |
| 1395 | ||
| 1396 | fdc->upd765_command_bytes[3] ^= 0x01; | |
| 1397 | fdc->upd765_command_bytes[4] = 1; | |
| 1398 | fdc->side = fdc->upd765_command_bytes[3] & 0x01; | |
| 1399 | } | |
| 1400 | else | |
| 1401 | { | |
| 1402 | fdc->upd765_command_bytes[4]++; | |
| 1403 | } | |
| 1404 | } | |
| 1108 | logerror("%s: command done (%s) -", tag(), data_completion ? "data" : "seek"); | |
| 1109 | for(int i=0; i != result_pos; i++) | |
| 1110 | logerror(" %02x", result[i]); | |
| 1111 | logerror("\n"); | |
| 1112 | fi.main_state = fi.sub_state = IDLE; | |
| 1113 | if(data_completion) | |
| 1114 | data_irq = true; | |
| 1405 | 1115 | else |
| 1406 | { | |
| 1407 | if (fdc->upd765_command_bytes[4] == fdc->upd765_command_bytes[6]) | |
| 1408 | { | |
| 1409 | fdc->upd765_command_bytes[2]++; | |
| 1410 | fdc->upd765_command_bytes[4] = 1; | |
| 1411 | } | |
| 1412 | else | |
| 1413 | { | |
| 1414 | fdc->upd765_command_bytes[4]++; | |
| 1415 | } | |
| 1416 | } | |
| 1116 | fi.irq_seek = true; | |
| 1117 | check_irq(); | |
| 1417 | 1118 | } |
| 1418 | 1119 | |
| 1419 | /* control mark handling code */ | |
| 1420 | ||
| 1421 | /* if SK==0, and we are executing a read data command, and a deleted data sector is found, | |
| 1422 | the data is not skipped. The data is read, but the control mark is set and the read is stopped */ | |
| 1423 | /* if SK==0, and we are executing a read deleted data command, and a data sector is found, | |
| 1424 | the data is not skipped. The data is read, but the control mark is set and the read is stopped */ | |
| 1425 | static int upd765_read_data_stop(device_t *device) | |
| 1120 | void upd765_family_device::recalibrate_start(floppy_info &fi) | |
| 1426 | 1121 | { |
| 1427 | upd765_t *fdc = get_safe_token(device); | |
| 1428 | /* skip not set? */ | |
| 1429 | if ((fdc->upd765_command_bytes[0] & (1<<5))==0) | |
| 1430 | { | |
| 1431 | /* read data? */ | |
| 1432 | if (fdc->command == 0x06) | |
| 1433 | { | |
| 1434 | /* did we just read a sector with deleted data? */ | |
| 1435 | if (fdc->data_type == UPD765_DAM_DELETED_DATA) | |
| 1436 | { | |
| 1437 | /* set control mark */ | |
| 1438 | fdc->upd765_status[2] |= UPD765_ST2_CONTROL_MARK; | |
| 1122 | logerror("%s: command recalibrate\n", tag()); | |
| 1123 | fi.main_state = RECALIBRATE; | |
| 1124 | fi.sub_state = SEEK_WAIT_STEP_TIME_DONE; | |
| 1125 | fi.dir = 1; | |
| 1126 | fi.counter = 77; | |
| 1127 | seek_continue(fi); | |
| 1128 | } | |
| 1439 | 1129 | |
| 1440 | /* quit */ | |
| 1441 | return TRUE; | |
| 1442 | } | |
| 1443 | } | |
| 1444 | /* deleted data? */ | |
| 1445 | else | |
| 1446 | if (fdc->command == 0x0c) | |
| 1447 | { | |
| 1448 | /* did we just read a sector with data? */ | |
| 1449 | if (fdc->data_type == UPD765_DAM_DATA) | |
| 1450 | { | |
| 1451 | /* set control mark */ | |
| 1452 | fdc->upd765_status[2] |= UPD765_ST2_CONTROL_MARK; | |
| 1453 | ||
| 1454 | /* quit */ | |
| 1455 | return TRUE; | |
| 1456 | } | |
| 1457 | } | |
| 1458 | } | |
| 1459 | ||
| 1460 | /* continue */ | |
| 1461 | return FALSE; | |
| 1130 | void upd765_family_device::seek_start(floppy_info &fi) | |
| 1131 | { | |
| 1132 | logerror("%s: command %sseek %d\n", tag(), command[0] & 0x80 ? "relative " : "", command[2]); | |
| 1133 | fi.main_state = SEEK; | |
| 1134 | fi.sub_state = SEEK_WAIT_STEP_TIME_DONE; | |
| 1135 | fi.dir = fi.pcn > command[2] ? 1 : 0; | |
| 1136 | seek_continue(fi); | |
| 1462 | 1137 | } |
| 1463 | 1138 | |
| 1464 | ||
| 1139 | void upd765_family_device::delay_cycles(emu_timer *tm, int cycles) | |
| 1465 | 1140 | { |
| 1466 | device_t *device = (device_t *)ptr; | |
| 1467 | upd765_t *fdc = get_safe_token(device); | |
| 1468 | if ((fdc->upd765_phase == UPD765_EXECUTION_PHASE_READ) || | |
| 1469 | (fdc->upd765_phase == UPD765_EXECUTION_PHASE_WRITE)) | |
| 1470 | { | |
| 1471 | switch (fdc->command) | |
| 1472 | { | |
| 1473 | /* read a track */ | |
| 1474 | case 0x02: | |
| 1475 | { | |
| 1476 | fdc->sector_counter++; | |
| 1141 | tm->adjust(attotime::from_double(double(cycles)/cur_rate)); | |
| 1142 | } | |
| 1477 | 1143 | |
| 1478 | /* sector counter == EOT */ | |
| 1479 | if (fdc->sector_counter==fdc->upd765_command_bytes[6]) | |
| 1480 | { | |
| 1481 | /* TODO: Add correct info here */ | |
| 1482 | ||
| 1483 | fdc->upd765_status[1] |= UPD765_ST1_END_OF_CYLINDER; | |
| 1484 | ||
| 1485 | upd765_setup_st0(device); | |
| 1486 | ||
| 1487 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 1488 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 1489 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 1490 | fdc->upd765_result_bytes[3] = fdc->upd765_command_bytes[2]; /* C */ | |
| 1491 | fdc->upd765_result_bytes[4] = fdc->upd765_command_bytes[3]; /* H */ | |
| 1492 | fdc->upd765_result_bytes[5] = fdc->upd765_command_bytes[4]; /* R */ | |
| 1493 | fdc->upd765_result_bytes[6] = fdc->upd765_command_bytes[5]; /* N */ | |
| 1494 | ||
| 1495 | upd765_setup_result_phase(device,7); | |
| 1496 | } | |
| 1497 | else | |
| 1498 | { | |
| 1499 | upd765_read_a_track(device); | |
| 1500 | } | |
| 1144 | void upd765_family_device::seek_continue(floppy_info &fi) | |
| 1145 | { | |
| 1146 | for(;;) { | |
| 1147 | switch(fi.sub_state) { | |
| 1148 | case SEEK_MOVE: | |
| 1149 | if(fi.dev) { | |
| 1150 | fi.dev->dir_w(fi.dir); | |
| 1151 | fi.dev->stp_w(0); | |
| 1501 | 1152 | } |
| 1502 | break; | |
| 1153 | fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME; | |
| 1154 | fi.tm->adjust(attotime::from_nsec(2500)); | |
| 1155 | return; | |
| 1503 | 1156 | |
| 1504 | /* format track */ | |
| 1505 | case 0x0d: | |
| 1506 | { | |
| 1507 | floppy_drive_format_sector(current_image(device), fdc->side, fdc->sector_counter, | |
| 1508 | fdc->format_data[0], fdc->format_data[1], | |
| 1509 | fdc->format_data[2], fdc->format_data[3], | |
| 1510 | fdc->upd765_command_bytes[5]); | |
| 1157 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 1158 | return; | |
| 1511 | 1159 | |
| 1512 | fdc->sector_counter++; | |
| 1160 | case SEEK_WAIT_STEP_SIGNAL_TIME_DONE: | |
| 1161 | if(fi.dev) | |
| 1162 | fi.dev->stp_w(1); | |
| 1513 | 1163 | |
| 1514 | /* sector_counter = SC */ | |
| 1515 | if (fdc->sector_counter == fdc->upd765_command_bytes[3]) | |
| 1516 | { | |
| 1517 | /* TODO: Check result is correct */ | |
| 1518 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 1519 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 1520 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 1521 | fdc->upd765_result_bytes[3] = fdc->format_data[0]; | |
| 1522 | fdc->upd765_result_bytes[4] = fdc->format_data[1]; | |
| 1523 | fdc->upd765_result_bytes[5] = fdc->format_data[2]; | |
| 1524 | fdc->upd765_result_bytes[6] = fdc->format_data[3]; | |
| 1525 | upd765_setup_result_phase(device,7); | |
| 1526 | } | |
| 1164 | if(fi.main_state == SEEK) { | |
| 1165 | if(fi.pcn > command[2]) | |
| 1166 | fi.pcn--; | |
| 1527 | 1167 | else |
| 1528 | { | |
| 1529 | upd765_format_track(device); | |
| 1530 | } | |
| 1168 | fi.pcn++; | |
| 1531 | 1169 | } |
| 1532 | break; | |
| 1170 | fi.sub_state = SEEK_WAIT_STEP_TIME; | |
| 1171 | delay_cycles(fi.tm, 500*(16-(spec >> 12))); | |
| 1172 | return; | |
| 1533 | 1173 | |
| 1534 | /* write data, write deleted data */ | |
| 1535 | case 0x09: | |
| 1536 | case 0x05: | |
| 1537 | { | |
| 1538 | /* sector id == EOT */ | |
| 1539 | UINT8 ddam; | |
| 1174 | case SEEK_WAIT_STEP_TIME: | |
| 1175 | return; | |
| 1540 | 1176 | |
| 1541 | ddam = 0; | |
| 1542 | if (fdc->command == 0x09) | |
| 1543 | { | |
| 1544 | ddam = 1; | |
| 1177 | case SEEK_WAIT_STEP_TIME_DONE: { | |
| 1178 | bool done = false; | |
| 1179 | switch(fi.main_state) { | |
| 1180 | case RECALIBRATE: | |
| 1181 | fi.counter--; | |
| 1182 | done = !fi.dev || !fi.dev->trk00_r(); | |
| 1183 | if(done) | |
| 1184 | fi.pcn = 0; | |
| 1185 | else if(!fi.counter) { | |
| 1186 | st0 = ST0_FAIL|ST0_SE|ST0_EC; | |
| 1187 | command_end(fi, false); | |
| 1188 | return; | |
| 1545 | 1189 | } |
| 1546 | ||
| 1547 | /* write data to disc */ | |
| 1548 | // logerror("floppy_drive_write_sector_data side=%d sector=%d tc=%x\n", fdc->side, fdc->sector_id, fdc->upd765_flags & UPD765_TC); | |
| 1549 | floppy_drive_write_sector_data(current_image(device), fdc->side, fdc->sector_id,fdc->data_buffer,upd765_n_to_bytes(fdc->upd765_command_bytes[5]),ddam); | |
| 1550 | ||
| 1551 | /* nothing to write */ | |
| 1552 | if ((fdc->upd765_transfer_bytes_remaining==0) && (fdc->upd765_flags & UPD765_DMA_MODE)) | |
| 1553 | { | |
| 1554 | if (fdc->upd765_flags & UPD765_TC) | |
| 1555 | { | |
| 1556 | upd765_write_complete(device); | |
| 1557 | break; | |
| 1558 | } | |
| 1559 | } | |
| 1560 | ||
| 1561 | if (upd765_sector_count_complete(device)) | |
| 1562 | { | |
| 1563 | upd765_increment_sector(device); | |
| 1564 | upd765_write_complete(device); | |
| 1565 | } | |
| 1566 | else | |
| 1567 | { | |
| 1568 | upd765_increment_sector(device); | |
| 1569 | upd765_write_data(device); | |
| 1570 | } | |
| 1190 | break; | |
| 1191 | case SEEK: | |
| 1192 | done = fi.pcn == command[2]; | |
| 1193 | break; | |
| 1571 | 1194 | } |
| 1572 | break; | |
| 1573 | ||
| 1574 | /* read data, read deleted data */ | |
| 1575 | case 0x0c: | |
| 1576 | case 0x06: | |
| 1577 | { | |
| 1578 | ||
| 1579 | int cause; | |
| 1580 | /* read all sectors? */ | |
| 1581 | ||
| 1582 | /* sector id == EOT */ | |
| 1583 | if ((cause = upd765_sector_count_complete(device)) || upd765_read_data_stop(device)) | |
| 1584 | { | |
| 1585 | if (cause == 2) | |
| 1586 | upd765_increment_sector(device); // advance to next cylinder if EOT | |
| 1587 | ||
| 1588 | upd765_read_complete(device); | |
| 1589 | } | |
| 1590 | else | |
| 1591 | { | |
| 1592 | upd765_increment_sector(device); | |
| 1593 | upd765_read_data(device); | |
| 1594 | } | |
| 1195 | if(done) { | |
| 1196 | st0 = ST0_SE; | |
| 1197 | command_end(fi, false); | |
| 1198 | return; | |
| 1595 | 1199 | } |
| 1200 | fi.sub_state = SEEK_MOVE; | |
| 1596 | 1201 | break; |
| 1597 | ||
| 1598 | default: | |
| 1599 | break; | |
| 1600 | 1202 | } |
| 1203 | } | |
| 1601 | 1204 | } |
| 1602 | 1205 | } |
| 1603 | 1206 | |
| 1604 | ||
| 1605 | static int upd765_get_command_byte_count(device_t *device) | |
| 1207 | void upd765_family_device::read_data_start(floppy_info &fi) | |
| 1606 | 1208 | { |
| 1607 | upd765_t *fdc = get_safe_token(device); | |
| 1608 | fdc->command = fdc->upd765_command_bytes[0] & 0x01f; | |
| 1209 | fi.main_state = READ_DATA; | |
| 1210 | fi.sub_state = HEAD_LOAD_DONE; | |
| 1211 | logerror("%s: command read%s data%s%s%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", | |
| 1212 | tag(), | |
| 1213 | command[0] & 0x08 ? " deleted" : "", | |
| 1214 | command[0] & 0x80 ? " mt" : "", | |
| 1215 | command[0] & 0x40 ? " mfm" : "", | |
| 1216 | command[0] & 0x20 ? " sk" : "", | |
| 1217 | fifocfg & 0x40 ? " seek" : "", | |
| 1218 | command[0], | |
| 1219 | command[1], | |
| 1220 | command[2], | |
| 1221 | command[3], | |
| 1222 | command[4], | |
| 1223 | 128 << (command[5] & 7), | |
| 1224 | command[6], | |
| 1225 | command[7], | |
| 1226 | command[8], | |
| 1227 | cur_rate); | |
| 1609 | 1228 | |
| 1610 | if (fdc->version==TYPE_UPD765A) | |
| 1611 | { | |
| 1612 | return upd765_cmd_size[fdc->command]; | |
| 1613 | } | |
| 1614 | else | |
| 1615 | { | |
| 1616 | if (fdc->version==TYPE_UPD72065) | |
| 1617 | { | |
| 1618 | switch(fdc->upd765_command_bytes[0]) | |
| 1619 | { | |
| 1620 | case 0x34: // Reset Standby | |
| 1621 | case 0x35: // Set Standby | |
| 1622 | case 0x36: // Software Reset | |
| 1623 | return 1; | |
| 1624 | default: | |
| 1625 | return upd765_cmd_size[fdc->command]; | |
| 1626 | } | |
| 1627 | } | |
| 1628 | if (fdc->version==TYPE_SMC37C78) | |
| 1629 | { | |
| 1630 | switch (fdc->command) | |
| 1631 | { | |
| 1632 | /* version */ | |
| 1633 | case 0x010: | |
| 1634 | return 1; | |
| 1229 | st0 = command[1] & 7; | |
| 1230 | st1 = ST1_MA; | |
| 1231 | st2 = 0x00; | |
| 1635 | 1232 | |
| 1636 | /* verify */ | |
| 1637 | case 0x016: | |
| 1638 | return 9; | |
| 1639 | ||
| 1640 | /* configure */ | |
| 1641 | case 0x013: | |
| 1642 | return 4; | |
| 1643 | ||
| 1644 | /* dumpreg */ | |
| 1645 | case 0x0e: | |
| 1646 | return 1; | |
| 1647 | ||
| 1648 | /* perpendicular mode */ | |
| 1649 | case 0x012: | |
| 1650 | return 1; | |
| 1651 | ||
| 1652 | /* lock */ | |
| 1653 | case 0x014: | |
| 1654 | return 1; | |
| 1655 | ||
| 1656 | /* seek/relative seek are together! */ | |
| 1657 | ||
| 1658 | default: | |
| 1659 | return upd765_cmd_size[fdc->command]; | |
| 1660 | } | |
| 1661 | } | |
| 1662 | } | |
| 1663 | ||
| 1664 | return upd765_cmd_size[fdc->command]; | |
| 1233 | if(fi.dev) | |
| 1234 | fi.dev->ss_w(command[1] & 4 ? 1 : 0); | |
| 1235 | read_data_continue(fi); | |
| 1665 | 1236 | } |
| 1666 | 1237 | |
| 1667 | ||
| 1668 | ||
| 1669 | ||
| 1670 | ||
| 1671 | void upd765_update_state(device_t *device) | |
| 1238 | void upd765_family_device::read_data_continue(floppy_info &fi) | |
| 1672 | 1239 | { |
| 1673 | upd765_t *fdc = get_safe_token(device); | |
| 1674 | switch (fdc->upd765_phase) { | |
| 1675 | case UPD765_RESULT_PHASE: | |
| 1676 | /* set data reg */ | |
| 1677 | fdc->upd765_data_reg = fdc->upd765_result_bytes[fdc->upd765_transfer_bytes_count]; | |
| 1678 | ||
| 1679 | if (fdc->upd765_transfer_bytes_count == 0) | |
| 1680 | { | |
| 1681 | /* clear int for specific commands */ | |
| 1682 | switch (fdc->command) { | |
| 1683 | case 2: /* read a track */ | |
| 1684 | case 5: /* write data */ | |
| 1685 | case 6: /* read data */ | |
| 1686 | case 9: /* write deleted data */ | |
| 1687 | case 10: /* read id */ | |
| 1688 | case 12: /* read deleted data */ | |
| 1689 | case 13: /* format at track */ | |
| 1690 | case 17: /* scan equal */ | |
| 1691 | case 19: /* scan low or equal */ | |
| 1692 | case 29: /* scan high or equal */ | |
| 1693 | upd765_set_int(device, 0); | |
| 1240 | for(;;) { | |
| 1241 | switch(fi.sub_state) { | |
| 1242 | case HEAD_LOAD_DONE: | |
| 1243 | if(fi.pcn == command[2] || !(fifocfg & 0x40)) { | |
| 1244 | fi.sub_state = SEEK_DONE; | |
| 1694 | 1245 | break; |
| 1695 | ||
| 1696 | default: | |
| 1697 | break; | |
| 1698 | 1246 | } |
| 1699 | } | |
| 1247 | st0 |= ST0_SE; | |
| 1248 | if(fi.dev) { | |
| 1249 | fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0); | |
| 1250 | fi.dev->stp_w(0); | |
| 1251 | } | |
| 1252 | fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME; | |
| 1253 | fi.tm->adjust(attotime::from_nsec(2500)); | |
| 1254 | return; | |
| 1700 | 1255 | |
| 1701 | if (LOG_VERBOSE) | |
| 1702 | logerror("UPD765: RESULT: %02x\n", fdc->upd765_data_reg); | |
| 1256 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 1257 | return; | |
| 1703 | 1258 | |
| 1704 | fdc->upd765_transfer_bytes_count++; | |
| 1705 | fdc->upd765_transfer_bytes_remaining--; | |
| 1259 | case SEEK_WAIT_STEP_SIGNAL_TIME_DONE: | |
| 1260 | if(fi.dev) | |
| 1261 | fi.dev->stp_w(1); | |
| 1706 | 1262 | |
| 1707 | if (fdc->upd765_transfer_bytes_remaining==0) | |
| 1708 | { | |
| 1709 | upd765_idle(device); | |
| 1710 | } | |
| 1711 | else | |
| 1712 | { | |
| 1713 | upd765_set_data_request(device); | |
| 1714 | } | |
| 1715 | break; | |
| 1263 | fi.sub_state = SEEK_WAIT_STEP_TIME; | |
| 1264 | delay_cycles(fi.tm, 500*(16-(spec >> 12))); | |
| 1265 | return; | |
| 1716 | 1266 | |
| 1717 | case UPD765_EXECUTION_PHASE_READ: | |
| 1718 | /* setup data register */ | |
| 1719 | fdc->upd765_data_reg = fdc->execution_phase_data[fdc->upd765_transfer_bytes_count]; | |
| 1720 | fdc->upd765_transfer_bytes_count++; | |
| 1721 | fdc->upd765_transfer_bytes_remaining--; | |
| 1267 | case SEEK_WAIT_STEP_TIME: | |
| 1268 | return; | |
| 1722 | 1269 | |
| 1723 | if (LOG_EXTRA) | |
| 1724 | logerror("EXECUTION PHASE READ: %02x\n", fdc->upd765_data_reg); | |
| 1270 | case SEEK_WAIT_STEP_TIME_DONE: | |
| 1271 | if(fi.pcn > command[2]) | |
| 1272 | fi.pcn--; | |
| 1273 | else | |
| 1274 | fi.pcn++; | |
| 1275 | fi.sub_state = HEAD_LOAD_DONE; | |
| 1276 | break; | |
| 1725 | 1277 | |
| 1726 | if ((fdc->upd765_transfer_bytes_remaining==0) || (fdc->upd765_flags & UPD765_TC)) | |
| 1727 | { | |
| 1728 | fdc->command_timer->adjust(attotime::zero); | |
| 1729 | } | |
| 1730 | else | |
| 1731 | { | |
| 1732 | /* trigger int */ | |
| 1733 | upd765_setup_timed_data_request(device,1); | |
| 1734 | } | |
| 1735 | break; | |
| 1278 | case SEEK_DONE: | |
| 1279 | fi.counter = 0; | |
| 1280 | fi.sub_state = SCAN_ID; | |
| 1281 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1282 | return; | |
| 1736 | 1283 | |
| 1737 | case UPD765_COMMAND_PHASE_FIRST_BYTE: | |
| 1738 | fdc->FDC_main |= 0x10; /* set BUSY */ | |
| 1284 | case SCAN_ID: | |
| 1285 | if(cur_live.crc) { | |
| 1286 | st0 |= ST0_FAIL; | |
| 1287 | st1 |= ST1_DE|ST1_ND; | |
| 1288 | fi.sub_state = COMMAND_DONE; | |
| 1289 | break; | |
| 1290 | } | |
| 1291 | st1 &= ~ST1_MA; | |
| 1292 | if(!sector_matches()) { | |
| 1293 | if(cur_live.idbuf[0] != command[2]) { | |
| 1294 | if(cur_live.idbuf[0] == 0xff) | |
| 1295 | st2 |= ST2_WC|ST2_BC; | |
| 1296 | else | |
| 1297 | st2 |= ST2_WC; | |
| 1298 | st0 |= ST0_FAIL; | |
| 1299 | fi.sub_state = COMMAND_DONE; | |
| 1300 | break; | |
| 1301 | } | |
| 1302 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1303 | return; | |
| 1304 | } | |
| 1305 | logerror("%s: reading sector %02x %02x %02x %02x\n", | |
| 1306 | tag(), | |
| 1307 | cur_live.idbuf[0], | |
| 1308 | cur_live.idbuf[1], | |
| 1309 | cur_live.idbuf[2], | |
| 1310 | cur_live.idbuf[3]); | |
| 1311 | sector_size = calc_sector_size(cur_live.idbuf[3]); | |
| 1312 | fifo_expect(sector_size, false); | |
| 1313 | fi.sub_state = SECTOR_READ; | |
| 1314 | live_start(fi, SEARCH_ADDRESS_MARK_DATA); | |
| 1315 | return; | |
| 1739 | 1316 | |
| 1740 | if (LOG_VERBOSE) | |
| 1741 | logerror("%s: upd765(): command=0x%02x\n", device->machine().describe_context(), fdc->upd765_data_reg); | |
| 1317 | case SCAN_ID_FAILED: | |
| 1318 | st0 |= ST0_FAIL; | |
| 1319 | st1 |= ST1_ND; | |
| 1320 | fi.sub_state = COMMAND_DONE; | |
| 1321 | break; | |
| 1742 | 1322 | |
| 1743 | /* seek in progress? */ | |
| 1744 | if (fdc->upd765_flags & UPD765_SEEK_ACTIVE) | |
| 1745 | { | |
| 1746 | /* any command results in a invalid - I think that seek, recalibrate and | |
| 1747 | sense interrupt status may work*/ | |
| 1748 | if (fdc->upd765_data_reg != 8) /* Sense Interrupt Status */ | |
| 1749 | fdc->upd765_data_reg = 0; | |
| 1323 | case SECTOR_READ: { | |
| 1324 | if(st2 & ST2_MD) { | |
| 1325 | st0 |= ST0_FAIL; | |
| 1326 | fi.sub_state = COMMAND_DONE; | |
| 1327 | break; | |
| 1328 | } | |
| 1329 | if(cur_live.crc) { | |
| 1330 | st0 |= ST0_FAIL; | |
| 1331 | st1 |= ST1_DE; | |
| 1332 | st2 |= ST2_CM; | |
| 1333 | fi.sub_state = COMMAND_DONE; | |
| 1334 | break; | |
| 1335 | } | |
| 1336 | bool done = tc_done; | |
| 1337 | command[4]++; | |
| 1338 | if(command[4] > command[6]) { | |
| 1339 | command[4] = 1; | |
| 1340 | if(command[0] & 0x80) { | |
| 1341 | command[3] = command[3] ^ 1; | |
| 1342 | if(fi.dev) | |
| 1343 | fi.dev->ss_w(command[3] & 1); | |
| 1344 | } | |
| 1345 | if(!(command[0] & 0x80) || !(command[3] & 1)) { | |
| 1346 | command[2]++; | |
| 1347 | if(!tc_done) { | |
| 1348 | st0 |= ST0_FAIL; | |
| 1349 | st1 |= ST1_EN; | |
| 1350 | } | |
| 1351 | done = true; | |
| 1352 | } | |
| 1353 | } | |
| 1354 | if(!done) { | |
| 1355 | fi.sub_state = SEEK_DONE; | |
| 1356 | break; | |
| 1357 | } | |
| 1358 | fi.sub_state = COMMAND_DONE; | |
| 1359 | break; | |
| 1750 | 1360 | } |
| 1751 | 1361 | |
| 1752 | fdc->upd765_command_bytes[0] = fdc->upd765_data_reg; | |
| 1362 | case COMMAND_DONE: | |
| 1363 | main_phase = PHASE_RESULT; | |
| 1364 | result[0] = st0; | |
| 1365 | result[1] = st1; | |
| 1366 | result[2] = st2; | |
| 1367 | result[3] = command[2]; | |
| 1368 | result[4] = command[3]; | |
| 1369 | result[5] = command[4]; | |
| 1370 | result[6] = command[5]; | |
| 1371 | result_pos = 7; | |
| 1372 | command_end(fi, true); | |
| 1373 | return; | |
| 1753 | 1374 | |
| 1754 | fdc->upd765_transfer_bytes_remaining = upd765_get_command_byte_count(device); | |
| 1755 | ||
| 1756 | fdc->upd765_transfer_bytes_count = 1; | |
| 1757 | fdc->upd765_transfer_bytes_remaining--; | |
| 1758 | ||
| 1759 | if (fdc->upd765_transfer_bytes_remaining==0) | |
| 1760 | { | |
| 1761 | upd765_setup_command(device); | |
| 1375 | default: | |
| 1376 | logerror("%s: read sector unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 1377 | return; | |
| 1762 | 1378 | } |
| 1763 | else | |
| 1764 | { | |
| 1765 | /* request more data */ | |
| 1766 | upd765_set_data_request(device); | |
| 1767 | fdc->upd765_phase = UPD765_COMMAND_PHASE_BYTES; | |
| 1768 | } | |
| 1769 | break; | |
| 1770 | ||
| 1771 | case UPD765_COMMAND_PHASE_BYTES: | |
| 1772 | if (LOG_VERBOSE) | |
| 1773 | logerror("%s: upd765(): command=0x%02x\n", device->machine().describe_context(), fdc->upd765_data_reg); | |
| 1774 | ||
| 1775 | fdc->upd765_command_bytes[fdc->upd765_transfer_bytes_count] = fdc->upd765_data_reg; | |
| 1776 | fdc->upd765_transfer_bytes_count++; | |
| 1777 | fdc->upd765_transfer_bytes_remaining--; | |
| 1778 | ||
| 1779 | if (fdc->upd765_transfer_bytes_remaining==0) | |
| 1780 | { | |
| 1781 | upd765_setup_command(device); | |
| 1782 | } | |
| 1783 | else | |
| 1784 | { | |
| 1785 | /* request more data */ | |
| 1786 | upd765_set_data_request(device); | |
| 1787 | } | |
| 1788 | break; | |
| 1789 | ||
| 1790 | case UPD765_EXECUTION_PHASE_WRITE: | |
| 1791 | fdc->execution_phase_data[fdc->upd765_transfer_bytes_count]=fdc->upd765_data_reg; | |
| 1792 | fdc->upd765_transfer_bytes_count++; | |
| 1793 | fdc->upd765_transfer_bytes_remaining--; | |
| 1794 | ||
| 1795 | if ((fdc->upd765_transfer_bytes_remaining == 0) || (fdc->upd765_flags & UPD765_TC)) | |
| 1796 | { | |
| 1797 | fdc->command_timer->adjust(attotime::zero); | |
| 1798 | } | |
| 1799 | else | |
| 1800 | { | |
| 1801 | upd765_setup_timed_data_request(device,1); | |
| 1802 | } | |
| 1803 | break; | |
| 1804 | 1379 | } |
| 1805 | 1380 | } |
| 1806 | 1381 | |
| 1807 | ||
| 1808 | READ8_DEVICE_HANDLER(upd765_data_r) | |
| 1382 | void upd765_family_device::write_data_start(floppy_info &fi) | |
| 1809 | 1383 | { |
| 1810 | upd765_t *fdc = get_safe_token(device); | |
| 1384 | fi.main_state = WRITE_DATA; | |
| 1385 | fi.sub_state = HEAD_LOAD_DONE; | |
| 1386 | logerror("%s: command write%s data%s%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", | |
| 1387 | tag(), | |
| 1388 | command[0] & 0x08 ? " deleted" : "", | |
| 1389 | command[0] & 0x80 ? " mt" : "", | |
| 1390 | command[0] & 0x40 ? " mfm" : "", | |
| 1391 | command[0], | |
| 1392 | command[1], | |
| 1393 | command[2], | |
| 1394 | command[3], | |
| 1395 | command[4], | |
| 1396 | 128 << (command[5] & 7), | |
| 1397 | command[6], | |
| 1398 | command[7], | |
| 1399 | command[8], | |
| 1400 | cur_rate); | |
| 1811 | 1401 | |
| 1812 | // if ((fdc->FDC_main & 0x0c0) == 0x0c0) | |
| 1813 | if ((fdc->FDC_main & 0x080) == 0x080) | |
| 1814 | { | |
| 1815 | if ( | |
| 1816 | (fdc->upd765_phase == UPD765_EXECUTION_PHASE_READ) || | |
| 1817 | (fdc->upd765_phase == UPD765_EXECUTION_PHASE_WRITE)) | |
| 1818 | { | |
| 1402 | if(fi.dev) | |
| 1403 | fi.dev->ss_w(command[1] & 4 ? 1 : 0); | |
| 1819 | 1404 | |
| 1820 | /* reading the data byte clears the interrupt */ | |
| 1821 | upd765_set_int(device,CLEAR_LINE); | |
| 1822 | } | |
| 1405 | st0 = command[1] & 7; | |
| 1406 | st1 = ST1_MA; | |
| 1407 | st2 = 0x00; | |
| 1823 | 1408 | |
| 1824 | /* reset data request */ | |
| 1825 | upd765_clear_data_request(device); | |
| 1826 | ||
| 1827 | /* update state */ | |
| 1828 | upd765_update_state(device); | |
| 1829 | } | |
| 1830 | ||
| 1831 | if (LOG_EXTRA) | |
| 1832 | logerror("DATA R: %02x\n", fdc->upd765_data_reg); | |
| 1833 | ||
| 1834 | return fdc->upd765_data_reg; | |
| 1409 | write_data_continue(fi); | |
| 1835 | 1410 | } |
| 1836 | 1411 | |
| 1837 | ||
| 1412 | void upd765_family_device::write_data_continue(floppy_info &fi) | |
| 1838 | 1413 | { |
| 1839 | upd765_t *fdc = get_safe_token(device); | |
| 1414 | for(;;) { | |
| 1415 | switch(fi.sub_state) { | |
| 1416 | case HEAD_LOAD_DONE: | |
| 1417 | fi.counter = 0; | |
| 1418 | fi.sub_state = SCAN_ID; | |
| 1419 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1420 | return; | |
| 1840 | 1421 | |
| 1841 | if (LOG_EXTRA) | |
| 1842 | logerror("DATA W: %02x\n", data); | |
| 1422 | case SCAN_ID: | |
| 1423 | if(!sector_matches()) { | |
| 1424 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1425 | return; | |
| 1426 | } | |
| 1427 | if(cur_live.crc) { | |
| 1428 | fprintf(stderr, "Header CRC error\n"); | |
| 1429 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1430 | return; | |
| 1431 | } | |
| 1432 | sector_size = calc_sector_size(cur_live.idbuf[3]); | |
| 1433 | fifo_expect(sector_size, true); | |
| 1434 | fi.sub_state = SECTOR_WRITTEN; | |
| 1435 | live_start(fi, WRITE_SECTOR_SKIP_GAP2); | |
| 1436 | return; | |
| 1843 | 1437 | |
| 1844 | /* write data to data reg */ | |
| 1845 | fdc->upd765_data_reg = data; | |
| 1438 | case SCAN_ID_FAILED: | |
| 1439 | st0 |= ST0_FAIL; | |
| 1440 | st1 |= ST1_ND; | |
| 1441 | fi.sub_state = COMMAND_DONE; | |
| 1442 | break; | |
| 1846 | 1443 | |
| 1847 | if ((fdc->FDC_main & 0x0c0)==0x080) | |
| 1848 | { | |
| 1849 | if ( | |
| 1850 | (fdc->upd765_phase == UPD765_EXECUTION_PHASE_READ) || | |
| 1851 | (fdc->upd765_phase == UPD765_EXECUTION_PHASE_WRITE)) | |
| 1852 | { | |
| 1853 | ||
| 1854 | /* reading the data byte clears the interrupt */ | |
| 1855 | upd765_set_int(device, CLEAR_LINE); | |
| 1444 | case SECTOR_WRITTEN: { | |
| 1445 | bool done = tc_done; | |
| 1446 | command[4]++; | |
| 1447 | if(command[4] > command[6]) { | |
| 1448 | command[4] = 1; | |
| 1449 | if(command[0] & 0x80) { | |
| 1450 | command[3] = command[3] ^ 1; | |
| 1451 | if(fi.dev) | |
| 1452 | fi.dev->ss_w(command[3] & 1); | |
| 1453 | } | |
| 1454 | if(!(command[0] & 0x80) || !(command[3] & 1)) { | |
| 1455 | command[2]++; | |
| 1456 | if(!tc_done) { | |
| 1457 | st0 |= ST0_FAIL; | |
| 1458 | st1 |= ST1_EN; | |
| 1459 | } | |
| 1460 | done = true; | |
| 1461 | } | |
| 1462 | } | |
| 1463 | if(!done) { | |
| 1464 | fi.sub_state = HEAD_LOAD_DONE; | |
| 1465 | break; | |
| 1466 | } | |
| 1467 | fi.sub_state = COMMAND_DONE; | |
| 1468 | break; | |
| 1856 | 1469 | } |
| 1857 | 1470 | |
| 1858 | /* reset data request */ | |
| 1859 | upd765_clear_data_request(device); | |
| 1471 | case COMMAND_DONE: | |
| 1472 | main_phase = PHASE_RESULT; | |
| 1473 | result[0] = st0; | |
| 1474 | result[1] = st1; | |
| 1475 | result[2] = st2; | |
| 1476 | result[3] = command[2]; | |
| 1477 | result[4] = command[3]; | |
| 1478 | result[5] = command[4]; | |
| 1479 | result[6] = command[5]; | |
| 1480 | result_pos = 7; | |
| 1481 | command_end(fi, true); | |
| 1482 | return; | |
| 1860 | 1483 | |
| 1861 | /* update state */ | |
| 1862 | upd765_update_state(device); | |
| 1484 | default: | |
| 1485 | logerror("%s: write sector unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 1486 | return; | |
| 1487 | } | |
| 1863 | 1488 | } |
| 1864 | 1489 | } |
| 1865 | 1490 | |
| 1866 | ||
| 1491 | void upd765_family_device::read_track_start(floppy_info &fi) | |
| 1867 | 1492 | { |
| 1868 | upd765_t *fdc = get_safe_token(device); | |
| 1493 | fi.main_state = READ_TRACK; | |
| 1494 | fi.sub_state = HEAD_LOAD_DONE; | |
| 1869 | 1495 | |
| 1870 | fdc->command = 0; | |
| 1871 | fdc->upd765_result_bytes[0] = 0x080; | |
| 1872 | upd765_setup_result_phase(device,1); | |
| 1496 | logerror("%s: command read track%s cmd=%02x sel=%x chrn=(%d, %d, %d, %d) eot=%02x gpl=%02x dtl=%02x rate=%d\n", | |
| 1497 | tag(), | |
| 1498 | command[0] & 0x40 ? " mfm" : "", | |
| 1499 | command[0], | |
| 1500 | command[1], | |
| 1501 | command[2], | |
| 1502 | command[3], | |
| 1503 | command[4], | |
| 1504 | 128 << (command[5] & 7), | |
| 1505 | command[6], | |
| 1506 | command[7], | |
| 1507 | command[8], | |
| 1508 | cur_rate); | |
| 1509 | ||
| 1510 | if(fi.dev) | |
| 1511 | fi.dev->ss_w(command[1] & 4 ? 1 : 0); | |
| 1512 | read_track_continue(fi); | |
| 1873 | 1513 | } |
| 1874 | 1514 | |
| 1875 | ||
| 1515 | void upd765_family_device::read_track_continue(floppy_info &fi) | |
| 1876 | 1516 | { |
| 1877 | upd765_t *fdc = get_safe_token(device); | |
| 1517 | for(;;) { | |
| 1518 | switch(fi.sub_state) { | |
| 1519 | case HEAD_LOAD_DONE: | |
| 1520 | if(fi.pcn == command[2] || !(fifocfg & 0x40)) { | |
| 1521 | fi.sub_state = SEEK_DONE; | |
| 1522 | break; | |
| 1523 | } | |
| 1524 | if(fi.dev) { | |
| 1525 | fi.dev->dir_w(fi.pcn > command[2] ? 1 : 0); | |
| 1526 | fi.dev->stp_w(0); | |
| 1527 | } | |
| 1528 | fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME; | |
| 1529 | fi.tm->adjust(attotime::from_nsec(2500)); | |
| 1530 | return; | |
| 1878 | 1531 | |
| 1879 | static const char *const commands[] = | |
| 1880 | { | |
| 1881 | NULL, /* [00] */ | |
| 1882 | NULL, /* [01] */ | |
| 1883 | "Read Track", /* [02] */ | |
| 1884 | "Specify", /* [03] */ | |
| 1885 | "Sense Drive Status", /* [04] */ | |
| 1886 | "Write Data", /* [05] */ | |
| 1887 | "Read Data", /* [06] */ | |
| 1888 | "Recalibrate", /* [07] */ | |
| 1889 | "Sense Interrupt Status", /* [08] */ | |
| 1890 | "Write Deleted Data", /* [09] */ | |
| 1891 | "Read ID", /* [0A] */ | |
| 1892 | NULL, /* [0B] */ | |
| 1893 | "Read Deleted Data", /* [0C] */ | |
| 1894 | "Format Track", /* [0D] */ | |
| 1895 | "Dump Registers", /* [0E] */ | |
| 1896 | "Seek", /* [0F] */ | |
| 1897 | "Version", /* [10] */ | |
| 1898 | NULL, /* [11] */ | |
| 1899 | "Perpendicular Mode", /* [12] */ | |
| 1900 | "Configure", /* [13] */ | |
| 1901 | "Lock" /* [14] */ | |
| 1902 | }; | |
| 1532 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 1533 | return; | |
| 1903 | 1534 | |
| 1904 | device_t *img; | |
| 1905 | const char *cmd = NULL; | |
| 1906 | chrn_id id; | |
| 1535 | case SEEK_WAIT_STEP_SIGNAL_TIME_DONE: | |
| 1536 | if(fi.dev) | |
| 1537 | fi.dev->stp_w(1); | |
| 1907 | 1538 | |
| 1908 | /* if not in dma mode set execution phase bit */ | |
| 1909 | if (!(fdc->upd765_flags & UPD765_DMA_MODE)) | |
| 1910 | { | |
| 1911 | fdc->FDC_main |= 0x020; /* execution phase */ | |
| 1912 | } | |
| 1539 | fi.sub_state = SEEK_WAIT_STEP_TIME; | |
| 1540 | delay_cycles(fi.tm, 500*(16-(spec >> 12))); | |
| 1541 | return; | |
| 1913 | 1542 | |
| 1914 | if (LOG_COMMAND) | |
| 1915 | { | |
| 1916 | if ((fdc->upd765_command_bytes[0] & 0x1f) < ARRAY_LENGTH(commands)) | |
| 1917 | cmd = commands[fdc->upd765_command_bytes[0] & 0x1f]; | |
| 1918 | logerror("upd765_setup_command(): Setting up command 0x%02X (%s)\n", | |
| 1919 | fdc->upd765_command_bytes[0] & 0x1f, cmd ? cmd : "???"); | |
| 1920 | } | |
| 1543 | case SEEK_WAIT_STEP_TIME: | |
| 1544 | return; | |
| 1921 | 1545 | |
| 1922 | switch (fdc->upd765_command_bytes[0] & 0x1f) | |
| 1923 | { | |
| 1924 | case 0x03: /* specify */ | |
| 1925 | /* setup step rate */ | |
| 1926 | fdc->srt_in_ms = 16-((fdc->upd765_command_bytes[1]>>4) & 0x0f); | |
| 1927 | ||
| 1928 | fdc->upd765_flags &= ~UPD765_DMA_MODE; | |
| 1929 | ||
| 1930 | if ((fdc->upd765_command_bytes[2] & 0x01)==0) | |
| 1931 | { | |
| 1932 | fdc->upd765_flags |= UPD765_DMA_MODE; | |
| 1933 | } | |
| 1934 | ||
| 1935 | upd765_idle(device); | |
| 1546 | case SEEK_WAIT_STEP_TIME_DONE: | |
| 1547 | if(fi.pcn > command[2]) | |
| 1548 | fi.pcn--; | |
| 1549 | else | |
| 1550 | fi.pcn++; | |
| 1551 | fi.sub_state = HEAD_LOAD_DONE; | |
| 1936 | 1552 | break; |
| 1937 | 1553 | |
| 1938 | case 0x04: /* sense drive status */ | |
| 1939 | upd765_setup_drive_and_side(device); | |
| 1940 | img = current_image(device); | |
| 1554 | case SEEK_DONE: | |
| 1555 | fi.counter = 0; | |
| 1556 | fi.sub_state = SCAN_ID; | |
| 1557 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1558 | return; | |
| 1941 | 1559 | |
| 1942 | fdc->upd765_status[3] = fdc->drive | (fdc->side<<2); | |
| 1943 | ||
| 1944 | if (img) | |
| 1945 | { | |
| 1946 | fdc->upd765_status[3] |= !floppy_tk00_r(img) << 4; | |
| 1947 | fdc->upd765_status[3] |= !floppy_wpt_r(img) << 6; | |
| 1948 | ||
| 1949 | if (upd765_get_rdy(device)) | |
| 1950 | { | |
| 1951 | fdc->upd765_status[3] |= 0x20; | |
| 1952 | } | |
| 1560 | case SCAN_ID: | |
| 1561 | if(cur_live.crc) { | |
| 1562 | fprintf(stderr, "Header CRC error\n"); | |
| 1563 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1564 | return; | |
| 1953 | 1565 | } |
| 1566 | sector_size = calc_sector_size(cur_live.idbuf[3]); | |
| 1567 | fifo_expect(sector_size, false); | |
| 1568 | fi.sub_state = SECTOR_READ; | |
| 1569 | live_start(fi, SEARCH_ADDRESS_MARK_DATA); | |
| 1570 | return; | |
| 1954 | 1571 | |
| 1955 | fdc->upd765_status[3] |= 0x08; | |
| 1572 | case SCAN_ID_FAILED: | |
| 1573 | fprintf(stderr, "RNF\n"); | |
| 1574 | // command_end(fi, true, 1); | |
| 1575 | return; | |
| 1956 | 1576 | |
| 1957 | /* two side and fault not set but should be? */ | |
| 1958 | fdc->upd765_result_bytes[0] = fdc->upd765_status[3]; | |
| 1959 | upd765_setup_result_phase(device,1); | |
| 1960 | break; | |
| 1961 | ||
| 1962 | case 0x07: /* recalibrate */ | |
| 1963 | upd765_seek_setup(device, 1); | |
| 1964 | break; | |
| 1965 | ||
| 1966 | case 0x0f: /* seek */ | |
| 1967 | upd765_seek_setup(device, 0); | |
| 1968 | break; | |
| 1969 | ||
| 1970 | case 0x0a: /* read id */ | |
| 1971 | upd765_setup_drive_and_side(device); | |
| 1972 | img = current_image(device); | |
| 1973 | ||
| 1974 | fdc->upd765_status[0] = fdc->drive | (fdc->side<<2); | |
| 1975 | fdc->upd765_status[1] = 0; | |
| 1976 | fdc->upd765_status[2] = 0; | |
| 1977 | ||
| 1978 | /* drive ready? */ | |
| 1979 | if (upd765_get_rdy(device)) | |
| 1980 | { | |
| 1981 | /* is disk inserted? */ | |
| 1982 | device_image_interface *image = dynamic_cast<device_image_interface *>( img); | |
| 1983 | if (image!=NULL && image->exists()) | |
| 1984 | { | |
| 1985 | int index_count = 0; | |
| 1986 | ||
| 1987 | /* floppy drive is ready and disc is inserted */ | |
| 1988 | ||
| 1989 | /* this is the id that appears when a disc is not formatted */ | |
| 1990 | /* to be checked on Amstrad */ | |
| 1991 | id.C = 0; | |
| 1992 | id.H = 0; | |
| 1993 | id.R = 0x01; | |
| 1994 | id.N = 0x02; | |
| 1995 | ||
| 1996 | /* repeat for two index counts before quitting */ | |
| 1997 | do | |
| 1998 | { | |
| 1999 | /* get next id from disc */ | |
| 2000 | if (floppy_drive_get_next_id(img, fdc->side, &id)) | |
| 2001 | { | |
| 2002 | /* got an id */ | |
| 2003 | /* if bad media keep going until failure */ | |
| 2004 | if (!(fdc->upd765_flags & UPD765_BAD_MEDIA)) break; | |
| 2005 | } | |
| 2006 | ||
| 2007 | if (floppy_drive_get_flag_state(img, FLOPPY_DRIVE_INDEX)) | |
| 2008 | { | |
| 2009 | /* update index count */ | |
| 2010 | index_count++; | |
| 2011 | } | |
| 2012 | } | |
| 2013 | while (index_count!=2); | |
| 2014 | ||
| 2015 | if (fdc->upd765_flags & UPD765_BAD_MEDIA) | |
| 2016 | { | |
| 2017 | fdc->upd765_status[0] |= 0x40; | |
| 2018 | fdc->upd765_status[1] |= 1; | |
| 2019 | } | |
| 2020 | ||
| 2021 | /* at this point, we have seen a id or two index pulses have occurred! */ | |
| 2022 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 2023 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 2024 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 2025 | fdc->upd765_result_bytes[3] = id.C; /* C */ | |
| 2026 | fdc->upd765_result_bytes[4] = id.H; /* H */ | |
| 2027 | fdc->upd765_result_bytes[5] = id.R; /* R */ | |
| 2028 | fdc->upd765_result_bytes[6] = id.N; /* N */ | |
| 2029 | ||
| 2030 | upd765_setup_result_phase(device,7); | |
| 2031 | } | |
| 2032 | else | |
| 2033 | { | |
| 2034 | /* floppy drive is ready, but no disc is inserted */ | |
| 2035 | /* this occurs on the PC */ | |
| 2036 | /* in this case, the command never quits! */ | |
| 2037 | /* there are no index pulses to stop the command! */ | |
| 2038 | } | |
| 1577 | case SECTOR_READ: | |
| 1578 | if(cur_live.crc) { | |
| 1579 | fprintf(stderr, "CRC error\n"); | |
| 2039 | 1580 | } |
| 2040 | else | |
| 2041 | { | |
| 2042 | /* what are id values when drive not ready? */ | |
| 2043 | ||
| 2044 | /* not ready, abnormal termination */ | |
| 2045 | fdc->upd765_status[0] |= (1<<3) | (1<<6); | |
| 2046 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 2047 | fdc->upd765_result_bytes[1] = fdc->upd765_status[1]; | |
| 2048 | fdc->upd765_result_bytes[2] = fdc->upd765_status[2]; | |
| 2049 | fdc->upd765_result_bytes[3] = 0; /* C */ | |
| 2050 | fdc->upd765_result_bytes[4] = 0; /* H */ | |
| 2051 | fdc->upd765_result_bytes[5] = 0; /* R */ | |
| 2052 | fdc->upd765_result_bytes[6] = 0; /* N */ | |
| 1581 | if(command[4] < command[6]) { | |
| 1582 | command[4]++; | |
| 1583 | fi.sub_state = HEAD_LOAD_DONE; | |
| 1584 | break; | |
| 2053 | 1585 | } |
| 2054 | break; | |
| 2055 | 1586 | |
| 1587 | main_phase = PHASE_RESULT; | |
| 1588 | result[0] = 0x40 | (fi.dev->ss_r() << 2) | fi.id; | |
| 1589 | result[1] = 0; | |
| 1590 | result[2] = 0; | |
| 1591 | result[3] = command[2]; | |
| 1592 | result[4] = command[3]; | |
| 1593 | result[5] = command[4]; | |
| 1594 | result[6] = command[5]; | |
| 1595 | result_pos = 7; | |
| 1596 | // command_end(fi, true, 0); | |
| 1597 | return; | |
| 2056 | 1598 | |
| 2057 | case 0x08: /* sense interrupt status */ | |
| 2058 | /* interrupt pending? */ | |
| 2059 | if (fdc->upd765_flags & UPD765_INT) | |
| 2060 | { | |
| 2061 | /* clear ready changed bit */ | |
| 2062 | fdc->ready_changed &= ~(1 << fdc->drive); | |
| 1599 | default: | |
| 1600 | logerror("%s: read track unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 1601 | return; | |
| 1602 | } | |
| 1603 | } | |
| 1604 | } | |
| 2063 | 1605 | |
| 2064 | if (!fdc->pool) { | |
| 2065 | fdc->ready_changed = 0; | |
| 2066 | } | |
| 1606 | int upd765_family_device::calc_sector_size(UINT8 size) | |
| 1607 | { | |
| 1608 | return size > 7 ? 16384 : 128 << size; | |
| 1609 | } | |
| 2067 | 1610 | |
| 2068 | /* clear drive seek bits */ | |
| 2069 | fdc->FDC_main &= ~(1 | 2 | 4 | 8); | |
| 1611 | void upd765_family_device::format_track_start(floppy_info &fi) | |
| 1612 | { | |
| 1613 | fi.main_state = FORMAT_TRACK; | |
| 1614 | fi.sub_state = HEAD_LOAD_DONE; | |
| 2070 | 1615 | |
| 2071 | /* return status */ | |
| 2072 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 2073 | /* return pcn */ | |
| 2074 | fdc->upd765_result_bytes[1] = fdc->pcn[fdc->drive]; | |
| 1616 | logerror("%s: command format track %s h=%02x n=%02x sc=%02x gpl=%02x d=%02x\n", | |
| 1617 | tag(), | |
| 1618 | command[0] & 0x40 ? "mfm" : "fm", | |
| 1619 | command[1], command[2], command[3], command[4], command[5]); | |
| 2075 | 1620 | |
| 2076 | /* return result */ | |
| 2077 | upd765_setup_result_phase(device,2); | |
| 1621 | if(fi.dev) | |
| 1622 | fi.dev->ss_w(command[1] & 4 ? 1 : 0); | |
| 1623 | sector_size = calc_sector_size(command[2]); | |
| 2078 | 1624 | |
| 2079 | if (fdc->ready_changed) | |
| 2080 | { | |
| 2081 | fdc->drive++; | |
| 2082 | fdc->upd765_status[0] = 0xc0 | fdc->drive; | |
| 2083 | } | |
| 2084 | else | |
| 2085 | { | |
| 2086 | /* Clear int */ | |
| 2087 | upd765_set_int(device, CLEAR_LINE); | |
| 2088 | } | |
| 2089 | } | |
| 2090 | else | |
| 2091 | { | |
| 2092 | if(fdc->version == TYPE_UPD72065 && (fdc->FDC_main & 0x0f) == 0x00) | |
| 2093 | { // based on XM6 | |
| 2094 | upd765_setup_invalid(device); | |
| 2095 | } | |
| 2096 | else | |
| 2097 | { | |
| 2098 | /* no int */ | |
| 2099 | fdc->upd765_result_bytes[0] = 0x80; | |
| 2100 | /* return pcn */ | |
| 2101 | fdc->upd765_result_bytes[1] = fdc->pcn[fdc->drive]; | |
| 1625 | format_track_continue(fi); | |
| 1626 | } | |
| 2102 | 1627 | |
| 2103 | /* return result */ | |
| 2104 | upd765_setup_result_phase(device,2); | |
| 2105 | } | |
| 2106 | } | |
| 1628 | void upd765_family_device::format_track_continue(floppy_info &fi) | |
| 1629 | { | |
| 1630 | for(;;) { | |
| 1631 | switch(fi.sub_state) { | |
| 1632 | case HEAD_LOAD_DONE: | |
| 1633 | fi.sub_state = WAIT_INDEX; | |
| 2107 | 1634 | break; |
| 2108 | 1635 | |
| 2109 | case 0x06: /* read data */ | |
| 2110 | upd765_setup_drive_and_side(device); | |
| 1636 | case WAIT_INDEX: | |
| 1637 | return; | |
| 2111 | 1638 | |
| 2112 | fdc->upd765_status[0] = fdc->drive | (fdc->side<<2); | |
| 2113 | fdc->upd765_status[1] = 0; | |
| 2114 | fdc->upd765_status[2] = 0; | |
| 1639 | case WAIT_INDEX_DONE: | |
| 1640 | logerror("%s: index found, writing track\n", tag()); | |
| 1641 | fi.sub_state = TRACK_DONE; | |
| 1642 | cur_live.pll.start_writing(machine().time()); | |
| 1643 | live_start(fi, WRITE_TRACK_PRE_SECTORS); | |
| 1644 | return; | |
| 2115 | 1645 | |
| 2116 | upd765_read_data(device); | |
| 2117 | break; | |
| 1646 | case TRACK_DONE: | |
| 1647 | main_phase = PHASE_RESULT; | |
| 1648 | result[0] = (fi.dev->ss_r() << 2) | fi.id; | |
| 1649 | result[1] = 0; | |
| 1650 | result[2] = 0; | |
| 1651 | result[3] = 0; | |
| 1652 | result[4] = 0; | |
| 1653 | result[5] = 0; | |
| 1654 | result[6] = 0; | |
| 1655 | result_pos = 7; | |
| 1656 | command_end(fi, true); | |
| 1657 | return; | |
| 2118 | 1658 | |
| 2119 | case 0x0c: | |
| 2120 | /* read deleted data */ | |
| 2121 | upd765_setup_drive_and_side(device); | |
| 1659 | default: | |
| 1660 | logerror("%s: format track unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 1661 | return; | |
| 1662 | } | |
| 1663 | } | |
| 1664 | } | |
| 2122 | 1665 | |
| 2123 | fdc->upd765_status[0] = fdc->drive | (fdc->side<<2); | |
| 2124 | fdc->upd765_status[1] = 0; | |
| 2125 | fdc->upd765_status[2] = 0; | |
| 1666 | void upd765_family_device::read_id_start(floppy_info &fi) | |
| 1667 | { | |
| 1668 | fi.main_state = READ_ID; | |
| 1669 | fi.sub_state = HEAD_LOAD_DONE; | |
| 2126 | 1670 | |
| 2127 | /* .. for now */ | |
| 2128 | upd765_read_data(device); | |
| 2129 | break; | |
| 1671 | logerror("%s: command read id%s, rate=%d\n", | |
| 1672 | tag(), | |
| 1673 | command[0] & 0x40 ? " mfm" : "", | |
| 1674 | cur_rate); | |
| 2130 | 1675 | |
| 2131 | case 0x09: | |
| 2132 | /* write deleted data */ | |
| 2133 | upd765_setup_drive_and_side(device); | |
| 1676 | if(fi.dev) | |
| 1677 | fi.dev->ss_w(command[1] & 4 ? 1 : 0); | |
| 2134 | 1678 | |
| 2135 | fdc->upd765_status[0] = fdc->drive | (fdc->side<<2); | |
| 2136 | fdc->upd765_status[1] = 0; | |
| 2137 | fdc->upd765_status[2] = 0; | |
| 1679 | st0 = command[1] & 7; | |
| 1680 | st1 = 0x00; | |
| 1681 | st2 = 0x00; | |
| 2138 | 1682 | |
| 2139 | /* ... for now */ | |
| 2140 | upd765_write_data(device); | |
| 2141 | break; | |
| 1683 | for(int i=0; i<4; i++) | |
| 1684 | cur_live.idbuf[i] = 0x00; | |
| 2142 | 1685 | |
| 2143 | case 0x02: | |
| 2144 | /* read a track */ | |
| 2145 | upd765_setup_drive_and_side(device); | |
| 2146 | img = current_image(device); | |
| 2147 | fdc->upd765_status[0] = fdc->drive | (fdc->side<<2); | |
| 2148 | fdc->upd765_status[1] = 0; | |
| 2149 | fdc->upd765_status[2] = 0; | |
| 1686 | read_id_continue(fi); | |
| 1687 | } | |
| 2150 | 1688 | |
| 2151 | fdc->upd765_status[0] |= UPD765_ST1_NO_DATA; | |
| 1689 | void upd765_family_device::read_id_continue(floppy_info &fi) | |
| 1690 | { | |
| 1691 | for(;;) { | |
| 1692 | switch(fi.sub_state) { | |
| 1693 | case HEAD_LOAD_DONE: | |
| 1694 | fi.counter = 0; | |
| 1695 | fi.sub_state = SCAN_ID; | |
| 1696 | live_start(fi, SEARCH_ADDRESS_MARK_HEADER); | |
| 1697 | return; | |
| 2152 | 1698 | |
| 2153 | /* wait for index */ | |
| 2154 | do | |
| 2155 | { | |
| 2156 | /* get next id from disc */ | |
| 2157 | floppy_drive_get_next_id(img, fdc->side,&id); | |
| 1699 | case SCAN_ID: | |
| 1700 | if(cur_live.crc) { | |
| 1701 | st0 |= ST0_FAIL; | |
| 1702 | st1 |= ST1_MA|ST1_DE|ST1_ND; | |
| 2158 | 1703 | } |
| 2159 | while ((floppy_drive_get_flag_state(img, FLOPPY_DRIVE_INDEX))==0); | |
| 2160 | ||
| 2161 | fdc->sector_counter = 0; | |
| 2162 | ||
| 2163 | upd765_read_a_track(device); | |
| 1704 | fi.sub_state = COMMAND_DONE; | |
| 2164 | 1705 | break; |
| 2165 | 1706 | |
| 2166 | case 0x05: /* write data */ | |
| 2167 | upd765_setup_drive_and_side(device); | |
| 2168 | ||
| 2169 | fdc->upd765_status[0] = fdc->drive | (fdc->side<<2); | |
| 2170 | fdc->upd765_status[1] = 0; | |
| 2171 | fdc->upd765_status[2] = 0; | |
| 2172 | ||
| 2173 | upd765_write_data(device); | |
| 1707 | case SCAN_ID_FAILED: | |
| 1708 | st0 |= ST0_FAIL; | |
| 1709 | st1 |= ST1_ND|ST1_MA; | |
| 1710 | fi.sub_state = COMMAND_DONE; | |
| 2174 | 1711 | break; |
| 2175 | 1712 | |
| 2176 | case 0x0d: /* format a track */ | |
| 2177 | upd765_setup_drive_and_side(device); | |
| 1713 | case COMMAND_DONE: | |
| 1714 | main_phase = PHASE_RESULT; | |
| 1715 | result[0] = st0; | |
| 1716 | result[1] = st1; | |
| 1717 | result[2] = st2; | |
| 1718 | result[3] = cur_live.idbuf[0]; | |
| 1719 | result[4] = cur_live.idbuf[1]; | |
| 1720 | result[5] = cur_live.idbuf[2]; | |
| 1721 | result[6] = cur_live.idbuf[3]; | |
| 1722 | result_pos = 7; | |
| 1723 | command_end(fi, true); | |
| 1724 | return; | |
| 2178 | 1725 | |
| 2179 | fdc->upd765_status[0] = fdc->drive | (fdc->side<<2); | |
| 2180 | fdc->upd765_status[1] = 0; | |
| 2181 | fdc->upd765_status[2] = 0; | |
| 2182 | ||
| 2183 | fdc->sector_counter = 0; | |
| 2184 | ||
| 2185 | upd765_format_track(device); | |
| 2186 | break; | |
| 2187 | ||
| 2188 | default: /* invalid */ | |
| 2189 | switch (fdc->version) | |
| 2190 | { | |
| 2191 | case TYPE_UPD765A: | |
| 2192 | upd765_setup_invalid(device); | |
| 2193 | break; | |
| 2194 | ||
| 2195 | case TYPE_UPD765B: | |
| 2196 | /* from upd765b data sheet */ | |
| 2197 | if ((fdc->upd765_command_bytes[0] & 0x01f)==0x010) | |
| 2198 | { | |
| 2199 | /* version */ | |
| 2200 | fdc->upd765_status[0] = 0x090; | |
| 2201 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 2202 | upd765_setup_result_phase(device,1); | |
| 2203 | } | |
| 2204 | break; | |
| 2205 | ||
| 2206 | case TYPE_UPD72065: | |
| 2207 | switch(fdc->upd765_command_bytes[0] & 0x3f) | |
| 2208 | { | |
| 2209 | case 0x36: // Software Reset | |
| 2210 | upd765_reset(device,0); | |
| 2211 | upd765_idle(device); | |
| 2212 | if(LOG_COMMAND) | |
| 2213 | logerror("upd72065: command - Software Reset\n"); | |
| 2214 | break; | |
| 2215 | default: | |
| 2216 | upd765_setup_invalid(device); | |
| 2217 | break; | |
| 2218 | } | |
| 2219 | break; | |
| 2220 | ||
| 2221 | case TYPE_SMC37C78: | |
| 2222 | /* TO BE COMPLETED!!! !*/ | |
| 2223 | switch (fdc->upd765_command_bytes[0] & 0x1f) | |
| 2224 | { | |
| 2225 | case 0x10: /* version */ | |
| 2226 | fdc->upd765_status[0] = 0x90; | |
| 2227 | fdc->upd765_result_bytes[0] = fdc->upd765_status[0]; | |
| 2228 | upd765_setup_result_phase(device,1); | |
| 2229 | break; | |
| 2230 | ||
| 2231 | case 0x13: /* configure */ | |
| 2232 | fdc->pool = fdc->upd765_command_bytes[1] & 0x10; | |
| 2233 | upd765_idle(device); | |
| 2234 | break; | |
| 2235 | ||
| 2236 | case 0x0e: /* dump reg */ | |
| 2237 | fdc->upd765_result_bytes[0] = fdc->pcn[0]; | |
| 2238 | fdc->upd765_result_bytes[1] = fdc->pcn[1]; | |
| 2239 | fdc->upd765_result_bytes[2] = fdc->pcn[2]; | |
| 2240 | fdc->upd765_result_bytes[3] = fdc->pcn[3]; | |
| 2241 | ||
| 2242 | upd765_setup_result_phase(device,10); | |
| 2243 | break; | |
| 2244 | ||
| 2245 | case 0x12: /* perpendicular mode */ | |
| 2246 | upd765_idle(device); | |
| 2247 | break; | |
| 2248 | ||
| 2249 | case 0x14: /* lock */ | |
| 2250 | upd765_setup_result_phase(device,1); | |
| 2251 | break; | |
| 2252 | } | |
| 2253 | break; | |
| 2254 | } | |
| 1726 | default: | |
| 1727 | logerror("%s: read id unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 1728 | return; | |
| 1729 | } | |
| 2255 | 1730 | } |
| 2256 | 1731 | } |
| 2257 | 1732 | |
| 2258 | ||
| 2259 | /* dma acknowledge write */ | |
| 2260 | WRITE8_DEVICE_HANDLER(upd765_dack_w) | |
| 1733 | void upd765_family_device::check_irq() | |
| 2261 | 1734 | { |
| 2262 | /* clear request */ | |
| 2263 | upd765_set_dma_drq(device, CLEAR_LINE); | |
| 2264 | ||
| 2265 | /* write data */ | |
| 2266 | upd765_data_w(device, space, offset, data); | |
| 1735 | bool old_irq = cur_irq; | |
| 1736 | cur_irq = data_irq || internal_drq; | |
| 1737 | for(int i=0; i<4; i++) | |
| 1738 | cur_irq = cur_irq || flopi[i].irq_seek || flopi[i].irq_polled; | |
| 1739 | cur_irq = cur_irq && (dor & 4) && (dor & 8); | |
| 1740 | if(cur_irq != old_irq && !intrq_cb.isnull()) { | |
| 1741 | logerror("%s: irq = %d\n", tag(), cur_irq); | |
| 1742 | intrq_cb(cur_irq); | |
| 1743 | } | |
| 2267 | 1744 | } |
| 2268 | 1745 | |
| 2269 | ||
| 1746 | bool upd765_family_device::get_irq() const | |
| 2270 | 1747 | { |
| 2271 | /* clear data request */ | |
| 2272 | upd765_set_dma_drq(device,CLEAR_LINE); | |
| 2273 | ||
| 2274 | /* read data */ | |
| 2275 | return upd765_data_r(device, space, offset); | |
| 1748 | return cur_irq; | |
| 2276 | 1749 | } |
| 2277 | 1750 | |
| 2278 | st | |
| 1751 | astring upd765_family_device::tts(attotime t) | |
| 2279 | 1752 | { |
| 2280 | device_t* device = (device_t*)ptr; | |
| 2281 | upd765_set_int(device, 1); | |
| 1753 | char buf[256]; | |
| 1754 | const char *sign = ""; | |
| 1755 | if(t.seconds < 0) { | |
| 1756 | t = attotime::zero-t; | |
| 1757 | sign = "-"; | |
| 1758 | } | |
| 1759 | int nsec = t.attoseconds / ATTOSECONDS_PER_NANOSECOND; | |
| 1760 | sprintf(buf, "%s%04d.%03d,%03d,%03d", sign, int(t.seconds), nsec/1000000, (nsec/1000)%1000, nsec % 1000); | |
| 1761 | return buf; | |
| 2282 | 1762 | } |
| 2283 | 1763 | |
| 2284 | ||
| 1764 | astring upd765_family_device::ttsn() | |
| 2285 | 1765 | { |
| 2286 | upd765_t *fdc = get_safe_token(device); | |
| 2287 | if (state) fdc->upd765_flags |= UPD765_BAD_MEDIA; | |
| 2288 | else fdc->upd765_flags &= ~UPD765_BAD_MEDIA; | |
| 1766 | return tts(machine().time()); | |
| 2289 | 1767 | } |
| 2290 | 1768 | |
| 2291 | void upd765_ | |
| 1769 | void upd765_family_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) | |
| 2292 | 1770 | { |
| 2293 | upd765_t *fdc = get_safe_token(device); | |
| 1771 | if(id == TIMER_DRIVE_READY_POLLING) { | |
| 1772 | run_drive_ready_polling(); | |
| 1773 | return; | |
| 1774 | } | |
| 2294 | 1775 | |
| 2295 | /* upd765 in idle state - ready to accept commands */ | |
| 2296 | upd765_idle(device); | |
| 1776 | live_sync(); | |
| 2297 | 1777 | |
| 2298 | /* set int low */ | |
| 2299 | upd765_set_int(device, 0); | |
| 2300 | /* set dma drq output */ | |
| 2301 | upd765_set_dma_drq(device,0); | |
| 1778 | floppy_info &fi = flopi[id]; | |
| 1779 | switch(fi.sub_state) { | |
| 1780 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 1781 | fi.sub_state = SEEK_WAIT_STEP_SIGNAL_TIME_DONE; | |
| 1782 | break; | |
| 1783 | case SEEK_WAIT_STEP_TIME: | |
| 1784 | fi.sub_state = SEEK_WAIT_STEP_TIME_DONE; | |
| 1785 | break; | |
| 1786 | } | |
| 2302 | 1787 | |
| 2303 | /* tandy 100hx assumes that after NEC is reset, it is in DMA mode */ | |
| 2304 | fdc->upd765_flags |= UPD765_DMA_MODE; | |
| 1788 | general_continue(fi); | |
| 1789 | } | |
| 2305 | 1790 | |
| 2306 | /* if ready input is set during reset generate an int */ | |
| 2307 | if (upd765_get_rdy(device)) | |
| 2308 | { | |
| 2309 | int i; | |
| 2310 | int a_drive_is_ready; | |
| 1791 | void upd765_family_device::run_drive_ready_polling() | |
| 1792 | { | |
| 1793 | if(main_phase != PHASE_CMD || (fifocfg & FIF_POLL)) | |
| 1794 | return; | |
| 2311 | 1795 | |
| 2312 | fdc->upd765_status[0] = 0x080 | 0x040; | |
| 1796 | bool changed = false; | |
| 1797 | for(int fid=0; fid<4; fid++) { | |
| 1798 | bool ready = get_ready(fid); | |
| 1799 | if(ready != flopi[fid].ready) { | |
| 1800 | logerror("%s: polled %d : %d -> %d\n", tag(), fid, flopi[fid].ready, ready); | |
| 1801 | flopi[fid].ready = ready; | |
| 1802 | flopi[fid].irq_polled = true; | |
| 1803 | changed = true; | |
| 1804 | } | |
| 1805 | } | |
| 1806 | if(changed) | |
| 1807 | check_irq(); | |
| 1808 | } | |
| 2313 | 1809 | |
| 2314 | // HACK signal ready changed for all drives | |
| 2315 | fdc->ready_changed = 0x0f; | |
| 2316 | fdc->drive = 0; | |
| 1810 | void upd765_family_device::index_callback(floppy_image_device *floppy, int state) | |
| 1811 | { | |
| 1812 | for(int fid=0; fid<4; fid++) { | |
| 1813 | floppy_info &fi = flopi[fid]; | |
| 1814 | if(fi.dev != floppy) | |
| 1815 | continue; | |
| 2317 | 1816 | |
| 2318 | /* for the purpose of pc-xt. If any of the drives have a disk inserted, | |
| 2319 | do not set not-ready - need to check with pc_fdc.c whether all drives | |
| 2320 | are checked or only the drive selected with the drive select bits?? */ | |
| 1817 | if(fi.live) | |
| 1818 | live_sync(); | |
| 1819 | fi.index = state; | |
| 2321 | 1820 | |
| 2322 | a_drive_is_ready = 0; | |
| 2323 | for (i = 0; i < 4; i++) | |
| 2324 | { | |
| 2325 | if (fdc->intf->floppy_drive_tags[i]!=NULL) | |
| 2326 | { | |
| 2327 | device_t *img; | |
| 1821 | if(!state) { | |
| 1822 | general_continue(fi); | |
| 1823 | continue; | |
| 1824 | } | |
| 2328 | 1825 | |
| 2329 | if (device->owner() != NULL) | |
| 2330 | img = device->owner()->subdevice(fdc->intf->floppy_drive_tags[i]); | |
| 2331 | else | |
| 2332 | img = device->machine().device(fdc->intf->floppy_drive_tags[i]); | |
| 1826 | switch(fi.sub_state) { | |
| 1827 | case IDLE: | |
| 1828 | case SEEK_MOVE: | |
| 1829 | case SEEK_WAIT_STEP_SIGNAL_TIME: | |
| 1830 | case SEEK_WAIT_STEP_SIGNAL_TIME_DONE: | |
| 1831 | case SEEK_WAIT_STEP_TIME: | |
| 1832 | case SEEK_WAIT_STEP_TIME_DONE: | |
| 1833 | case HEAD_LOAD_DONE: | |
| 1834 | case SCAN_ID_FAILED: | |
| 1835 | case SECTOR_READ: | |
| 1836 | break; | |
| 2333 | 1837 | |
| 2334 | device_image_interface *image = dynamic_cast<device_image_interface *>( img); | |
| 2335 | if (image->exists()) | |
| 2336 | { | |
| 2337 | a_drive_is_ready = 1; | |
| 2338 | break; | |
| 2339 | } | |
| 1838 | case WAIT_INDEX: | |
| 1839 | fi.sub_state = WAIT_INDEX_DONE; | |
| 1840 | break; | |
| 1841 | ||
| 1842 | case SCAN_ID: | |
| 1843 | fi.counter++; | |
| 1844 | if(fi.counter == 2) { | |
| 1845 | fi.sub_state = SCAN_ID_FAILED; | |
| 1846 | live_abort(); | |
| 2340 | 1847 | } |
| 1848 | break; | |
| 2341 | 1849 | |
| 2342 | } | |
| 1850 | case TRACK_DONE: | |
| 1851 | live_abort(); | |
| 1852 | break; | |
| 2343 | 1853 | |
| 2344 | if (!a_drive_is_ready && fdc->intf->rdy_pin == UPD765_RDY_PIN_CONNECTED ) | |
| 2345 | { | |
| 2346 | fdc->upd765_status[0] |= 0x08; | |
| 1854 | default: | |
| 1855 | logerror("%s: Index pulse on unknown sub-state %d\n", ttsn().cstr(), fi.sub_state); | |
| 1856 | break; | |
| 2347 | 1857 | } |
| 2348 | 1858 | |
| 2349 | | |
| 1859 | general_continue(fi); | |
| 2350 | 1860 | } |
| 2351 | 1861 | } |
| 2352 | 1862 | |
| 2353 | WRITE_LINE_DEVICE_HANDLER( upd765_reset_w ) | |
| 1863 | ||
| 1864 | void upd765_family_device::general_continue(floppy_info &fi) | |
| 2354 | 1865 | { |
| 2355 | upd765_t *fdc = get_safe_token(device); | |
| 1866 | if(fi.live && cur_live.state != IDLE) { | |
| 1867 | live_run(); | |
| 1868 | if(cur_live.state != IDLE) | |
| 1869 | return; | |
| 1870 | } | |
| 2356 | 1871 | |
| 2357 | int flags; | |
| 1872 | switch(fi.main_state) { | |
| 1873 | case IDLE: | |
| 1874 | break; | |
| 2358 | 1875 | |
| 2359 | /* get previous reset state */ | |
| 2360 | flags = fdc->upd765_flags; | |
| 1876 | case RECALIBRATE: | |
| 1877 | case SEEK: | |
| 1878 | seek_continue(fi); | |
| 1879 | break; | |
| 2361 | 1880 | |
| 2362 | /* set new reset state */ | |
| 2363 | /* clear reset */ | |
| 2364 | fdc->upd765_flags &= ~UPD765_RESET; | |
| 1881 | case READ_DATA: | |
| 1882 | read_data_continue(fi); | |
| 1883 | break; | |
| 2365 | 1884 | |
| 2366 | /* reset */ | |
| 2367 | if (state) | |
| 2368 | { | |
| 2369 | fdc->upd765_flags |= UPD765_RESET; | |
| 1885 | case WRITE_DATA: | |
| 1886 | write_data_continue(fi); | |
| 1887 | break; | |
| 2370 | 1888 | |
| 2371 | upd765_set_int(device, 0); | |
| 2372 | } | |
| 1889 | case READ_TRACK: | |
| 1890 | read_track_continue(fi); | |
| 1891 | break; | |
| 2373 | 1892 | |
| 2374 | /* reset changed state? */ | |
| 2375 | if (((flags^fdc->upd765_flags) & UPD765_RESET)!=0) | |
| 2376 | { | |
| 2377 | /* yes */ | |
| 1893 | case FORMAT_TRACK: | |
| 1894 | format_track_continue(fi); | |
| 1895 | break; | |
| 2378 | 1896 | |
| 2379 | /* no longer reset */ | |
| 2380 | if ((fdc->upd765_flags & UPD765_RESET)==0) | |
| 2381 | { | |
| 2382 | /* reset nec */ | |
| 2383 | upd765_reset(device, 0); | |
| 2384 | } | |
| 1897 | case READ_ID: | |
| 1898 | read_id_continue(fi); | |
| 1899 | break; | |
| 1900 | ||
| 1901 | default: | |
| 1902 | logerror("%s: general_continue on unknown main-state %d\n", ttsn().cstr(), fi.main_state); | |
| 1903 | break; | |
| 2385 | 1904 | } |
| 2386 | 1905 | } |
| 2387 | 1906 | |
| 1907 | bool upd765_family_device::read_one_bit(attotime limit) | |
| 1908 | { | |
| 1909 | int bit = cur_live.pll.get_next_bit(cur_live.tm, cur_live.fi->dev, limit); | |
| 1910 | if(bit < 0) | |
| 1911 | return true; | |
| 1912 | cur_live.shift_reg = (cur_live.shift_reg << 1) | bit; | |
| 1913 | cur_live.bit_counter++; | |
| 1914 | if(cur_live.data_separator_phase) { | |
| 1915 | cur_live.data_reg = (cur_live.data_reg << 1) | bit; | |
| 1916 | if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000) | |
| 1917 | cur_live.crc = (cur_live.crc << 1) ^ 0x1021; | |
| 1918 | else | |
| 1919 | cur_live.crc = cur_live.crc << 1; | |
| 1920 | } | |
| 1921 | cur_live.data_separator_phase = !cur_live.data_separator_phase; | |
| 1922 | return false; | |
| 1923 | } | |
| 2388 | 1924 | |
| 2389 | ||
| 1925 | bool upd765_family_device::write_one_bit(attotime limit) | |
| 2390 | 1926 | { |
| 2391 | upd765_t *fdc = get_safe_token(device); | |
| 1927 | bool bit = cur_live.shift_reg & 0x8000; | |
| 1928 | if(cur_live.pll.write_next_bit(bit, cur_live.tm, cur_live.fi->dev, limit)) | |
| 1929 | return true; | |
| 1930 | if(cur_live.bit_counter & 1) { | |
| 1931 | if((cur_live.crc ^ (bit ? 0x8000 : 0x0000)) & 0x8000) | |
| 1932 | cur_live.crc = (cur_live.crc << 1) ^ 0x1021; | |
| 1933 | else | |
| 1934 | cur_live.crc = cur_live.crc << 1; | |
| 1935 | } | |
| 1936 | cur_live.shift_reg = cur_live.shift_reg << 1; | |
| 1937 | cur_live.bit_counter--; | |
| 1938 | return false; | |
| 1939 | } | |
| 2392 | 1940 | |
| 2393 | /* clear ready state */ | |
| 2394 | fdc->upd765_flags &= ~UPD765_FDD_READY; | |
| 1941 | void upd765_family_device::live_write_raw(UINT16 raw) | |
| 1942 | { | |
| 1943 | // logerror("write %04x %04x\n", raw, cur_live.crc); | |
| 1944 | cur_live.shift_reg = raw; | |
| 1945 | cur_live.data_bit_context = raw & 1; | |
| 1946 | } | |
| 2395 | 1947 | |
| 2396 | if (state) | |
| 2397 | { | |
| 2398 | fdc->upd765_flags |= UPD765_FDD_READY; | |
| 1948 | void upd765_family_device::live_write_mfm(UINT8 mfm) | |
| 1949 | { | |
| 1950 | bool context = cur_live.data_bit_context; | |
| 1951 | UINT16 raw = 0; | |
| 1952 | for(int i=0; i<8; i++) { | |
| 1953 | bool bit = mfm & (0x80 >> i); | |
| 1954 | if(!(bit || context)) | |
| 1955 | raw |= 0x8000 >> (2*i); | |
| 1956 | if(bit) | |
| 1957 | raw |= 0x4000 >> (2*i); | |
| 1958 | context = bit; | |
| 2399 | 1959 | } |
| 1960 | cur_live.data_reg = mfm; | |
| 1961 | cur_live.shift_reg = raw; | |
| 1962 | cur_live.data_bit_context = context; | |
| 1963 | // logerror("write %02x %04x %04x\n", mfm, cur_live.crc, raw); | |
| 2400 | 1964 | } |
| 2401 | 1965 | |
| 2402 | ||
| 2403 | /* Device Interface */ | |
| 2404 | ||
| 2405 | static void common_start(device_t *device, int device_type) | |
| 1966 | bool upd765_family_device::sector_matches() const | |
| 2406 | 1967 | { |
| 2407 | upd765_t *fdc = get_safe_token(device); | |
| 2408 | // validate arguments | |
| 1968 | return | |
| 1969 | cur_live.idbuf[0] == command[2] && | |
| 1970 | cur_live.idbuf[1] == command[3] && | |
| 1971 | cur_live.idbuf[2] == command[4] && | |
| 1972 | cur_live.idbuf[3] == command[5]; | |
| 1973 | } | |
| 2409 | 1974 | |
| 2410 | assert(device != NULL); | |
| 2411 | assert(device->tag() != NULL); | |
| 2412 | assert(device->static_config() != NULL); | |
| 2413 | ||
| 2414 | fdc->intf = (const upd765_interface*)device->static_config(); | |
| 2415 | ||
| 2416 | fdc->version = (UPD765_VERSION)device_type; | |
| 2417 | fdc->timer = device->machine().scheduler().timer_alloc(FUNC(upd765_timer_callback), (void*)device); | |
| 2418 | fdc->seek_timer = device->machine().scheduler().timer_alloc(FUNC(upd765_seek_timer_callback), (void*)device); | |
| 2419 | fdc->command_timer = device->machine().scheduler().timer_alloc(FUNC(upd765_continue_command), (void*)device); | |
| 2420 | ||
| 2421 | fdc->upd765_flags &= UPD765_FDD_READY; | |
| 2422 | fdc->data_buffer = auto_alloc_array(device->machine(), char, 32*1024); | |
| 2423 | ||
| 2424 | fdc->out_int_func.resolve(fdc->intf->out_int_func, *device); | |
| 2425 | fdc->out_drq_func.resolve(fdc->intf->out_drq_func, *device); | |
| 2426 | ||
| 2427 | // plain upd765 is doing pooling | |
| 2428 | fdc->pool = true; | |
| 2429 | // register for state saving | |
| 2430 | //state_save_register_item(device->machine(), "upd765", device->tag(), 0, upd765->number); | |
| 1975 | void upd765_family_device::pll_t::set_clock(attotime _period) | |
| 1976 | { | |
| 1977 | period = _period; | |
| 1978 | period_adjust_base = period * 0.05; | |
| 1979 | min_period = period * 0.75; | |
| 1980 | max_period = period * 1.25; | |
| 2431 | 1981 | } |
| 2432 | 1982 | |
| 2433 | ||
| 1983 | void upd765_family_device::pll_t::reset(attotime when) | |
| 2434 | 1984 | { |
| 2435 | common_start(device, TYPE_UPD765A); | |
| 1985 | ctime = when; | |
| 1986 | phase_adjust = attotime::zero; | |
| 1987 | freq_hist = 0; | |
| 1988 | write_position = 0; | |
| 1989 | write_start_time = attotime::never; | |
| 2436 | 1990 | } |
| 2437 | 1991 | |
| 2438 | ||
| 1992 | void upd765_family_device::pll_t::start_writing(attotime tm) | |
| 2439 | 1993 | { |
| 2440 | common_start(device, TYPE_UPD765B); | |
| 1994 | write_start_time = tm; | |
| 1995 | write_position = 0; | |
| 2441 | 1996 | } |
| 2442 | 1997 | |
| 2443 | st | |
| 1998 | void upd765_family_device::pll_t::stop_writing(floppy_image_device *floppy, attotime tm) | |
| 2444 | 1999 | { |
| 2445 | common_start(device, TYPE_SMC37C78); | |
| 2446 | // specified in documentation that by default is off | |
| 2447 | upd765_t *fdc = get_safe_token(device); | |
| 2448 | fdc->pool = false; | |
| 2000 | commit(floppy, tm); | |
| 2001 | write_start_time = attotime::never; | |
| 2449 | 2002 | } |
| 2450 | 2003 | |
| 2451 | ||
| 2004 | void upd765_family_device::pll_t::commit(floppy_image_device *floppy, attotime tm) | |
| 2452 | 2005 | { |
| 2453 | common_start(device, TYPE_UPD72065); | |
| 2006 | if(write_start_time.is_never() || tm == write_start_time) | |
| 2007 | return; | |
| 2008 | ||
| 2009 | if(floppy) | |
| 2010 | floppy->write_flux(write_start_time, tm, write_position, write_buffer); | |
| 2011 | write_start_time = tm; | |
| 2012 | write_position = 0; | |
| 2454 | 2013 | } |
| 2455 | 2014 | |
| 2456 | ||
| 2015 | int upd765_family_device::pll_t::get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit) | |
| 2457 | 2016 | { |
| 2458 | int i; | |
| 2459 | upd765_t *fdc = get_safe_token(device); | |
| 2460 | for (i = 0; i < 4; i++) { | |
| 2461 | if (fdc->intf->floppy_drive_tags[i]!=NULL) | |
| 2462 | { | |
| 2463 | device_t *img; | |
| 2017 | attotime edge = floppy ? floppy->get_next_transition(ctime) : attotime::never; | |
| 2464 | 2018 | |
| 2465 | if (device->owner() != NULL) | |
| 2466 | img = device->owner()->subdevice(fdc->intf->floppy_drive_tags[i]); | |
| 2467 | else | |
| 2468 | img = device->machine().device(fdc->intf->floppy_drive_tags[i]); | |
| 2019 | attotime next = ctime + period + phase_adjust; | |
| 2469 | 2020 | |
| 2470 | floppy_drive_set_controller(img, device); | |
| 2471 | floppy_drive_set_ready_state_change_callback(img, upd765_set_ready_change_callback); | |
| 2472 | } | |
| 2021 | #if 0 | |
| 2022 | if(!edge.is_never()) | |
| 2023 | fprintf(stderr, "ctime=%s, transition_time=%s, next=%s, pha=%s\n", tts(ctime).cstr(), tts(edge).cstr(), tts(next).cstr(), tts(phase_adjust).cstr()); | |
| 2024 | #endif | |
| 2025 | ||
| 2026 | if(next > limit) | |
| 2027 | return -1; | |
| 2028 | ||
| 2029 | ctime = next; | |
| 2030 | ||
| 2031 | if(edge.is_never() || edge >= next) { | |
| 2032 | // No transition in the window means 0 and pll in free run mode | |
| 2033 | phase_adjust = attotime::zero; | |
| 2034 | tm = next; | |
| 2035 | return 0; | |
| 2473 | 2036 | } |
| 2474 | 2037 | |
| 2475 | upd765_reset(device,0); | |
| 2476 | } | |
| 2038 | // Transition in the window means 1, and the pll is adjusted | |
| 2477 | 2039 | |
| 2478 | ||
| 2040 | attotime delta = edge - (next - period/2); | |
| 2479 | 2041 | |
| 2480 | upd765a_device::upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) | |
| 2481 | : device_t(mconfig, UPD765A, "UPD765A", tag, owner, clock) | |
| 2482 | { | |
| 2483 | m_token = global_alloc_clear(upd765_t); | |
| 2484 | } | |
| 2485 | upd765a_device::upd765a_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) | |
| 2486 | : device_t(mconfig, type, name, tag, owner, clock) | |
| 2487 | { | |
| 2488 | m_token = global_alloc_clear(upd765_t); | |
| 2489 | } | |
| 2042 | if(delta.seconds < 0) | |
| 2043 | phase_adjust = attotime::zero - ((attotime::zero - delta)*65)/100; | |
| 2044 | else | |
| 2045 | phase_adjust = (delta*65)/100; | |
| 2490 | 2046 | |
| 2491 | //------------------------------------------------- | |
| 2492 | // device_config_complete - perform any | |
| 2493 | // operations now that the configuration is | |
| 2494 | // complete | |
| 2495 | //------------------------------------------------- | |
| 2047 | if(delta < attotime::zero) { | |
| 2048 | if(freq_hist < 0) | |
| 2049 | freq_hist--; | |
| 2050 | else | |
| 2051 | freq_hist = -1; | |
| 2052 | } else if(delta > attotime::zero) { | |
| 2053 | if(freq_hist > 0) | |
| 2054 | freq_hist++; | |
| 2055 | else | |
| 2056 | freq_hist = 1; | |
| 2057 | } else | |
| 2058 | freq_hist = 0; | |
| 2496 | 2059 | |
| 2497 | void upd765a_device::device_config_complete() | |
| 2498 | { | |
| 2499 | } | |
| 2060 | if(freq_hist) { | |
| 2061 | int afh = freq_hist < 0 ? -freq_hist : freq_hist; | |
| 2062 | if(afh > 1) { | |
| 2063 | attotime aper = attotime::from_double(period_adjust_base.as_double()*delta.as_double()/period.as_double()); | |
| 2064 | period += aper; | |
| 2500 | 2065 | |
| 2501 | //------------------------------------------------- | |
| 2502 | // device_start - device-specific startup | |
| 2503 | //------------------------------------------------- | |
| 2066 | if(period < min_period) | |
| 2067 | period = min_period; | |
| 2068 | else if(period > max_period) | |
| 2069 | period = max_period; | |
| 2070 | } | |
| 2071 | } | |
| 2504 | 2072 | |
| 2505 | void upd765a_device::device_start() | |
| 2506 | { | |
| 2507 | DEVICE_START_NAME( upd765a )(this); | |
| 2073 | return 1; | |
| 2508 | 2074 | } |
| 2509 | 2075 | |
| 2510 | //------------------------------------------------- | |
| 2511 | // device_reset - device-specific reset | |
| 2512 | //------------------------------------------------- | |
| 2513 | ||
| 2514 | void upd765a_device::device_reset() | |
| 2076 | bool upd765_family_device::pll_t::write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit) | |
| 2515 | 2077 | { |
| 2516 | DEVICE_RESET_NAME( upd765 )(this); | |
| 2517 | } | |
| 2078 | if(write_start_time.is_never()) { | |
| 2079 | write_start_time = ctime; | |
| 2080 | write_position = 0; | |
| 2081 | } | |
| 2518 | 2082 | |
| 2083 | attotime etime = ctime + period; | |
| 2084 | if(etime > limit) | |
| 2085 | return true; | |
| 2519 | 2086 | |
| 2520 | const device_type UPD765B = &device_creator<upd765b_device>; | |
| 2087 | if(bit && write_position < ARRAY_LENGTH(write_buffer)) | |
| 2088 | write_buffer[write_position++] = ctime + period/2; | |
| 2521 | 2089 | |
| 2522 | upd765b_device::upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) | |
| 2523 | : upd765a_device(mconfig, UPD765B, "UPD765B", tag, owner, clock) | |
| 2090 | tm = etime; | |
| 2091 | ctime = etime; | |
| 2092 | return false; | |
| 2093 | } | |
| 2094 | ||
| 2095 | upd765a_device::upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD765A, "UPD765A", tag, owner, clock) | |
| 2524 | 2096 | { |
| 2097 | m_shortname = "upd765a"; | |
| 2098 | dor_reset = 0x0c; | |
| 2525 | 2099 | } |
| 2526 | 2100 | |
| 2527 | //------------------------------------------------- | |
| 2528 | // device_start - device-specific startup | |
| 2529 | //------------------------------------------------- | |
| 2530 | ||
| 2531 | void upd765b_device::device_start() | |
| 2101 | upd765b_device::upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD765B, "UPD765B", tag, owner, clock) | |
| 2532 | 2102 | { |
| 2533 | DEVICE_START_NAME( upd765b )(this); | |
| 2103 | m_shortname = "upd765b"; | |
| 2104 | dor_reset = 0x0c; | |
| 2534 | 2105 | } |
| 2535 | 2106 | |
| 2536 | ||
| 2537 | const device_type SMC37C78 = &device_creator<smc37c78_device>; | |
| 2538 | ||
| 2539 | smc37c78_device::smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) | |
| 2540 | : upd765a_device(mconfig, SMC37C78, "SMC37C78", tag, owner, clock) | |
| 2107 | i8272a_device::i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, I8272A, "I8272A", tag, owner, clock) | |
| 2541 | 2108 | { |
| 2109 | m_shortname = "i8272a"; | |
| 2110 | dor_reset = 0x0c; | |
| 2542 | 2111 | } |
| 2543 | 2112 | |
| 2544 | //------------------------------------------------- | |
| 2545 | // device_start - device-specific startup | |
| 2546 | //------------------------------------------------- | |
| 2547 | ||
| 2548 | void smc37c78_device::device_start() | |
| 2113 | upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD72065, "UPD72065", tag, owner, clock) | |
| 2549 | 2114 | { |
| 2550 | DEVICE_START_NAME( smc37c78 )(this); | |
| 2115 | m_shortname = "upd72065"; | |
| 2116 | dor_reset = 0x0c; | |
| 2551 | 2117 | } |
| 2552 | 2118 | |
| 2553 | ||
| 2554 | const device_type UPD72065 = &device_creator<upd72065_device>; | |
| 2555 | ||
| 2556 | upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) | |
| 2557 | : upd765a_device(mconfig, UPD72065, "UPD72065", tag, owner, clock) | |
| 2119 | smc37c78_device::smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, SMC37C78, "SMC37C78", tag, owner, clock) | |
| 2558 | 2120 | { |
| 2121 | m_shortname = "smc37c78"; | |
| 2122 | ready_connected = false; | |
| 2123 | select_connected = true; | |
| 2559 | 2124 | } |
| 2560 | 2125 | |
| 2561 | //------------------------------------------------- | |
| 2562 | // device_start - device-specific startup | |
| 2563 | //------------------------------------------------- | |
| 2564 | ||
| 2565 | void upd72065_device::device_start() | |
| 2126 | n82077aa_device::n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, N82077AA, "N82077AA", tag, owner, clock) | |
| 2566 | 2127 | { |
| 2567 | DEVICE_START_NAME( upd72065 )(this); | |
| 2128 | m_shortname = "n82077aa"; | |
| 2129 | ready_connected = false; | |
| 2130 | select_connected = true; | |
| 2568 | 2131 | } |
| 2569 | 2132 | |
| 2570 | ||
| 2133 | pc_fdc_superio_device::pc_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, PC_FDC_SUPERIO, "PC FDC SUPERIO", tag, owner, clock) | |
| 2134 | { | |
| 2135 | m_shortname = "pc_fdc_superio"; | |
| 2136 | ready_polled = false; | |
| 2137 | ready_connected = false; | |
| 2138 | select_connected = true; | |
| 2139 | } |
| r18419 | r18420 | |
|---|---|---|
| 1 | /*************************************************************************** | |
| 1 | #ifndef __UPD765_F_H__ | |
| 2 | #define __UPD765_F_H__ | |
| 2 | 3 | |
| 3 | machine/upd765.h | |
| 4 | #include "emu.h" | |
| 5 | #include "imagedev/floppy.h" | |
| 4 | 6 | |
| 5 | Functions to emulate a NEC upd765/Intel 8272 compatible | |
| 6 | floppy disk controller | |
| 7 | /* | |
| 8 | * ready = true if the ready line is physically connected to the floppy drive | |
| 9 | * select = true if the fdc controls the floppy drive selection | |
| 10 | * mode = MODE_AT, MODE_PS2 or MODE_M30 for the fdcs that have reset-time selection | |
| 11 | */ | |
| 7 | 12 | |
| 8 | ***************************************************************************/ | |
| 13 | #define MCFG_UPD765A_ADD(_tag, _ready, _select) \ | |
| 14 | MCFG_DEVICE_ADD(_tag, UPD765A, 0) \ | |
| 15 | downcast<upd765a_device *>(device)->set_ready_line_connected(_ready); \ | |
| 16 | downcast<upd765a_device *>(device)->set_select_lines_connected(_select); | |
| 9 | 17 | |
| 10 | #ifndef __UPD765_H__ | |
| 11 | #define __UPD765_H__ | |
| 18 | #define MCFG_UPD765B_ADD(_tag, _ready, _select) \ | |
| 19 | MCFG_DEVICE_ADD(_tag, UPD765B, 0) \ | |
| 20 | downcast<upd765b_device *>(device)->set_ready_line_connected(_ready); \ | |
| 21 | downcast<upd765b_device *>(device)->set_select_lines_connected(_select); | |
| 12 | 22 | |
| 13 | #include "devcb.h" | |
| 14 | #include "imagedev/flopdrv.h" | |
| 23 | #define MCFG_I8272A_ADD(_tag, _ready) \ | |
| 24 | MCFG_DEVICE_ADD(_tag, I8272A, 0) \ | |
| 25 | downcast<i8272a_device *>(device)->set_ready_line_connected(_ready); | |
| 15 | 26 | |
| 27 | #define MCFG_UPD72065_ADD(_tag, _ready, _select) \ | |
| 28 | MCFG_DEVICE_ADD(_tag, UPD72065, 0) \ | |
| 29 | downcast<upd72065_device *>(device)->set_ready_line_connected(_ready); \ | |
| 30 | downcast<upd72065_device *>(device)->set_select_lines_connected(_select); | |
| 16 | 31 | |
| 17 | /*************************************************************************** | |
| 18 | MACROS | |
| 19 | ***************************************************************************/ | |
| 32 | #define MCFG_SMC37C78_ADD(_tag) \ | |
| 33 | MCFG_DEVICE_ADD(_tag, SMC37C78, 0) | |
| 20 | 34 | |
| 21 | class upd765a_device : public device_t | |
| 22 | { | |
| 35 | #define MCFG_N82077AA_ADD(_tag, _mode) \ | |
| 36 | MCFG_DEVICE_ADD(_tag, N82077AA, 0) \ | |
| 37 | downcast<n82077aa_device *>(device)->set_mode(_mode); | |
| 38 | ||
| 39 | #define MCFG_PC_FDC_SUPERIO_ADD(_tag) \ | |
| 40 | MCFG_DEVICE_ADD(_tag, PC_FDC_SUPERIO, 0) | |
| 41 | ||
| 42 | /* Interface required for PC ISA wrapping */ | |
| 43 | class pc_fdc_interface : public device_t { | |
| 23 | 44 | public: |
| 24 | upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 25 | upd765a_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 26 | ~upd765a_device() { global_free(m_token); } | |
| 45 | typedef delegate<void (bool state)> line_cb; | |
| 46 | typedef delegate<UINT8 ()> byte_read_cb; | |
| 47 | typedef delegate<void (UINT8)> byte_write_cb; | |
| 27 | 48 | |
| 28 | // access to legacy token | |
| 29 | void *token() const { assert(m_token != NULL); return m_token; } | |
| 30 | protected: | |
| 31 | // device-level overrides | |
| 32 | virtual void device_config_complete(); | |
| 33 | virtual void device_start(); | |
| 34 | virtual void device_reset(); | |
| 35 | private: | |
| 36 | // internal state | |
| 37 | void *m_token; | |
| 38 | }; | |
| 49 | pc_fdc_interface(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : device_t(mconfig, type, name, tag, owner, clock) {} | |
| 39 | 50 | |
| 40 | extern const device_type UPD765A; | |
| 51 | virtual void setup_intrq_cb(line_cb cb) = 0; | |
| 52 | virtual void setup_drq_cb(line_cb cb) = 0; | |
| 41 | 53 | |
| 42 | class upd765b_device : public upd765a_device | |
| 43 | { | |
| 44 | public: | |
| 45 | upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 46 | protected: | |
| 47 | // device-level overrides | |
| 48 | virtual void device_start(); | |
| 49 | }; | |
| 54 | /* Note that the address map must cover and handle the whole 0-7 | |
| 55 | * range. The upd765, while conforming to the rest of the | |
| 56 | * interface, is not eligible as a result. | |
| 57 | */ | |
| 50 | 58 | |
| 51 | ||
| 59 | virtual DECLARE_ADDRESS_MAP(map, 8) = 0; | |
| 52 | 60 | |
| 53 | class smc37c78_device : public upd765a_device | |
| 54 | { | |
| 55 | public: | |
| 56 | smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 57 | protected: | |
| 58 | // device-level overrides | |
| 59 | virtual void device_start(); | |
| 61 | virtual UINT8 dma_r() = 0; | |
| 62 | virtual void dma_w(UINT8 data) = 0; | |
| 63 | ||
| 64 | virtual void tc_w(bool val) = 0; | |
| 65 | virtual UINT8 do_dir_r() = 0; | |
| 60 | 66 | }; |
| 61 | 67 | |
| 62 | extern const device_type SMC37C78; | |
| 68 | class upd765_family_device : public pc_fdc_interface { | |
| 69 | public: | |
| 70 | enum { MODE_AT, MODE_PS2, MODE_M30 }; | |
| 63 | 71 | |
| 64 | class upd72065_device : public upd765a_device | |
| 65 | { | |
| 66 | public: | |
| 67 | upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 72 | upd765_family_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 73 | ||
| 74 | void setup_intrq_cb(line_cb cb); | |
| 75 | void setup_drq_cb(line_cb cb); | |
| 76 | ||
| 77 | virtual DECLARE_ADDRESS_MAP(map, 8) = 0; | |
| 78 | ||
| 79 | DECLARE_READ8_MEMBER (sra_r); | |
| 80 | DECLARE_READ8_MEMBER (srb_r); | |
| 81 | DECLARE_READ8_MEMBER (dor_r); | |
| 82 | DECLARE_WRITE8_MEMBER(dor_w); | |
| 83 | DECLARE_READ8_MEMBER (tdr_r); | |
| 84 | DECLARE_WRITE8_MEMBER(tdr_w); | |
| 85 | DECLARE_READ8_MEMBER (msr_r); | |
| 86 | DECLARE_WRITE8_MEMBER(dsr_w); | |
| 87 | DECLARE_READ8_MEMBER (fifo_r); | |
| 88 | DECLARE_WRITE8_MEMBER(fifo_w); | |
| 89 | DECLARE_READ8_MEMBER (dir_r); | |
| 90 | DECLARE_WRITE8_MEMBER(ccr_w); | |
| 91 | ||
| 92 | virtual UINT8 do_dir_r(); | |
| 93 | ||
| 94 | UINT8 dma_r(); | |
| 95 | void dma_w(UINT8 data); | |
| 96 | ||
| 97 | // Same as the previous ones, but as memory-mappable members | |
| 98 | DECLARE_READ8_MEMBER(mdma_r); | |
| 99 | DECLARE_WRITE8_MEMBER(mdma_w); | |
| 100 | ||
| 101 | bool get_irq() const; | |
| 102 | bool get_drq() const; | |
| 103 | void tc_w(bool val); | |
| 104 | void ready_w(bool val); | |
| 105 | ||
| 106 | void set_rate(int rate); // rate in bps, to be used when the fdc is externally frequency-controlled | |
| 107 | ||
| 108 | void set_mode(int mode); | |
| 109 | void set_ready_line_connected(bool ready); | |
| 110 | void set_select_lines_connected(bool select); | |
| 111 | void set_floppy(floppy_image_device *image); | |
| 112 | ||
| 68 | 113 | protected: |
| 69 | // device-level overrides | |
| 70 | 114 | virtual void device_start(); |
| 71 | }; | |
| 115 | virtual void device_reset(); | |
| 116 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); | |
| 72 | 117 | |
| 73 | extern const device_type UPD72065; | |
| 118 | enum { | |
| 119 | TIMER_DRIVE_READY_POLLING = 4 | |
| 120 | }; | |
| 74 | 121 | |
| 122 | enum { | |
| 123 | PHASE_CMD, PHASE_EXEC, PHASE_RESULT | |
| 124 | }; | |
| 75 | 125 | |
| 76 | /*************************************************************************** | |
| 77 | TYPE DEFINITIONS | |
| 78 | ***************************************************************************/ | |
| 126 | enum { | |
| 127 | MSR_DB = 0x0f, | |
| 128 | MSR_CB = 0x10, | |
| 129 | MSR_EXM = 0x20, | |
| 130 | MSR_DIO = 0x40, | |
| 131 | MSR_RQM = 0x80, | |
| 79 | 132 | |
| 80 | /* RDY pin connected state */ | |
| 81 | enum UPD765_RDY_PIN | |
| 82 | { | |
| 83 | UPD765_RDY_PIN_NOT_CONNECTED = 0, | |
| 84 | UPD765_RDY_PIN_CONNECTED = 1 | |
| 85 | }; | |
| 133 | ST0_UNIT = 0x07, | |
| 134 | ST0_NR = 0x08, | |
| 135 | ST0_EC = 0x10, | |
| 136 | ST0_SE = 0x20, | |
| 137 | ST0_FAIL = 0x40, | |
| 138 | ST0_UNK = 0x80, | |
| 139 | ST0_ABRT = 0xc0, | |
| 86 | 140 | |
| 87 | #define UPD765_DAM_DELETED_DATA 0x0f8 | |
| 88 | #define UPD765_DAM_DATA 0x0fb | |
| 141 | ST1_MA = 0x01, | |
| 142 | ST1_NW = 0x02, | |
| 143 | ST1_ND = 0x04, | |
| 144 | ST1_OR = 0x10, | |
| 145 | ST1_DE = 0x20, | |
| 146 | ST1_EN = 0x80, | |
| 89 | 147 | |
| 90 | typedef device_t *(*upd765_get_image_func)(device_t *device, int floppy_index); | |
| 91 | #define UPD765_GET_IMAGE(name) device_t *name(device_t *device, int floppy_index ) | |
| 148 | ST2_MD = 0x01, | |
| 149 | ST2_BC = 0x02, | |
| 150 | ST2_SN = 0x04, | |
| 151 | ST2_SH = 0x08, | |
| 152 | ST2_WC = 0x10, | |
| 153 | ST2_DD = 0x20, | |
| 154 | ST2_CM = 0x40, | |
| 92 | 155 | |
| 156 | ST3_UNIT = 0x07, | |
| 157 | ST3_TS = 0x08, | |
| 158 | ST3_T0 = 0x10, | |
| 159 | ST3_RY = 0x20, | |
| 160 | ST3_WP = 0x40, | |
| 161 | ST3_FT = 0x80, | |
| 93 | 162 | |
| 94 | struct upd765_interface | |
| 95 | { | |
| 96 | /* interrupt issued */ | |
| 97 | devcb_write_line out_int_func; | |
| 163 | FIF_THR = 0x0f, | |
| 164 | FIF_POLL = 0x10, | |
| 165 | FIF_DIS = 0x20, | |
| 166 | FIF_EIS = 0x40, | |
| 98 | 167 | |
| 99 | /* dma data request */ | |
| 100 | devcb_write_line out_drq_func; | |
| 168 | SPEC_ND = 0x0001, | |
| 169 | }; | |
| 101 | 170 | |
| 102 | /* image lookup */ | |
| 103 | upd765_get_image_func get_image; | |
| 171 | ||
| 172 | enum { | |
| 173 | // General "doing nothing" state | |
| 174 | IDLE, | |
| 104 | 175 | |
| 105 | UPD765_RDY_PIN rdy_pin; | |
| 176 | // Main states | |
| 177 | RECALIBRATE, | |
| 178 | SEEK, | |
| 179 | READ_DATA, | |
| 180 | WRITE_DATA, | |
| 181 | READ_TRACK, | |
| 182 | FORMAT_TRACK, | |
| 183 | READ_ID, | |
| 106 | 184 | |
| 107 | const char *floppy_drive_tags[4]; | |
| 108 | }; | |
| 185 | // Sub-states | |
| 186 | COMMAND_DONE, | |
| 109 | 187 | |
| 188 | SEEK_MOVE, | |
| 189 | SEEK_WAIT_STEP_SIGNAL_TIME, | |
| 190 | SEEK_WAIT_STEP_SIGNAL_TIME_DONE, | |
| 191 | SEEK_WAIT_STEP_TIME, | |
| 192 | SEEK_WAIT_STEP_TIME_DONE, | |
| 193 | SEEK_DONE, | |
| 110 | 194 | |
| 111 | /*************************************************************************** | |
| 112 | FUNCTION PROTOTYPES | |
| 113 | ***************************************************************************/ | |
| 195 | HEAD_LOAD_DONE, | |
| 114 | 196 | |
| 115 | /* read of data register */ | |
| 116 | DECLARE_READ8_DEVICE_HANDLER(upd765_data_r); | |
| 117 | /* write to data register */ | |
| 118 | DECLARE_WRITE8_DEVICE_HANDLER(upd765_data_w); | |
| 119 | /* read of main status register */ | |
| 120 | DECLARE_READ8_DEVICE_HANDLER(upd765_status_r); | |
| 197 | WAIT_INDEX, | |
| 198 | WAIT_INDEX_DONE, | |
| 121 | 199 | |
| 122 | /* dma acknowledge with write */ | |
| 123 | DECLARE_WRITE8_DEVICE_HANDLER(upd765_dack_w); | |
| 124 | /* dma acknowledge with read */ | |
| 125 | DECLARE_READ8_DEVICE_HANDLER(upd765_dack_r); | |
| 200 | SCAN_ID, | |
| 201 | SCAN_ID_FAILED, | |
| 126 | 202 | |
| 127 | /* reset upd765 */ | |
| 128 | void upd765_reset(device_t *device, int); | |
| 203 | SECTOR_READ, | |
| 204 | SECTOR_WRITTEN, | |
| 205 | TC_DONE, | |
| 129 | 206 | |
| 130 | /* reset pin of upd765 */ | |
| 131 | WRITE_LINE_DEVICE_HANDLER(upd765_reset_w); | |
| 207 | TRACK_DONE, | |
| 132 | 208 | |
| 133 | /* set upd765 terminal count input state */ | |
| 134 | WRITE_LINE_DEVICE_HANDLER(upd765_tc_w); | |
| 209 | // Live states | |
| 210 | SEARCH_ADDRESS_MARK_HEADER, | |
| 211 | READ_HEADER_BLOCK_HEADER, | |
| 212 | READ_DATA_BLOCK_HEADER, | |
| 213 | READ_ID_BLOCK, | |
| 214 | SEARCH_ADDRESS_MARK_DATA, | |
| 215 | SEARCH_ADDRESS_MARK_DATA_FAILED, | |
| 216 | READ_SECTOR_DATA, | |
| 217 | READ_SECTOR_DATA_BYTE, | |
| 135 | 218 | |
| 136 | /* set upd765 ready input*/ | |
| 137 | WRITE_LINE_DEVICE_HANDLER(upd765_ready_w); | |
| 219 | WRITE_SECTOR_SKIP_GAP2, | |
| 220 | WRITE_SECTOR_SKIP_GAP2_BYTE, | |
| 221 | WRITE_SECTOR_DATA, | |
| 222 | WRITE_SECTOR_DATA_BYTE, | |
| 138 | 223 | |
| 139 | void upd765_idle(device_t *device); | |
| 140 | void upd765_set_bad(device_t *device, int state); | |
| 224 | WRITE_TRACK_PRE_SECTORS, | |
| 225 | WRITE_TRACK_PRE_SECTORS_BYTE, | |
| 141 | 226 | |
| 142 | READ_LINE_DEVICE_HANDLER( upd765_int_r ); | |
| 143 | READ_LINE_DEVICE_HANDLER( upd765_drq_r ); | |
| 227 | WRITE_TRACK_SECTOR, | |
| 228 | WRITE_TRACK_SECTOR_BYTE, | |
| 144 | 229 | |
| 145 | /*********************/ | |
| 146 | /* STATUS REGISTER 1 */ | |
| 230 | WRITE_TRACK_POST_SECTORS, | |
| 231 | WRITE_TRACK_POST_SECTORS_BYTE, | |
| 232 | }; | |
| 147 | 233 | |
| 148 | /* this is set if a TC signal was not received after the sector data was read */ | |
| 149 | #define UPD765_ST1_END_OF_CYLINDER (1<<7) | |
| 150 | /* this is set if the sector ID being searched for is not found */ | |
| 151 | #define UPD765_ST1_NO_DATA (1<<2) | |
| 152 | /* set if disc is write protected and a write/format operation was performed */ | |
| 153 | #define UPD765_ST1_NOT_WRITEABLE (1<<1) | |
| 234 | struct pll_t { | |
| 235 | attotime ctime, period, min_period, max_period, period_adjust_base, phase_adjust; | |
| 154 | 236 | |
| 155 | /*********************/ | |
| 156 | /* STATUS REGISTER 2 */ | |
| 237 | attotime write_start_time; | |
| 238 | attotime write_buffer[32]; | |
| 239 | int write_position; | |
| 240 | int freq_hist; | |
| 157 | 241 | |
| 158 | /* C parameter specified did not match C value read from disc */ | |
| 159 | #define UPD765_ST2_WRONG_CYLINDER (1<<4) | |
| 160 | /* C parameter specified did not match C value read from disc, and C read from disc was 0x0ff */ | |
| 161 | #define UPD765_ST2_BAD_CYLINDER (1<<1) | |
| 162 | /* this is set if the FDC encounters a Deleted Data Mark when executing a read data | |
| 163 | command, or FDC encounters a Data Mark when executing a read deleted data command */ | |
| 164 | #define UPD765_ST2_CONTROL_MARK (1<<6) | |
| 242 | void set_clock(attotime period); | |
| 243 | void reset(attotime when); | |
| 244 | int get_next_bit(attotime &tm, floppy_image_device *floppy, attotime limit); | |
| 245 | bool write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, attotime limit); | |
| 246 | void start_writing(attotime tm); | |
| 247 | void commit(floppy_image_device *floppy, attotime tm); | |
| 248 | void stop_writing(floppy_image_device *floppy, attotime tm); | |
| 249 | }; | |
| 165 | 250 | |
| 166 | /*************************************************************************** | |
| 167 | DEVICE CONFIGURATION MACROS | |
| 168 | ***************************************************************************/ | |
| 251 | struct floppy_info { | |
| 252 | emu_timer *tm; | |
| 253 | floppy_image_device *dev; | |
| 254 | int id; | |
| 255 | int main_state, sub_state; | |
| 256 | int dir, counter; | |
| 257 | UINT8 pcn; | |
| 258 | bool irq_seek, live, index, ready, irq_polled; | |
| 259 | }; | |
| 169 | 260 | |
| 170 | #define MCFG_UPD765A_ADD(_tag, _intrf) \ | |
| 171 | MCFG_DEVICE_ADD(_tag, UPD765A, 0) \ | |
| 172 | MCFG_DEVICE_CONFIG(_intrf) | |
| 261 | struct live_info { | |
| 262 | enum { PT_NONE, PT_CRC_1, PT_CRC_2 }; | |
| 173 | 263 | |
| 174 | #define MCFG_UPD765A_MODIFY(_tag, _intrf) \ | |
| 175 | MCFG_DEVICE_MODIFY(_tag) \ | |
| 176 | MCFG_DEVICE_CONFIG(_intrf) | |
| 264 | attotime tm; | |
| 265 | int state, next_state; | |
| 266 | floppy_info *fi; | |
| 267 | UINT16 shift_reg; | |
| 268 | UINT16 crc; | |
| 269 | int bit_counter, byte_counter, previous_type; | |
| 270 | bool data_separator_phase, data_bit_context; | |
| 271 | UINT8 data_reg; | |
| 272 | UINT8 idbuf[6]; | |
| 273 | pll_t pll; | |
| 274 | }; | |
| 177 | 275 | |
| 178 | #define MCFG_UPD765A_REMOVE(_tag) \ | |
| 179 | MCFG_DEVICE_REMOVE(_tag) | |
| 276 | static int rates[4]; | |
| 180 | 277 | |
| 181 | #define MCFG_UPD765B_ADD(_tag, _intrf) \ | |
| 182 | MCFG_DEVICE_ADD(_tag, UPD765B, 0) \ | |
| 183 | MCFG_DEVICE_CONFIG(_intrf) | |
| 278 | bool ready_connected, ready_polled, select_connected; | |
| 184 | 279 | |
| 185 | #define MCFG_UPD765B_MODIFY(_tag, _intrf) \ | |
| 186 | MCFG_DEVICE_MODIFY(_tag) \ | |
| 187 | MCFG_DEVICE_CONFIG(_intrf) | |
| 280 | bool external_ready; | |
| 188 | 281 | |
| 189 | #define MCFG_UPD765B_REMOVE(_tag) \ | |
| 190 | MCFG_DEVICE_REMOVE(_tag) | |
| 282 | int mode; | |
| 283 | int main_phase; | |
| 191 | 284 | |
| 192 | #define MCFG_SMC37C78_ADD(_tag, _intrf) \ | |
| 193 | MCFG_DEVICE_ADD(_tag, SMC37C78, 0) \ | |
| 194 | MCFG_DEVICE_CONFIG(_intrf) | |
| 285 | live_info cur_live, checkpoint_live; | |
| 286 | line_cb intrq_cb, drq_cb; | |
| 287 | bool cur_irq, data_irq, drq, internal_drq, tc, tc_done; | |
| 288 | floppy_info flopi[4]; | |
| 195 | 289 | |
| 196 | #define MCFG_SMC37C78_MODIFY(_tag, _intrf) \ | |
| 197 | MCFG_DEVICE_MODIFY(_tag) \ | |
| 198 | MCFG_DEVICE_CONFIG(_intrf) | |
| 290 | int fifo_pos, fifo_expected, command_pos, result_pos; | |
| 291 | bool fifo_write; | |
| 292 | UINT8 dor, dsr, msr, fifo[16], command[16], result[16]; | |
| 293 | UINT8 st0, st1, st2, st3; | |
| 294 | UINT8 fifocfg, dor_reset; | |
| 295 | UINT16 spec; | |
| 296 | int sector_size; | |
| 297 | int cur_rate; | |
| 199 | 298 | |
| 200 | #define MCFG_SMC37C78_REMOVE(_tag) \ | |
| 201 | MCFG_DEVICE_REMOVE(_tag) | |
| 299 | emu_timer *poll_timer; | |
| 202 | 300 | |
| 203 | #define MCFG_UPD72065_ADD(_tag, _intrf) \ | |
| 204 | MCFG_DEVICE_ADD(_tag, UPD72065, 0) \ | |
| 205 | MCFG_DEVICE_CONFIG(_intrf) | |
| 301 | static astring tts(attotime t); | |
| 302 | astring ttsn(); | |
| 206 | 303 | |
| 207 | #define MCFG_UPD72065_MODIFY(_tag, _intrf) \ | |
| 208 | MCFG_DEVICE_MODIFY(_tag) \ | |
| 209 | MCFG_DEVICE_CONFIG(_intrf) | |
| 304 | enum { | |
| 305 | C_CONFIGURE, | |
| 306 | C_FORMAT_TRACK, | |
| 307 | C_PERPENDICULAR, | |
| 308 | C_READ_DATA, | |
| 309 | C_READ_ID, | |
| 310 | C_READ_TRACK, | |
| 311 | C_RECALIBRATE, | |
| 312 | C_SEEK, | |
| 313 | C_SENSE_DRIVE_STATUS, | |
| 314 | C_SENSE_INTERRUPT_STATUS, | |
| 315 | C_SPECIFY, | |
| 316 | C_WRITE_DATA, | |
| 210 | 317 | |
| 211 | #define MCFG_UPD72065_REMOVE(_tag) \ | |
| 212 | MCFG_DEVICE_REMOVE(_tag) | |
| 318 | C_INVALID, | |
| 319 | C_INCOMPLETE, | |
| 320 | }; | |
| 213 | 321 | |
| 322 | void delay_cycles(emu_timer *tm, int cycles); | |
| 323 | void check_irq(); | |
| 324 | void fifo_expect(int size, bool write); | |
| 325 | void fifo_push(UINT8 data, bool internal); | |
| 326 | UINT8 fifo_pop(bool internal); | |
| 327 | void set_drq(bool state); | |
| 328 | bool get_ready(int fid); | |
| 214 | 329 | |
| 215 | #endif /* __UPD765_H__ */ | |
| 330 | void enable_transfer(); | |
| 331 | void disable_transfer(); | |
| 332 | int calc_sector_size(UINT8 size); | |
| 333 | ||
| 334 | void run_drive_ready_polling(); | |
| 335 | ||
| 336 | int check_command(); | |
| 337 | void start_command(int cmd); | |
| 338 | void command_end(floppy_info &fi, bool data_completion); | |
| 339 | ||
| 340 | void recalibrate_start(floppy_info &fi); | |
| 341 | void seek_start(floppy_info &fi); | |
| 342 | void seek_continue(floppy_info &fi); | |
| 343 | ||
| 344 | void read_data_start(floppy_info &fi); | |
| 345 | void read_data_continue(floppy_info &fi); | |
| 346 | ||
| 347 | void write_data_start(floppy_info &fi); | |
| 348 | void write_data_continue(floppy_info &fi); | |
| 349 | ||
| 350 | void read_track_start(floppy_info &fi); | |
| 351 | void read_track_continue(floppy_info &fi); | |
| 352 | ||
| 353 | void format_track_start(floppy_info &fi); | |
| 354 | void format_track_continue(floppy_info &fi); | |
| 355 | ||
| 356 | void read_id_start(floppy_info &fi); | |
| 357 | void read_id_continue(floppy_info &fi); | |
| 358 | ||
| 359 | void general_continue(floppy_info &fi); | |
| 360 | void index_callback(floppy_image_device *floppy, int state); | |
| 361 | bool sector_matches() const; | |
| 362 | ||
| 363 | void live_start(floppy_info &fi, int live_state); | |
| 364 | void live_abort(); | |
| 365 | void checkpoint(); | |
| 366 | void rollback(); | |
| 367 | void live_delay(int state); | |
| 368 | void live_sync(); | |
| 369 | void live_run(attotime limit = attotime::never); | |
| 370 | void live_write_raw(UINT16 raw); | |
| 371 | void live_write_mfm(UINT8 mfm); | |
| 372 | ||
| 373 | bool read_one_bit(attotime limit); | |
| 374 | bool write_one_bit(attotime limit); | |
| 375 | }; | |
| 376 | ||
| 377 | class upd765a_device : public upd765_family_device { | |
| 378 | public: | |
| 379 | upd765a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 380 | ||
| 381 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 382 | }; | |
| 383 | ||
| 384 | class upd765b_device : public upd765_family_device { | |
| 385 | public: | |
| 386 | upd765b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 387 | ||
| 388 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 389 | }; | |
| 390 | ||
| 391 | class i8272a_device : public upd765_family_device { | |
| 392 | public: | |
| 393 | i8272a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 394 | ||
| 395 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 396 | }; | |
| 397 | ||
| 398 | class smc37c78_device : public upd765_family_device { | |
| 399 | public: | |
| 400 | smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 401 | ||
| 402 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 403 | }; | |
| 404 | ||
| 405 | class upd72065_device : public upd765_family_device { | |
| 406 | public: | |
| 407 | upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 408 | ||
| 409 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 410 | }; | |
| 411 | ||
| 412 | class n82077aa_device : public upd765_family_device { | |
| 413 | public: | |
| 414 | n82077aa_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 415 | ||
| 416 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 417 | }; | |
| 418 | ||
| 419 | class pc_fdc_superio_device : public upd765_family_device { | |
| 420 | public: | |
| 421 | pc_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 422 | ||
| 423 | virtual DECLARE_ADDRESS_MAP(map, 8); | |
| 424 | }; | |
| 425 | ||
| 426 | extern const device_type UPD765A; | |
| 427 | extern const device_type UPD765B; | |
| 428 | extern const device_type I8272A; | |
| 429 | extern const device_type UPD72065; | |
| 430 | extern const device_type SMC37C78; | |
| 431 | extern const device_type N82077AA; | |
| 432 | extern const device_type PC_FDC_SUPERIO; | |
| 433 | ||
| 434 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 202 | 202 | |
| 203 | 203 | READ8_MEMBER(pc_state::pc_dma8237_fdc_dack_r) |
| 204 | 204 | { |
| 205 | return pc_fdc_ | |
| 205 | return machine().device<pc_fdc_interface>("fdc")->dma_r(); | |
| 206 | 206 | } |
| 207 | 207 | |
| 208 | 208 | |
| r18419 | r18420 | |
| 214 | 214 | |
| 215 | 215 | WRITE8_MEMBER(pc_state::pc_dma8237_fdc_dack_w) |
| 216 | 216 | { |
| 217 | | |
| 217 | machine().device<pc_fdc_interface>("fdc")->dma_w(data); | |
| 218 | 218 | } |
| 219 | 219 | |
| 220 | 220 | |
| r18419 | r18420 | |
| 232 | 232 | |
| 233 | 233 | WRITE_LINE_MEMBER(pc_state::pc_dma8237_out_eop) |
| 234 | 234 | { |
| 235 | pc_fdc_ | |
| 235 | machine().device<pc_fdc_interface>("fdc")->tc_w(state == ASSERT_LINE); | |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | 238 | static void set_dma_channel(running_machine &machine, int channel, int state) |
| r18419 | r18420 | |
| 1136 | 1136 | * |
| 1137 | 1137 | **********************************************************/ |
| 1138 | 1138 | |
| 1139 | ||
| 1139 | void pc_state::fdc_interrupt(bool state) | |
| 1140 | 1140 | { |
| 1141 | pc_state *st = machine.driver_data<pc_state>(); | |
| 1142 | if (st->m_pic8259) | |
| 1141 | if (m_pic8259) | |
| 1143 | 1142 | { |
| 1144 | pic8259_ir6_w( | |
| 1143 | pic8259_ir6_w(m_pic8259, state); | |
| 1145 | 1144 | } |
| 1146 | 1145 | } |
| 1147 | 1146 | |
| 1148 | ||
| 1147 | void pc_state::fdc_dma_drq(bool state) | |
| 1149 | 1148 | { |
| 1150 | pc_state *st = machine.driver_data<pc_state>(); | |
| 1151 | i8237_dreq2_w( st->m_dma8237, state); | |
| 1149 | i8237_dreq2_w( m_dma8237, state); | |
| 1152 | 1150 | } |
| 1153 | 1151 | |
| 1154 | static device_t * pc_get_device(running_machine &machine ) | |
| 1155 | { | |
| 1156 | return machine.device("upd765"); | |
| 1157 | } | |
| 1158 | ||
| 1159 | static const struct pc_fdc_interface fdc_interface_nc = | |
| 1160 | { | |
| 1161 | pc_fdc_interrupt, | |
| 1162 | pc_fdc_dma_drq, | |
| 1163 | NULL, | |
| 1164 | pc_get_device | |
| 1165 | }; | |
| 1166 | ||
| 1167 | ||
| 1168 | static const struct pc_fdc_interface pcjr_fdc_interface_nc = | |
| 1169 | { | |
| 1170 | pc_fdc_interrupt, | |
| 1171 | NULL, | |
| 1172 | NULL, | |
| 1173 | pc_get_device | |
| 1174 | }; | |
| 1175 | ||
| 1176 | ||
| 1177 | 1152 | static void pc_set_irq_line(running_machine &machine,int irq, int state) |
| 1178 | 1153 | { |
| 1179 | 1154 | pc_state *st = machine.driver_data<pc_state>(); |
| r18419 | r18420 | |
| 1396 | 1371 | m_pic8259 = machine().device("pic8259"); |
| 1397 | 1372 | m_dma8237 = machine().device("dma8237"); |
| 1398 | 1373 | m_pit8253 = machine().device("pit8253"); |
| 1399 | pc_fdc_init( machine(), &fdc_interface_nc ); | |
| 1374 | ||
| 1375 | pc_fdc_interface *fdc = machine().device<pc_fdc_interface>("fdc"); | |
| 1376 | fdc->setup_intrq_cb(pc_fdc_interface::line_cb(FUNC(pc_state::fdc_interrupt), this)); | |
| 1377 | fdc->setup_drq_cb(pc_fdc_interface::line_cb(FUNC(pc_state::fdc_dma_drq), this)); | |
| 1400 | 1378 | } |
| 1401 | 1379 | |
| 1402 | 1380 | |
| r18419 | r18420 | |
| 1450 | 1428 | |
| 1451 | 1429 | MACHINE_START_MEMBER(pc_state,pcjr) |
| 1452 | 1430 | { |
| 1453 | pc_fdc_init( machine(), &pcjr_fdc_interface_nc ); | |
| 1454 | pcjr_keyb.keyb_signal_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc_state::pcjr_keyb_signal_callback),this)); | |
| 1431 | pc_fdc_interface *fdc = machine().device<pc_fdc_interface>("fdc"); | |
| 1432 | fdc->setup_intrq_cb(pc_fdc_interface::line_cb(FUNC(pc_state::fdc_interrupt), this)); | |
| 1455 | 1433 | pc_int_delay_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc_state::pcjr_delayed_pic8259_irq),this)); |
| 1456 | 1434 | m_maincpu = machine().device<cpu_device>("maincpu" ); |
| 1457 | 1435 | m_maincpu->set_irq_acknowledge_callback(pc_irq_callback); |
| r18419 | r18420 | |
|---|---|---|
| 27 | 27 | |
| 28 | 28 | #include "includes/hec2hrp.h" |
| 29 | 29 | |
| 30 | /* Disquette timer*/ | |
| 31 | static TIMER_CALLBACK( Callback_DMA_irq ); | |
| 32 | static TIMER_CALLBACK( Callback_INT_irq ); | |
| 33 | ||
| 34 | 30 | /* Callback uPD request */ |
| 35 | //UPD765_DMA_REQUEST( hector_disc2_fdc_dma_irq ); | |
| 36 | static WRITE_LINE_DEVICE_HANDLER( disc2_fdc_interrupt ); | |
| 37 | static WRITE_LINE_DEVICE_HANDLER( hector_disc2_fdc_dma_irq ); | |
| 38 | 31 | |
| 39 | 32 | /* How uPD765 works: |
| 40 | 33 | * First we send at uPD the string of command (p.e. 9 bytes for read starting by 0x46) on port 60h |
| r18419 | r18420 | |
| 48 | 41 | * At this point the Z80 can read the RESULT in port 61h |
| 49 | 42 | */ |
| 50 | 43 | |
| 51 | // Define the hardware of the disk | |
| 52 | const floppy_interface hector_disc2_floppy_interface = | |
| 53 | { | |
| 54 | DEVCB_NULL, | |
| 55 | DEVCB_NULL, | |
| 56 | DEVCB_NULL, | |
| 57 | DEVCB_NULL, | |
| 58 | DEVCB_NULL, | |
| 59 | FLOPPY_STANDARD_5_25_DSHD, | |
| 60 | LEGACY_FLOPPY_OPTIONS_NAME(hector_disc2), | |
| 61 | NULL, | |
| 62 | NULL | |
| 63 | }; | |
| 64 | ||
| 65 | 44 | /*****************************************************************************/ |
| 66 | /****** Management of the uPD765 for interface with floppy images************/ | |
| 67 | /*****************************************************************************/ | |
| 68 | /* Hector Disc II uPD765 interface use interrupts and DMA! */ | |
| 69 | const upd765_interface hector_disc2_upd765_interface = | |
| 70 | { | |
| 71 | DEVCB_LINE(disc2_fdc_interrupt), | |
| 72 | DEVCB_LINE(hector_disc2_fdc_dma_irq), | |
| 73 | NULL, | |
| 74 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 75 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 76 | }; | |
| 77 | ||
| 78 | /*****************************************************************************/ | |
| 79 | 45 | /**** Management of the interrupts (NMI and INT)between uPD765 and Z80 ******/ |
| 80 | 46 | /*****************************************************************************/ |
| 81 | static void valid_interrupt( running_machine &machine) | |
| 82 | { | |
| 83 | hec2hrp_state *state = machine.driver_data<hec2hrp_state>(); | |
| 84 | /* Called at each rising state of NMI or RNMI ! */ | |
| 85 | ||
| 86 | /* Take NMI only if RNMI ok*/ | |
| 87 | if ((state->m_hector_disc2_RNMI==1) && (state->m_NMI_current_state==1)) | |
| 88 | { | |
| 89 | machine.device("disc2cpu")->execute().set_input_line(INPUT_LINE_NMI, CLEAR_LINE); // Clear NMI... | |
| 90 | state->m_DMA_timer->adjust(attotime::from_usec(6) );//a little time to let the Z80 terminate he's previous job ! | |
| 91 | state->m_NMI_current_state=0; | |
| 92 | } | |
| 93 | } | |
| 94 | ||
| 95 | 47 | void hector_disc2_init( running_machine &machine) |
| 96 | 48 | { |
| 97 | 49 | hec2hrp_state *state = machine.driver_data<hec2hrp_state>(); |
| 98 | state->m_DMA_timer = machine.scheduler().timer_alloc(FUNC(Callback_DMA_irq)); | |
| 99 | state->m_INT_timer = machine.scheduler().timer_alloc(FUNC(Callback_INT_irq)); | |
| 50 | upd765a_device *fdc = machine.device<upd765a_device>("upd765"); | |
| 51 | fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(hec2hrp_state::disc2_fdc_interrupt), state)); | |
| 52 | fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(hec2hrp_state::disc2_fdc_dma_irq), state)); | |
| 100 | 53 | } |
| 101 | 54 | |
| 102 | static TIMER_CALLBACK( Callback_DMA_irq ) | |
| 55 | /* upd765 INT is connected to interrupt of Z80 within a RNMI hardware authorization */ | |
| 56 | void hec2hrp_state::disc2_fdc_interrupt(bool state) | |
| 103 | 57 | { |
| 104 | hec2hrp_state *state = machine.driver_data<hec2hrp_state>(); | |
| 105 | /* To generate the NMI signal (late) when uPD DMA request*/ | |
| 106 | machine.device("disc2cpu")->execute().set_input_line(INPUT_LINE_NMI, ASSERT_LINE); //NMI... | |
| 107 | state->m_hector_nb_cde =0; // clear the cde length | |
| 58 | m_IRQ_current_state = state; | |
| 59 | machine().device("disc2cpu")->execute().set_input_line(INPUT_LINE_IRQ0, state && m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE); | |
| 108 | 60 | } |
| 109 | 61 | |
| 110 | static TIMER_CALLBACK( Callback_INT_irq ) | |
| 62 | /* upd765 DRQ is connected to NMI of Z80 within a RNMI hardware authorization */ | |
| 63 | void hec2hrp_state::disc2_fdc_dma_irq(bool state) | |
| 111 | 64 | { |
| 112 | /* To generate the INT signal (late) when uPD DMA request*/ | |
| 113 | /*device->*/machine.device("disc2cpu")->execute().set_input_line(INPUT_LINE_IRQ0, ASSERT_LINE); | |
| 65 | m_NMI_current_state = state; | |
| 66 | machine().device("disc2cpu")->execute().set_input_line(INPUT_LINE_NMI, state && m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE); | |
| 114 | 67 | } |
| 115 | 68 | |
| 116 | /* upd765 INT is connected to interrupt of Z80 within a RNMI hardware authorization*/ | |
| 117 | static WRITE_LINE_DEVICE_HANDLER( disc2_fdc_interrupt ) | |
| 118 | { | |
| 119 | hec2hrp_state *drvstate = device->machine().driver_data<hec2hrp_state>(); | |
| 120 | device->machine().device("disc2cpu")->execute().set_input_line(INPUT_LINE_IRQ0, CLEAR_LINE); | |
| 121 | if (state) | |
| 122 | drvstate->m_INT_timer->adjust(attotime::from_usec(500) );//a little time to let the Z80 terminate he's previous job ! | |
| 123 | } | |
| 124 | ||
| 125 | static WRITE_LINE_DEVICE_HANDLER( hector_disc2_fdc_dma_irq ) | |
| 126 | { | |
| 127 | hec2hrp_state *drvstate = device->machine().driver_data<hec2hrp_state>(); | |
| 128 | /* upd765 DRQ is connected to NMI of Z80 within a RNMI hardware authorization*/ | |
| 129 | /* Here the most difficult on this machine : | |
| 130 | The DMA request come with the uPD765 "soft" immediately, | |
| 131 | against the true hard uPD765. In the real life, the uPD had | |
| 132 | to seach for the sector before ! | |
| 133 | So, we had to memorize the signal (the DMA is a pulse) | |
| 134 | until disc2's Z80 is ready to take the NMI interupt (when | |
| 135 | he had set the RNMI authorization) ! */ | |
| 136 | ||
| 137 | if (state==1) | |
| 138 | drvstate->m_NMI_current_state = state; | |
| 139 | valid_interrupt(device->machine()); | |
| 140 | } | |
| 141 | ||
| 142 | 69 | // RESET the disc2 Unit ! |
| 143 | 70 | void hector_disc2_reset(running_machine &machine) |
| 144 | 71 | { |
| 145 | 72 | hec2hrp_state *state = machine.driver_data<hec2hrp_state>(); |
| 146 | 73 | // Initialization Disc2 unit |
| 147 | machine.device("disc2cpu" )->execute().set_input_line(INPUT_LINE_RESET, PULSE_LINE); | |
| 148 | //switch ON and OFF the reset line uPD | |
| 149 | upd765_reset_w(machine.device("upd765"), 1); | |
| 150 | upd765_reset_w(machine.device("upd765"), 0); | |
| 74 | machine.device("disc2cpu")->execute().set_input_line(INPUT_LINE_RESET, PULSE_LINE); | |
| 75 | machine.device<upd765a_device>("upd765")->reset(); | |
| 151 | 76 | // Select ROM memory to cold restart |
| 152 | 77 | state->membank("bank3")->set_entry(DISCII_BANK_ROM); |
| 153 | 78 | |
| r18419 | r18420 | |
| 157 | 82 | state->m_hector_disc2_data_read=0; /* Data send by Hector to Disc 2 when PC2=true */ |
| 158 | 83 | state->m_hector_disc2_data_write=0; /* Data send by Disc 2 to Hector when Write Port I/O 40 */ |
| 159 | 84 | state->m_hector_disc2_RNMI = 0; /* State of I/O 50 D5 = authorization for INT / NMI */ |
| 85 | state->m_IRQ_current_state=0; /* Clear the IRQ active request */ | |
| 160 | 86 | state->m_NMI_current_state=0; /* Clear the DMA active request */ |
| 161 | 87 | } |
| 162 | 88 | |
| r18419 | r18420 | |
| 219 | 145 | WRITE8_HANDLER( hector_disc2_io50_port_w) /* I/O Port to the stuff of Disc2*/ |
| 220 | 146 | { |
| 221 | 147 | hec2hrp_state *state = space.machine().driver_data<hec2hrp_state>(); |
| 222 | device | |
| 148 | upd765a_device *fdc = space.machine().device<upd765a_device>("upd765"); | |
| 223 | 149 | |
| 224 | 150 | /* FDC Motor Control - Bit 0/1 defines the state of the FDD 0/1 motor */ |
| 225 | floppy_mon_w(floppy_get_device(space.machine(), 0), BIT(data, 0)); // Moteur floppy A: | |
| 226 | floppy_mon_w(floppy_get_device(space.machine(), 1), BIT(data, 1)); // Moteur floppy B: | |
| 227 | floppy_drive_set_ready_state(floppy_get_device(space.machine(), 0), FLOPPY_DRIVE_READY,!BIT(data, 0)); | |
| 228 | floppy_drive_set_ready_state(floppy_get_device(space.machine(), 1), FLOPPY_DRIVE_READY,!BIT(data, 1)); | |
| 151 | space.machine().device<floppy_connector>("upd765:0")->get_device()->mon_w(BIT(data, 0)); // Moteur floppy A: | |
| 152 | space.machine().device<floppy_connector>("upd765:1")->get_device()->mon_w(BIT(data, 1)); // Moteur floppy B: | |
| 229 | 153 | |
| 230 | 154 | /* Write bit TC uPD765 on D4 of port I/O 50 */ |
| 231 | | |
| 155 | fdc->tc_w(BIT(data, 4)); | |
| 232 | 156 | |
| 233 | 157 | |
| 234 | 158 | /* Authorization interrupt and NMI with RNMI signal*/ |
| 235 | 159 | state->m_hector_disc2_RNMI = BIT(data, 5); |
| 236 | ||
| 237 | /* if RNMI is OK, try to lauch an NMI*/ | |
| 238 | if (state->m_hector_disc2_RNMI) | |
| 239 | valid_interrupt(space.machine()); | |
| 160 | space.machine().device("disc2cpu")->execute().set_input_line(INPUT_LINE_IRQ0, state->m_IRQ_current_state && state->m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE); | |
| 161 | space.machine().device("disc2cpu")->execute().set_input_line(INPUT_LINE_NMI, state->m_NMI_current_state && state->m_hector_disc2_RNMI ? ASSERT_LINE : CLEAR_LINE); | |
| 240 | 162 | } |
| 241 | ||
| 242 | //Here we must take the exchange with uPD against AM_DEVREADWRITE | |
| 243 | // Because we had to add D6 = 1 when write is done with 0x28 in ST0 back | |
| 244 | ||
| 245 | // AM_RANGE(0x061,0x061) AM_DEVREADWRITE("upd765",upd765_data_r,upd765_data_w) | |
| 246 | READ8_HANDLER( hector_disc2_io61_port_r) | |
| 247 | { | |
| 248 | hec2hrp_state *state = space.machine().driver_data<hec2hrp_state>(); | |
| 249 | UINT8 data; | |
| 250 | device_t *fdc = space.machine().device("upd765"); | |
| 251 | data = upd765_data_r(fdc,space, 0); //Get the result | |
| 252 | ||
| 253 | // if ST0 == 0x28 (drive A:) or 0x29 (drive B:) => add 0x40 | |
| 254 | // and correct the ST1 and ST2 (patch) | |
| 255 | if ((state->m_hector_flag_result == 3) & ((data==0x28) | (data==0x29)) ) // are we in the problem? | |
| 256 | { | |
| 257 | data=data + 0x40; | |
| 258 | state->m_hector_flag_result--; | |
| 259 | } | |
| 260 | // Nothing to do in over case! | |
| 261 | if (state->m_hector_flag_result == 3) | |
| 262 | state->m_hector_flag_result = 0; | |
| 263 | ||
| 264 | if ((state->m_hector_flag_result == 2) & (data==0x00) ) | |
| 265 | { | |
| 266 | data=/*data +*/ 0x04; | |
| 267 | state->m_hector_flag_result--; | |
| 268 | } | |
| 269 | if ((state->m_hector_flag_result == 1) & (data==0x00) ) | |
| 270 | { | |
| 271 | data=/*data + */0x10; | |
| 272 | state->m_hector_flag_result=0; // End ! | |
| 273 | } | |
| 274 | #ifdef hector_trace | |
| 275 | if (state->m_print==1) | |
| 276 | printf(" _%x",data); | |
| 277 | #endif | |
| 278 | state->m_hector_nb_cde =0; // clear the cde length | |
| 279 | return data; | |
| 280 | } | |
| 281 | WRITE8_HANDLER( hector_disc2_io61_port_w) | |
| 282 | { | |
| 283 | hec2hrp_state *state = space.machine().driver_data<hec2hrp_state>(); | |
| 284 | /* Data useful to patch the RESULT in case of write command */ | |
| 285 | state->m_hector_cmd[9]=state->m_hector_cmd[8]; //hector_cmd_8 = Cde number when state->m_hector_nb_cde = 9 | |
| 286 | state->m_hector_cmd[8]=state->m_hector_cmd[7]; //hector_cmd_7 = Drive | |
| 287 | state->m_hector_cmd[7]=state->m_hector_cmd[6]; //hector_cmd_6 = C | |
| 288 | state->m_hector_cmd[6]=state->m_hector_cmd[5]; //hector_cmd_5 = H | |
| 289 | state->m_hector_cmd[5]=state->m_hector_cmd[4]; //hector_cmd_4 = R | |
| 290 | state->m_hector_cmd[4]=state->m_hector_cmd[3]; //hector_cmd_3 = N | |
| 291 | state->m_hector_cmd[3]=state->m_hector_cmd[2]; //hector_cmd_2 = EOT | |
| 292 | state->m_hector_cmd[2]=state->m_hector_cmd[1]; //hector_cmd_1 = GPL | |
| 293 | state->m_hector_cmd[1]=state->m_hector_cmd[0]; //hector_cmd_0 = DTL | |
| 294 | state->m_hector_cmd[0] = data; | |
| 295 | // Increase the length cde! | |
| 296 | state->m_hector_nb_cde++; | |
| 297 | ||
| 298 | // check if current commande is write cmde. | |
| 299 | if (((state->m_hector_cmd[8] & 0x1f)== 0x05) & (state->m_hector_nb_cde==9) ) /*Detect wrtie commande*/ | |
| 300 | state->m_hector_flag_result = 3; // here we are! | |
| 301 | #ifdef hector_trace | |
| 302 | if (state->m_hector_nb_cde==6 ) /*Detect 1 octet command*/ | |
| 303 | { | |
| 304 | printf("\n commande = %x, %x, %x, %x, %x, %x Result = ", state->m_hector_cmd[5], state->m_hector_cmd[4], state->m_hector_cmd[3], state->m_hector_cmd[2], state->m_hector_cmd[1], data ); | |
| 305 | state->m_print=1; | |
| 306 | } | |
| 307 | else | |
| 308 | state->m_print=0; | |
| 309 | #endif | |
| 310 | ||
| 311 | device_t *fdc = space.machine().device("upd765"); | |
| 312 | upd765_data_w(fdc,space, 0, data); | |
| 313 | } | |
| 314 | ||
| 315 | // AM_RANGE(0x070,0x07f) AM_DEVREADWRITE("upd765",upd765_dack_r,upd765_dack_w) | |
| 316 | READ8_HANDLER( hector_disc2_io70_port_r) // Gestion du DMA | |
| 317 | { | |
| 318 | UINT8 data; | |
| 319 | device_t *fdc = space.machine().device("upd765"); | |
| 320 | data = upd765_dack_r(fdc,space, 0); | |
| 321 | return data; | |
| 322 | } | |
| 323 | WRITE8_HANDLER( hector_disc2_io70_port_w) | |
| 324 | { | |
| 325 | device_t *fdc = space.machine().device("upd765"); | |
| 326 | upd765_dack_w(fdc,space, 0, data); | |
| 327 | } |
| r18419 | r18420 | |
|---|---|---|
| 96 | 96 | #include "video/cirrus.h" |
| 97 | 97 | #include "cpu/powerpc/ppc.h" |
| 98 | 98 | #include "machine/ins8250.h" |
| 99 | #include "machine/p | |
| 99 | #include "machine/upd765.h" | |
| 100 | 100 | #include "machine/mc146818.h" |
| 101 | 101 | #include "machine/pic8259.h" |
| 102 | 102 | #include "machine/pit8253.h" |
| r18419 | r18420 | |
| 451 | 451 | * |
| 452 | 452 | *************************************/ |
| 453 | 453 | |
| 454 | ||
| 454 | void bebox_state::fdc_interrupt(bool state) | |
| 455 | 455 | { |
| 456 | bebox_state *drvstate = machine.driver_data<bebox_state>(); | |
| 457 | bebox_set_irq_bit(machine, 13, state); | |
| 458 | if ( drvstate->m_devices.pic8259_master ) { | |
| 459 | pic8259_ir6_w(drvstate->m_devices.pic8259_master, state); | |
| 456 | bebox_set_irq_bit(machine(), 13, state); | |
| 457 | if ( m_devices.pic8259_master ) { | |
| 458 | pic8259_ir6_w(m_devices.pic8259_master, state); | |
| 460 | 459 | } |
| 461 | 460 | } |
| 462 | 461 | |
| 463 | 462 | |
| 464 | ||
| 463 | void bebox_state::fdc_dma_drq(bool state) | |
| 465 | 464 | { |
| 466 | bebox_state *drvstate = machine.driver_data<bebox_state>(); | |
| 467 | if ( drvstate->m_devices.dma8237_1 ) { | |
| 468 | i8237_dreq2_w(drvstate->m_devices.dma8237_1, state); | |
| 465 | if ( m_devices.dma8237_1 ) { | |
| 466 | i8237_dreq2_w(m_devices.dma8237_1, state); | |
| 469 | 467 | } |
| 470 | 468 | } |
| 471 | 469 | |
| 472 | ||
| 473 | static device_t *bebox_fdc_get_image(running_machine &machine, int floppy_index) | |
| 474 | { | |
| 475 | /* the BeBox boot ROM seems to query for floppy #1 when it should be | |
| 476 | * querying for floppy #0 */ | |
| 477 | return floppy_get_device(machine, 0); | |
| 478 | } | |
| 479 | ||
| 480 | static device_t * bebox_get_device(running_machine &machine ) | |
| 481 | { | |
| 482 | return machine.device("smc37c78"); | |
| 483 | } | |
| 484 | ||
| 485 | ||
| 486 | static const struct pc_fdc_interface bebox_fdc_interface = | |
| 487 | { | |
| 488 | bebox_fdc_interrupt, | |
| 489 | bebox_fdc_dma_drq, | |
| 490 | bebox_fdc_get_image, | |
| 491 | bebox_get_device | |
| 492 | }; | |
| 493 | ||
| 494 | ||
| 495 | 470 | /************************************* |
| 496 | 471 | * |
| 497 | 472 | * 8259 PIC |
| r18419 | r18420 | |
| 563 | 538 | |
| 564 | 539 | READ64_MEMBER(bebox_state::bebox_800003F0_r ) |
| 565 | 540 | { |
| 566 | UINT64 result = | |
| 541 | UINT64 result = 0; | |
| 567 | 542 | |
| 568 | 543 | if (((mem_mask >> 8) & 0xFF) == 0) |
| 569 | 544 | { |
| 570 | result &= ~(0xFF << 8); | |
| 571 | result |= ide_controller_r(ide_device(space.machine()), 0x3F6, 1) << 8; | |
| 545 | result |= ide_controller_r(space.machine().device("ide"), 0x3F6, 1) << 8; | |
| 572 | 546 | } |
| 573 | ||
| 574 | if (((mem_mask >> 0) & 0xFF) == 0) | |
| 575 | { | |
| 576 | result &= ~(0xFF << 0); | |
| 577 | result |= ide_controller_r(ide_device(space.machine()), 0x3F7, 1) << 0; | |
| 578 | } | |
| 579 | 547 | return result; |
| 580 | 548 | } |
| 581 | 549 | |
| 582 | 550 | |
| 583 | 551 | WRITE64_MEMBER(bebox_state::bebox_800003F0_w ) |
| 584 | 552 | { |
| 585 | write64be_with_write8_handler(pc_fdc_w, space, offset, data, mem_mask | 0xFFFF); | |
| 586 | ||
| 587 | 553 | if (((mem_mask >> 8) & 0xFF) == 0) |
| 588 | ide_controller_w(ide_device(space.machine()), 0x3F6, 1, (data >> 8) & 0xFF); | |
| 589 | ||
| 590 | if (((mem_mask >> 0) & 0xFF) == 0) | |
| 591 | ide_controller_w(ide_device(space.machine()), 0x3F7, 1, (data >> 0) & 0xFF); | |
| 554 | ide_controller_w(space.machine().device("ide"), 0x3F6, 1, (data >> 8) & 0xFF); | |
| 592 | 555 | } |
| 593 | 556 | |
| 594 | 557 | |
| r18419 | r18420 | |
| 768 | 731 | |
| 769 | 732 | |
| 770 | 733 | READ8_MEMBER(bebox_state::bebox_dma8237_fdc_dack_r){ |
| 771 | return | |
| 734 | return machine().device<smc37c78_device>("smc37c78")->dma_r(); | |
| 772 | 735 | } |
| 773 | 736 | |
| 774 | 737 | |
| 775 | 738 | WRITE8_MEMBER(bebox_state::bebox_dma8237_fdc_dack_w){ |
| 776 | | |
| 739 | machine().device<smc37c78_device>("smc37c78")->dma_w(data); | |
| 777 | 740 | } |
| 778 | 741 | |
| 779 | 742 | |
| 780 | 743 | WRITE_LINE_MEMBER(bebox_state::bebox_dma8237_out_eop){ |
| 781 | | |
| 744 | machine().device<smc37c78_device>("smc37c78")->tc_w(state); | |
| 782 | 745 | } |
| 783 | 746 | |
| 784 | 747 | static void set_dma_channel(running_machine &machine, int channel, int state) |
| r18419 | r18420 | |
| 1067 | 1030 | |
| 1068 | 1031 | void bebox_state::machine_start() |
| 1069 | 1032 | { |
| 1070 | pc_fdc_init(machine(), &bebox_fdc_interface); | |
| 1033 | smc37c78_device *fdc = machine().device<smc37c78_device>("smc37c78"); | |
| 1034 | fdc->setup_intrq_cb(smc37c78_device::line_cb(FUNC(bebox_state::fdc_interrupt), this)); | |
| 1035 | fdc->setup_drq_cb(smc37c78_device::line_cb(FUNC(bebox_state::fdc_dma_drq), this)); | |
| 1071 | 1036 | } |
| 1072 | 1037 | |
| 1073 | 1038 | DRIVER_INIT_MEMBER(bebox_state,bebox) |
| r18419 | r18420 | |
|---|---|---|
| 150 | 150 | void install_device(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_device_func rhandler, const char* rhandler_name, write8_device_func whandler, const char *whandler_name); |
| 151 | 151 | void install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_delegate rhandler, write8_delegate whandler); |
| 152 | 152 | void install_device(offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_space_func rhandler, const char* rhandler_name, write8_space_func whandler, const char *whandler_name); |
| 153 | template<typename T> void install_device(offs_t addrstart, offs_t addrend, T &device, void (T::*map)(address_map &map, device_t &device), int bits = 8, UINT64 unitmask = 0xffffffffffffffff) { | |
| 154 | m_maincpu->space(AS_IO).install_device(addrstart, addrend, device, map, bits, unitmask); | |
| 155 | } | |
| 153 | 156 | void install_bank(offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, UINT8 *data); |
| 154 | 157 | void install_rom(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, const char *tag, const char *region); |
| 155 | 158 | void install_memory(device_t *dev, offs_t start, offs_t end, offs_t mask, offs_t mirror, read8_device_func rhandler, const char* rhandler_name, write8_device_func whandler, const char *whandler_name); |
| r18419 | r18420 | |
|---|---|---|
| 6 | 6 | |
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "machine/isa_fdc.h" |
| 9 | #include "machine/ | |
| 9 | #include "machine/pc_fdc.h" | |
| 10 | 10 | #include "imagedev/flopdrv.h" |
| 11 | 11 | #include "formats/pc_dsk.h" |
| 12 | 12 | #include "machine/idectrl.h" |
| 13 | #include "formats/pc_dsk.h" | |
| 14 | #include "formats/mfi_dsk.h" | |
| 13 | 15 | |
| 14 | static DECLARE_READ8_DEVICE_HANDLER ( pc_fdc_r ); | |
| 15 | static DECLARE_WRITE8_DEVICE_HANDLER ( pc_fdc_w ); | |
| 16 | 16 | |
| 17 | /* if not 1, DACK and TC inputs to FDC are disabled, and DRQ and IRQ are held | |
| 18 | * at high impedance i.e they are not affective */ | |
| 19 | #define PC_FDC_FLAGS_DOR_DMA_ENABLED (1<<3) | |
| 20 | #define PC_FDC_FLAGS_DOR_FDC_ENABLED (1<<2) | |
| 21 | #define PC_FDC_FLAGS_DOR_MOTOR_ON (1<<4) | |
| 22 | ||
| 23 | #define LOG_FDC 0 | |
| 24 | ||
| 25 | static const floppy_interface ibmpc_floppy_interface = | |
| 26 | { | |
| 27 | DEVCB_NULL, | |
| 28 | DEVCB_NULL, | |
| 29 | DEVCB_NULL, | |
| 30 | DEVCB_NULL, | |
| 31 | DEVCB_NULL, | |
| 32 | FLOPPY_STANDARD_5_25_DSHD, | |
| 33 | LEGACY_FLOPPY_OPTIONS_NAME(pc), | |
| 34 | "floppy_5_25", | |
| 17 | static const floppy_format_type pc_floppy_formats[] = { | |
| 18 | FLOPPY_PC_FORMAT, | |
| 19 | FLOPPY_MFI_FORMAT, | |
| 35 | 20 | NULL |
| 36 | 21 | }; |
| 37 | 22 | |
| 38 | static WRITE_LINE_DEVICE_HANDLER( pc_fdc_hw_interrupt ); | |
| 39 | static WRITE_LINE_DEVICE_HANDLER( pc_fdc_hw_dma_drq ); | |
| 40 | static UPD765_GET_IMAGE ( pc_fdc_get_image ); | |
| 23 | static SLOT_INTERFACE_START( pc_dd_floppies ) | |
| 24 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 25 | SLOT_INTERFACE( "35dd", FLOPPY_35_DD ) | |
| 26 | SLOT_INTERFACE_END | |
| 41 | 27 | |
| 42 | const upd765_interface pc_fdc_upd765_not_connected_interface = | |
| 43 | { | |
| 44 | DEVCB_LINE(pc_fdc_hw_interrupt), | |
| 45 | DEVCB_LINE(pc_fdc_hw_dma_drq), | |
| 46 | pc_fdc_get_image, | |
| 47 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 48 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 49 | }; | |
| 28 | static SLOT_INTERFACE_START( pc_hd_floppies ) | |
| 29 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 30 | SLOT_INTERFACE( "35hd", FLOPPY_35_HD ) | |
| 31 | SLOT_INTERFACE_END | |
| 50 | 32 | |
| 51 | static MACHINE_CONFIG_FRAGMENT( fdc_config ) | |
| 52 | MCFG_UPD765A_ADD("upd765", pc_fdc_upd765_not_connected_interface) | |
| 33 | static MACHINE_CONFIG_FRAGMENT( cfg_xt ) | |
| 34 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 35 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", pc_dd_floppies, "525dd", 0, pc_floppy_formats) | |
| 36 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", pc_dd_floppies, "525dd", 0, pc_floppy_formats) | |
| 37 | MACHINE_CONFIG_END | |
| 53 | 38 | |
| 54 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 39 | static MACHINE_CONFIG_FRAGMENT( cfg_at ) | |
| 40 | MCFG_PC_FDC_AT_ADD("fdc") | |
| 41 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 42 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 55 | 43 | MACHINE_CONFIG_END |
| 56 | 44 | |
| 57 | //************************************************************************** | |
| 58 | // GLOBAL VARIABLES | |
| 59 | //************************************************************************** | |
| 45 | static MACHINE_CONFIG_FRAGMENT( cfg_smc ) | |
| 46 | MCFG_SMC37C78_ADD("fdc") | |
| 47 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 48 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 49 | MACHINE_CONFIG_END | |
| 60 | 50 | |
| 61 | const device_type ISA8_FDC = &device_creator<isa8_fdc_device>; | |
| 51 | static MACHINE_CONFIG_FRAGMENT( cfg_ps2 ) | |
| 52 | MCFG_N82077AA_ADD("fdc", n82077aa_device::MODE_PS2) | |
| 53 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 54 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 55 | MACHINE_CONFIG_END | |
| 62 | 56 | |
| 63 | //------------------------------------------------- | |
| 64 | // machine_config_additions - device-specific | |
| 65 | // machine configurations | |
| 66 | //------------------------------------------------- | |
| 57 | static MACHINE_CONFIG_FRAGMENT( cfg_superio ) | |
| 58 | MCFG_PC_FDC_SUPERIO_ADD("fdc") | |
| 59 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 60 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", pc_hd_floppies, "35hd", 0, pc_floppy_formats) | |
| 61 | MACHINE_CONFIG_END | |
| 67 | 62 | |
| 68 | machine_config_constructor isa8_fdc_device::device_mconfig_additions() const | |
| 69 | { | |
| 70 | return MACHINE_CONFIG_NAME( fdc_config ); | |
| 71 | } | |
| 72 | 63 | |
| 73 | //************************************************************************** | |
| 74 | // LIVE DEVICE | |
| 75 | //************************************************************************** | |
| 76 | ||
| 77 | //------------------------------------------------- | |
| 78 | // isa8_fdc_device - constructor | |
| 79 | //------------------------------------------------- | |
| 80 | ||
| 81 | isa8_fdc_device::isa8_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 82 | device_t(mconfig, ISA8_FDC, "Diskette Drive Adapter", tag, owner, clock), | |
| 83 | device_isa8_card_interface(mconfig, *this), | |
| 84 | m_upd765(*this, "upd765") | |
| 85 | { | |
| 86 | } | |
| 87 | ||
| 88 | 64 | isa8_fdc_device::isa8_fdc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 89 | device_t(mconfig, type, name, tag, owner, clock), | |
| 90 | device_isa8_card_interface(mconfig, *this), | |
| 91 | m_upd765(*this, "upd765") | |
| 65 | device_t(mconfig, type, name, tag, owner, clock), | |
| 66 | device_isa8_card_interface(mconfig, *this), | |
| 67 | fdc(*this, "fdc") | |
| 92 | 68 | { |
| 93 | 69 | } |
| 94 | 70 | |
| 95 | //------------------------------------------------- | |
| 96 | // device_start - device-specific startup | |
| 97 | //------------------------------------------------- | |
| 98 | ||
| 99 | 71 | void isa8_fdc_device::device_start() |
| 100 | 72 | { |
| 101 | 73 | set_isa_device(); |
| 102 | m_isa->install_device( | |
| 74 | m_isa->install_device(0x03f0, 0x03f7, *fdc, &pc_fdc_interface::map); | |
| 103 | 75 | m_isa->set_dma_channel(2, this, TRUE); |
| 76 | ||
| 77 | fdc->setup_intrq_cb(pc_fdc_interface::line_cb(FUNC(isa8_fdc_device::irq_w), this)); | |
| 78 | fdc->setup_drq_cb(pc_fdc_interface::line_cb(FUNC(isa8_fdc_device::drq_w), this)); | |
| 104 | 79 | } |
| 105 | 80 | |
| 106 | //------------------------------------------------- | |
| 107 | // device_reset - device-specific reset | |
| 108 | //------------------------------------------------- | |
| 109 | ||
| 110 | 81 | void isa8_fdc_device::device_reset() |
| 111 | 82 | { |
| 112 | status_register_a = 0; | |
| 113 | status_register_b = 0; | |
| 114 | digital_output_register = 0; | |
| 115 | tape_drive_register = 0; | |
| 116 | data_rate_register = 2; | |
| 117 | digital_input_register = 0x07f; | |
| 118 | configuration_control_register = 0; | |
| 119 | tc_state = 0; | |
| 120 | dma_state = 0; | |
| 121 | int_state = 0; | |
| 122 | ||
| 123 | upd765_reset(m_upd765,0); | |
| 124 | ||
| 125 | /* set FDC at reset */ | |
| 126 | upd765_reset_w(m_upd765, 1); | |
| 127 | 83 | } |
| 128 | 84 | |
| 129 | ||
| 85 | void isa8_fdc_device::irq_w(bool state) | |
| 130 | 86 | { |
| 131 | switch(drive) { | |
| 132 | case 0 : return device->subdevice(FLOPPY_0); | |
| 133 | case 1 : return device->subdevice(FLOPPY_1); | |
| 134 | case 2 : return device->subdevice(FLOPPY_2); | |
| 135 | case 3 : return device->subdevice(FLOPPY_3); | |
| 136 | } | |
| 137 | return NULL; | |
| 87 | m_isa->irq6_w(state ? ASSERT_LINE : CLEAR_LINE); | |
| 138 | 88 | } |
| 139 | 89 | |
| 140 | ||
| 90 | void isa8_fdc_device::drq_w(bool state) | |
| 141 | 91 | { |
| 142 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device->owner()); | |
| 143 | ||
| 144 | return get_floppy_subdevice(fdc, fdc->digital_output_register & 0x03); | |
| 92 | m_isa->drq2_w(state ? ASSERT_LINE : CLEAR_LINE); | |
| 145 | 93 | } |
| 146 | 94 | |
| 147 | ||
| 95 | UINT8 isa8_fdc_device::dack_r(int line) | |
| 148 | 96 | { |
| 149 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device); | |
| 150 | /* store state */ | |
| 151 | fdc->tc_state = state; | |
| 152 | ||
| 153 | /* if dma is not enabled, tc's are not acknowledged */ | |
| 154 | if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)!=0) | |
| 155 | { | |
| 156 | upd765_tc_w(fdc->m_upd765, state); | |
| 157 | } | |
| 97 | return fdc->dma_r(); | |
| 158 | 98 | } |
| 159 | 99 | |
| 160 | ||
| 100 | void isa8_fdc_device::dack_w(int line, UINT8 data) | |
| 161 | 101 | { |
| 162 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device->owner()); | |
| 163 | ||
| 164 | fdc->int_state = state; | |
| 165 | ||
| 166 | /* if dma is not enabled, irq's are masked */ | |
| 167 | if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)==0) | |
| 168 | return; | |
| 169 | ||
| 170 | // not masked, send interrupt request | |
| 171 | fdc->m_isa->irq6_w(state); | |
| 102 | return fdc->dma_w(data); | |
| 172 | 103 | } |
| 173 | 104 | |
| 174 | ||
| 175 | static WRITE_LINE_DEVICE_HANDLER( pc_fdc_hw_dma_drq ) | |
| 105 | void isa8_fdc_device::eop_w(int state) | |
| 176 | 106 | { |
| 177 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device->owner()); | |
| 178 | fdc->dma_state = state; | |
| 179 | ||
| 180 | /* if dma is not enabled, drqs are masked */ | |
| 181 | if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)==0) | |
| 182 | return; | |
| 183 | ||
| 184 | // not masked, send dma request | |
| 185 | fdc->m_isa->drq2_w(state); | |
| 107 | fdc->tc_w(state == ASSERT_LINE); | |
| 186 | 108 | } |
| 187 | 109 | |
| 188 | ||
| 189 | ||
| 190 | static WRITE8_DEVICE_HANDLER( pc_fdc_data_rate_w ) | |
| 110 | isa8_fdc_xt_device::isa8_fdc_xt_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : isa8_fdc_device(mconfig, ISA8_FDC_XT, "ISA 8bits XT FDC hookup", tag, owner, clock) | |
| 191 | 111 | { |
| 192 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device); | |
| 193 | if ((data & 0x080)!=0) | |
| 194 | { | |
| 195 | /* set ready state */ | |
| 196 | upd765_ready_w(fdc->m_upd765,1); | |
| 197 | ||
| 198 | /* toggle reset state */ | |
| 199 | upd765_reset_w(fdc->m_upd765, 1); | |
| 200 | upd765_reset_w(fdc->m_upd765, 0); | |
| 201 | ||
| 202 | /* bit is self-clearing */ | |
| 203 | data &= ~0x080; | |
| 204 | } | |
| 205 | ||
| 206 | fdc->data_rate_register = data; | |
| 112 | m_shortname = "isa8_fdc_xt"; | |
| 207 | 113 | } |
| 208 | 114 | |
| 209 | ||
| 210 | ||
| 211 | /* FDC Digitial Output Register (DOR) | |
| 212 | ||
| 213 | |7|6|5|4|3|2|1|0| | |
| 214 | | | | | | | `------ floppy drive select (0=A, 1=B, 2=floppy C, ...) | |
| 215 | | | | | | `-------- 1 = FDC enable, 0 = hold FDC at reset | |
| 216 | | | | | `---------- 1 = DMA & I/O interface enabled | |
| 217 | | | | `------------ 1 = turn floppy drive A motor on | |
| 218 | | | `-------------- 1 = turn floppy drive B motor on | |
| 219 | | `---------------- 1 = turn floppy drive C motor on | |
| 220 | `------------------ 1 = turn floppy drive D motor on | |
| 221 | */ | |
| 222 | ||
| 223 | static WRITE8_DEVICE_HANDLER( pc_fdc_dor_w ) | |
| 115 | machine_config_constructor isa8_fdc_xt_device::device_mconfig_additions() const | |
| 224 | 116 | { |
| 225 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device); | |
| 226 | int selected_drive; | |
| 227 | int floppy_count; | |
| 228 | ||
| 229 | floppy_count = floppy_get_count(space.machine()); | |
| 230 | ||
| 231 | if (floppy_count > (fdc->digital_output_register & 0x03)) | |
| 232 | floppy_drive_set_ready_state(get_floppy_subdevice(device, fdc->digital_output_register & 0x03), 1, 0); | |
| 233 | ||
| 234 | fdc->digital_output_register = data; | |
| 235 | ||
| 236 | selected_drive = data & 0x03; | |
| 237 | ||
| 238 | /* set floppy drive motor state */ | |
| 239 | if (floppy_count > 0) | |
| 240 | floppy_mon_w(get_floppy_subdevice(device, 0), !BIT(data, 4)); | |
| 241 | if (floppy_count > 1) | |
| 242 | floppy_mon_w(get_floppy_subdevice(device, 1), !BIT(data, 5)); | |
| 243 | if (floppy_count > 2) | |
| 244 | floppy_mon_w(get_floppy_subdevice(device, 2), !BIT(data, 6)); | |
| 245 | if (floppy_count > 3) | |
| 246 | floppy_mon_w(get_floppy_subdevice(device, 3), !BIT(data, 7)); | |
| 247 | ||
| 248 | if ((data>>4) & (1<<selected_drive)) | |
| 249 | { | |
| 250 | if (floppy_count > selected_drive) | |
| 251 | floppy_drive_set_ready_state(get_floppy_subdevice(device, selected_drive), 1, 0); | |
| 252 | } | |
| 253 | ||
| 254 | /* changing the DMA enable bit, will affect the terminal count state | |
| 255 | from reaching the fdc - if dma is enabled this will send it through | |
| 256 | otherwise it will be ignored */ | |
| 257 | pc_fdc_set_tc_state(device, fdc->tc_state); | |
| 258 | ||
| 259 | /* changing the DMA enable bit, will affect the dma drq state | |
| 260 | from reaching us - if dma is enabled this will send it through | |
| 261 | otherwise it will be ignored */ | |
| 262 | pc_fdc_hw_dma_drq(fdc->m_upd765, fdc->dma_state); | |
| 263 | ||
| 264 | /* changing the DMA enable bit, will affect the irq state | |
| 265 | from reaching us - if dma is enabled this will send it through | |
| 266 | otherwise it will be ignored */ | |
| 267 | pc_fdc_hw_interrupt(fdc->m_upd765, fdc->int_state); | |
| 268 | ||
| 269 | /* reset? */ | |
| 270 | if ((fdc->digital_output_register & PC_FDC_FLAGS_DOR_FDC_ENABLED)==0) | |
| 271 | { | |
| 272 | /* yes */ | |
| 273 | ||
| 274 | /* pc-xt expects a interrupt to be generated | |
| 275 | when the fdc is reset. | |
| 276 | In the FDC docs, it states that a INT will | |
| 277 | be generated if READY input is true when the | |
| 278 | fdc is reset. | |
| 279 | ||
| 280 | It also states, that outputs to drive are set to 0. | |
| 281 | Maybe this causes the drive motor to go on, and therefore | |
| 282 | the ready line is set. | |
| 283 | ||
| 284 | This in return causes a int?? --- | |
| 285 | ||
| 286 | ||
| 287 | what is not yet clear is if this is a result of the drives ready state | |
| 288 | changing... | |
| 289 | */ | |
| 290 | upd765_ready_w(fdc->m_upd765, 1); | |
| 291 | ||
| 292 | /* set FDC at reset */ | |
| 293 | upd765_reset_w(fdc->m_upd765, 1); | |
| 294 | } | |
| 295 | else | |
| 296 | { | |
| 297 | pc_fdc_set_tc_state(device, 0); | |
| 298 | ||
| 299 | /* release reset on fdc */ | |
| 300 | upd765_reset_w(fdc->m_upd765, 0); | |
| 301 | } | |
| 117 | return MACHINE_CONFIG_NAME(cfg_xt); | |
| 302 | 118 | } |
| 303 | 119 | |
| 304 | #define RATE_250 2 | |
| 305 | #define RATE_300 1 | |
| 306 | #define RATE_500 0 | |
| 307 | #define RATE_1000 3 | |
| 308 | ||
| 309 | static void pc_fdc_check_data_rate(isa8_fdc_device *fdc, running_machine &machine) | |
| 120 | isa8_fdc_at_device::isa8_fdc_at_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : isa8_fdc_device(mconfig, ISA8_FDC_AT, "ISA 8bits AT FDC hookup", tag, owner, clock) | |
| 310 | 121 | { |
| 311 | device_t *device = get_floppy_subdevice(fdc, fdc->digital_output_register & 0x03); | |
| 312 | floppy_image_legacy *image; | |
| 313 | int tracks, sectors, rate; | |
| 314 | ||
| 315 | upd765_set_bad(fdc->m_upd765, 0); // unset in case format is unknown | |
| 316 | if (!device) return; | |
| 317 | image = flopimg_get_image(device); | |
| 318 | if (!image) return; | |
| 319 | tracks = floppy_get_tracks_per_disk(image); | |
| 320 | tracks -= (tracks % 10); // ignore extra tracks | |
| 321 | floppy_get_sector_count(image, 0, 0, §ors); | |
| 322 | ||
| 323 | if (tracks == 40) { | |
| 324 | if ((fdc->data_rate_register != RATE_250) && (fdc->data_rate_register != RATE_300)) | |
| 325 | upd765_set_bad(fdc->m_upd765, 1); | |
| 326 | return; | |
| 327 | } else if (tracks == 80) { | |
| 328 | if (sectors <= 14) rate = RATE_250; // 720KB 5 1/4 and 3 1/2 | |
| 329 | else if (sectors <= 24) rate = RATE_500; // 1.2MB 5 1/4 and 1.44MB 3 1/2 | |
| 330 | else rate = RATE_1000; // 2.88MB 3 1/2 | |
| 331 | } else return; | |
| 332 | ||
| 333 | if (rate != (fdc->data_rate_register & 3)) | |
| 334 | upd765_set_bad(fdc->m_upd765, 1); | |
| 122 | m_shortname = "isa8_fdc_at"; | |
| 335 | 123 | } |
| 336 | 124 | |
| 337 | ||
| 338 | static READ8_DEVICE_HANDLER ( pc_fdc_r ) | |
| 125 | machine_config_constructor isa8_fdc_at_device::device_mconfig_additions() const | |
| 339 | 126 | { |
| 340 | UINT8 data = 0xff; | |
| 341 | ||
| 342 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device); | |
| 343 | device_t *hdd = NULL; | |
| 344 | switch(offset) | |
| 345 | { | |
| 346 | case 0: /* status register a */ | |
| 347 | case 1: /* status register b */ | |
| 348 | data = 0x00; | |
| 349 | break; | |
| 350 | case 2: | |
| 351 | data = fdc->digital_output_register; | |
| 352 | break; | |
| 353 | case 3: /* tape drive select? */ | |
| 354 | break; | |
| 355 | case 4: | |
| 356 | data = upd765_status_r(fdc->m_upd765, space, 0); | |
| 357 | break; | |
| 358 | case 5: | |
| 359 | data = upd765_data_r(fdc->m_upd765, space, offset); | |
| 360 | break; | |
| 361 | case 6: /* FDC reserved */ | |
| 362 | hdd = space.machine().device(":board3:ide:ide"); | |
| 363 | if (hdd) | |
| 364 | data = ide_controller16_r(hdd, space, 0x3f6/2, 0x00ff); | |
| 365 | break; | |
| 366 | case 7: | |
| 367 | device_t *dev = get_floppy_subdevice(device, fdc->digital_output_register & 0x03); | |
| 368 | data = fdc->digital_input_register; | |
| 369 | if(dev!=NULL) data |= (!floppy_dskchg_r(dev)<<7); | |
| 370 | break; | |
| 371 | } | |
| 372 | ||
| 373 | if (LOG_FDC) | |
| 374 | logerror("pc_fdc_r(): pc=0x%08x offset=%d result=0x%02X\n", (unsigned) space.machine().firstcpu->pc(), offset, data); | |
| 375 | return data; | |
| 127 | return MACHINE_CONFIG_NAME(cfg_at); | |
| 376 | 128 | } |
| 377 | 129 | |
| 378 | ||
| 379 | ||
| 380 | static WRITE8_DEVICE_HANDLER ( pc_fdc_w ) | |
| 130 | isa8_fdc_smc_device::isa8_fdc_smc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : isa8_fdc_device(mconfig, ISA8_FDC_XT, "ISA 8bits SMC FDC hookup", tag, owner, clock) | |
| 381 | 131 | { |
| 382 | isa8_fdc_device *fdc = downcast<isa8_fdc_device *>(device); | |
| 383 | ||
| 384 | if (LOG_FDC) | |
| 385 | logerror("pc_fdc_w(): pc=0x%08x offset=%d data=0x%02X\n", (unsigned) space.machine().firstcpu->pc(), offset, data); | |
| 386 | pc_fdc_check_data_rate(fdc,space.machine()); // check every time a command may start | |
| 387 | device_t *hdd = NULL; | |
| 388 | ||
| 389 | switch(offset) | |
| 390 | { | |
| 391 | case 0: /* n/a */ | |
| 392 | case 1: /* n/a */ | |
| 393 | break; | |
| 394 | case 2: | |
| 395 | pc_fdc_dor_w(device, space, 0, data, mem_mask); | |
| 396 | break; | |
| 397 | case 3: | |
| 398 | /* tape drive select? */ | |
| 399 | break; | |
| 400 | case 4: | |
| 401 | pc_fdc_data_rate_w(device, space, 0, data, mem_mask); | |
| 402 | break; | |
| 403 | case 5: | |
| 404 | upd765_data_w(fdc->m_upd765, space, 0, data); | |
| 405 | break; | |
| 406 | case 6: | |
| 407 | /* FDC reserved */ | |
| 408 | hdd = space.machine().device(":board3:ide:ide"); | |
| 409 | if (hdd) | |
| 410 | ide_controller16_w(hdd, space, 0x3f6/2, data, 0x00ff); | |
| 411 | break; | |
| 412 | case 7: | |
| 413 | /* Configuration Control Register | |
| 414 | * | |
| 415 | * Currently unimplemented; bits 1-0 are supposed to control data | |
| 416 | * flow rates: | |
| 417 | * 0 0 500 kbps | |
| 418 | * 0 1 300 kbps | |
| 419 | * 1 0 250 kbps | |
| 420 | * 1 1 1000 kbps | |
| 421 | */ | |
| 422 | pc_fdc_data_rate_w(device, space, 0, data & 3, mem_mask); | |
| 423 | break; | |
| 424 | } | |
| 132 | m_shortname = "isa8_fdc_smc"; | |
| 425 | 133 | } |
| 426 | 134 | |
| 427 | ||
| 135 | machine_config_constructor isa8_fdc_smc_device::device_mconfig_additions() const | |
| 428 | 136 | { |
| 429 | /* what is output if dack is not acknowledged? */ | |
| 430 | int data = 0x0ff; | |
| 431 | ||
| 432 | /* if dma is not enabled, dacks are not acknowledged */ | |
| 433 | if ((digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)!=0) | |
| 434 | { | |
| 435 | data = upd765_dack_r(m_upd765, machine().driver_data()->generic_space(), 0); | |
| 436 | } | |
| 437 | ||
| 438 | return data; | |
| 137 | return MACHINE_CONFIG_NAME(cfg_smc); | |
| 439 | 138 | } |
| 440 | 139 | |
| 441 | ||
| 140 | isa8_fdc_ps2_device::isa8_fdc_ps2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : isa8_fdc_device(mconfig, ISA8_FDC_PS2, "ISA 8bits PS/2 FDC hookup", tag, owner, clock) | |
| 442 | 141 | { |
| 443 | /* if dma is not enabled, dacks are not issued */ | |
| 444 | if ((digital_output_register & PC_FDC_FLAGS_DOR_DMA_ENABLED)!=0) | |
| 445 | { | |
| 446 | /* dma acknowledge - and send byte to fdc */ | |
| 447 | upd765_dack_w(m_upd765, machine().driver_data()->generic_space(), 0,data); | |
| 448 | } | |
| 142 | m_shortname = "isa8_fdc_ps2"; | |
| 449 | 143 | } |
| 450 | void isa8_fdc_device::eop_w(int state) | |
| 144 | ||
| 145 | machine_config_constructor isa8_fdc_ps2_device::device_mconfig_additions() const | |
| 451 | 146 | { |
| 452 | | |
| 147 | return MACHINE_CONFIG_NAME(cfg_ps2); | |
| 453 | 148 | } |
| 454 | 149 | |
| 455 | static MACHINE_CONFIG_FRAGMENT( fdc_smc_config ) | |
| 456 | MCFG_SMC37C78_ADD("upd765", pc_fdc_upd765_not_connected_interface) | |
| 457 | ||
| 458 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 459 | MACHINE_CONFIG_END | |
| 460 | ||
| 461 | //************************************************************************** | |
| 462 | // GLOBAL VARIABLES | |
| 463 | //************************************************************************** | |
| 464 | ||
| 465 | const device_type ISA8_FDC_SMC = &device_creator<isa8_fdc_smc_device>; | |
| 466 | ||
| 467 | //------------------------------------------------- | |
| 468 | // machine_config_additions - device-specific | |
| 469 | // machine configurations | |
| 470 | //------------------------------------------------- | |
| 471 | ||
| 472 | machine_config_constructor isa8_fdc_smc_device::device_mconfig_additions() const | |
| 150 | isa8_fdc_superio_device::isa8_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : isa8_fdc_device(mconfig, ISA8_FDC_SUPERIO, "ISA 8bits SUPERIO FDC hookup", tag, owner, clock) | |
| 473 | 151 | { |
| 474 | r | |
| 152 | m_shortname = "isa8_fdc_superio"; | |
| 475 | 153 | } |
| 476 | 154 | |
| 477 | //------------------------------------------------- | |
| 478 | // isa8_fdc_smc_device - constructor | |
| 479 | //------------------------------------------------- | |
| 480 | ||
| 481 | isa8_fdc_smc_device::isa8_fdc_smc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 482 | isa8_fdc_device(mconfig, ISA8_FDC_SMC, "Diskette Drive Adapter (SMC37C78)", tag, owner, clock) | |
| 155 | machine_config_constructor isa8_fdc_superio_device::device_mconfig_additions() const | |
| 483 | 156 | { |
| 157 | return MACHINE_CONFIG_NAME(cfg_superio); | |
| 484 | 158 | } |
| 485 | 159 | |
| 160 | const device_type ISA8_FDC_XT = &device_creator<isa8_fdc_xt_device>; | |
| 161 | const device_type ISA8_FDC_AT = &device_creator<isa8_fdc_at_device>; | |
| 162 | const device_type ISA8_FDC_SMC = &device_creator<isa8_fdc_smc_device>; | |
| 163 | const device_type ISA8_FDC_PS2 = &device_creator<isa8_fdc_ps2_device>; | |
| 164 | const device_type ISA8_FDC_SUPERIO = &device_creator<isa8_fdc_superio_device>; |
| r18419 | r18420 | |
|---|---|---|
| 159 | 159 | /*-------------------------------------------------------------------------*/ |
| 160 | 160 | static void compis_fdc_reset(running_machine &machine) |
| 161 | 161 | { |
| 162 | device_t *fdc = machine.device("upd765"); | |
| 163 | ||
| 164 | upd765_reset(fdc, 0); | |
| 165 | ||
| 166 | /* set FDC at reset */ | |
| 167 | upd765_reset_w(fdc, 1); | |
| 162 | machine.device("upd765")->reset(); | |
| 168 | 163 | } |
| 169 | 164 | |
| 170 | 165 | void compis_state::compis_fdc_tc(int state) |
| r18419 | r18420 | |
| 172 | 167 | /* Terminal count if iSBX-218A has DMA enabled */ |
| 173 | 168 | if (ioport("DSW1")->read()) |
| 174 | 169 | { |
| 175 | | |
| 170 | m_fdc->tc_w(state); | |
| 176 | 171 | } |
| 177 | 172 | } |
| 178 | 173 | |
| 179 | ||
| 174 | void compis_state::fdc_irq(bool state) | |
| 180 | 175 | { |
| 181 | 176 | /* No interrupt requests if iSBX-218A has DMA enabled */ |
| 182 | 177 | if (!ioport("DSW1")->read() && state) |
| r18419 | r18420 | |
| 189 | 184 | } |
| 190 | 185 | } |
| 191 | 186 | |
| 192 | ||
| 187 | void compis_state::fdc_drq(bool state) | |
| 193 | 188 | { |
| 194 | /* DMA requst if iSBX-218A has DMA enabled */ | |
| 189 | /* DMA request if iSBX-218A has DMA enabled */ | |
| 195 | 190 | if (ioport("DSW1")->read() && state) |
| 196 | 191 | { |
| 197 | 192 | //compis_dma_drq(state, read); |
| 198 | 193 | } |
| 199 | 194 | } |
| 200 | 195 | |
| 201 | const upd765_interface compis_fdc_interface = | |
| 202 | { | |
| 203 | DEVCB_DRIVER_LINE_MEMBER(compis_state, compis_fdc_int), | |
| 204 | DEVCB_DRIVER_LINE_MEMBER(compis_state, compis_fdc_dma_drq), | |
| 205 | NULL, | |
| 206 | UPD765_RDY_PIN_CONNECTED, | |
| 207 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 208 | }; | |
| 209 | 196 | |
| 210 | READ16_MEMBER( compis_state::compis_fdc_dack_r ) | |
| 211 | { | |
| 212 | UINT16 data; | |
| 213 | data = 0xffff; | |
| 214 | /* DMA acknowledge if iSBX-218A has DMA enabled */ | |
| 215 | if (ioport("DSW1")->read()) | |
| 216 | { | |
| 217 | data = upd765_dack_r(m_fdc, space, 0); | |
| 218 | } | |
| 219 | ||
| 220 | return data; | |
| 221 | } | |
| 222 | ||
| 223 | WRITE8_MEMBER( compis_state::compis_fdc_w ) | |
| 224 | { | |
| 225 | switch(offset) | |
| 226 | { | |
| 227 | case 2: | |
| 228 | upd765_data_w(m_fdc, space, 0, data); | |
| 229 | break; | |
| 230 | default: | |
| 231 | printf("FDC Unknown Port Write %04X = %04X\n", offset, data); | |
| 232 | break; | |
| 233 | } | |
| 234 | } | |
| 235 | ||
| 236 | READ8_MEMBER( compis_state::compis_fdc_r ) | |
| 237 | { | |
| 238 | UINT16 data; | |
| 239 | data = 0xffff; | |
| 240 | switch(offset) | |
| 241 | { | |
| 242 | case 0: | |
| 243 | data = upd765_status_r(m_fdc, space, 0); | |
| 244 | break; | |
| 245 | case 2: | |
| 246 | data = upd765_data_r(m_fdc, space, 0); | |
| 247 | break; | |
| 248 | default: | |
| 249 | printf("FDC Unknown Port Read %04X\n", offset); | |
| 250 | break; | |
| 251 | } | |
| 252 | ||
| 253 | return data; | |
| 254 | } | |
| 255 | ||
| 256 | ||
| 257 | ||
| 258 | 197 | /*-------------------------------------------------------------------------*/ |
| 259 | 198 | /* Bit 0: J5-4 */ |
| 260 | 199 | /* Bit 1: J5-5 */ |
| r18419 | r18420 | |
|---|---|---|
| 10 | 10 | |
| 11 | 11 | #include "emu.h" |
| 12 | 12 | #include "machine/isa.h" |
| 13 | #include "machine/upd765.h" | |
| 13 | 14 | |
| 14 | 15 | //************************************************************************** |
| 15 | 16 | // TYPE DEFINITIONS |
| r18419 | r18420 | |
| 18 | 19 | // ======================> isa8_fdc_device |
| 19 | 20 | |
| 20 | 21 | class isa8_fdc_device : |
| 21 | public device_t, | |
| 22 | public device_isa8_card_interface | |
| 22 | public device_t, | |
| 23 | public device_isa8_card_interface | |
| 23 | 24 | { |
| 24 | 25 | public: |
| 25 | // construction/destruction | |
| 26 | isa8_fdc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 27 | isa8_fdc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 26 | // construction/destruction | |
| 27 | isa8_fdc_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); | |
| 28 | 28 | |
| 29 | // optional information overrides | |
| 30 | virtual machine_config_constructor device_mconfig_additions() const; | |
| 29 | required_device<pc_fdc_interface> fdc; | |
| 30 | ||
| 31 | 31 | protected: |
| 32 | // device-level overrides | |
| 33 | virtual void device_start(); | |
| 34 | virtual void device_reset(); | |
| 35 | virtual void device_config_complete() { m_shortname = "isa_fdc"; } | |
| 36 | private: | |
| 37 | // internal state | |
| 38 | public: | |
| 39 | virtual UINT8 dack_r(int line); | |
| 40 | virtual void dack_w(int line,UINT8 data); | |
| 41 | virtual void eop_w(int state); | |
| 32 | // device-level overrides | |
| 33 | virtual void device_start(); | |
| 34 | virtual void device_reset(); | |
| 42 | 35 | |
| 43 | int status_register_a; | |
| 44 | int status_register_b; | |
| 45 | int digital_output_register; | |
| 46 | int tape_drive_register; | |
| 47 | int data_rate_register; | |
| 48 | int digital_input_register; | |
| 49 | int configuration_control_register; | |
| 36 | virtual UINT8 dack_r(int line); | |
| 37 | virtual void dack_w(int line, UINT8 data); | |
| 38 | virtual void eop_w(int state); | |
| 50 | 39 | |
| 51 | /* stored tc state - state present at pins */ | |
| 52 | int tc_state; | |
| 53 | /* stored dma drq state */ | |
| 54 | int dma_state; | |
| 55 | /* stored int state */ | |
| 56 | int int_state; | |
| 40 | private: | |
| 41 | void irq_w(bool state); | |
| 42 | void drq_w(bool state); | |
| 57 | 43 | |
| 58 | required_device<device_t> m_upd765; | |
| 59 | 44 | }; |
| 60 | 45 | |
| 46 | class isa8_fdc_xt_device : public isa8_fdc_device { | |
| 47 | public: | |
| 48 | isa8_fdc_xt_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 49 | virtual machine_config_constructor device_mconfig_additions() const; | |
| 50 | }; | |
| 61 | 51 | |
| 62 | // device type definition | |
| 63 | extern const device_type ISA8_FDC; | |
| 52 | class isa8_fdc_at_device : public isa8_fdc_device { | |
| 53 | public: | |
| 54 | isa8_fdc_at_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 55 | virtual machine_config_constructor device_mconfig_additions() const; | |
| 56 | }; | |
| 64 | 57 | |
| 65 | // ======================> isa8_fdc_smc_device | |
| 58 | class isa8_fdc_smc_device : public isa8_fdc_device { | |
| 59 | public: | |
| 60 | isa8_fdc_smc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 61 | virtual machine_config_constructor device_mconfig_additions() const; | |
| 62 | }; | |
| 66 | 63 | |
| 67 | class isa8_fdc_smc_device : | |
| 68 | public isa8_fdc_device | |
| 69 | { | |
| 64 | class isa8_fdc_ps2_device : public isa8_fdc_device { | |
| 70 | 65 | public: |
| 71 | // construction/destruction | |
| 72 | isa8_fdc_smc_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 66 | isa8_fdc_ps2_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 67 | virtual machine_config_constructor device_mconfig_additions() const; | |
| 68 | }; | |
| 73 | 69 | |
| 74 | // optional information overrides | |
| 70 | class isa8_fdc_superio_device : public isa8_fdc_device { | |
| 71 | public: | |
| 72 | isa8_fdc_superio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 75 | 73 | virtual machine_config_constructor device_mconfig_additions() const; |
| 76 | virtual void device_config_complete() { m_shortname = "isa_fdc_smc"; } | |
| 77 | 74 | }; |
| 78 | 75 | |
| 79 | ||
| 80 | 76 | // device type definition |
| 77 | extern const device_type ISA8_FDC_XT; | |
| 78 | extern const device_type ISA8_FDC_AT; | |
| 81 | 79 | extern const device_type ISA8_FDC_SMC; |
| 80 | extern const device_type ISA8_FDC_PS2; | |
| 81 | extern const device_type ISA8_FDC_SUPERIO; | |
| 82 | 82 | |
| 83 | 83 | #endif /* ISA_FDC_H */ |
| r18419 | r18420 | |
|---|---|---|
| 527 | 527 | PORT_DIPNAME( 0x02, 0x00, "8087 installed") |
| 528 | 528 | PORT_DIPSETTING( 0x00, DEF_STR(No) ) |
| 529 | 529 | PORT_DIPSETTING( 0x02, DEF_STR(Yes) ) |
| 530 | PORT_DIPNAME( 0x01, 0x01, "Any floppy drive installed") | |
| 530 | PORT_DIPNAME( 0x01, 0x01, "Boot from floppy") | |
| 531 | PORT_DIPSETTING( 0x01, DEF_STR(Yes) ) | |
| 531 | 532 | PORT_DIPSETTING( 0x00, DEF_STR(No) ) |
| 532 | PORT_DIPSETTING( 0x01, DEF_STR(Yes) ) | |
| 533 | 533 | INPUT_PORTS_END |
| 534 | 534 | //------------------------------------------------- |
| 535 | 535 | // input_ports - device-specific input ports |
| r18419 | r18420 | |
|---|---|---|
| 16 | 16 | #include "machine/upd7201.h" |
| 17 | 17 | #include "machine/upd765.h" |
| 18 | 18 | #include "imagedev/flopdrv.h" |
| 19 | #include "formats/mfi_dsk.h" | |
| 19 | 20 | |
| 20 | ||
| 21 | 21 | /*************************************************************************** |
| 22 | 22 | CONSTANTS |
| 23 | 23 | ***************************************************************************/ |
| r18419 | r18420 | |
| 32 | 32 | |
| 33 | 33 | struct tf20_state |
| 34 | 34 | { |
| 35 | device_t *cpu; | |
| 35 | 36 | ram_device *ram; |
| 36 | device | |
| 37 | upd765a_device *upd765a; | |
| 37 | 38 | upd7201_device *upd7201; |
| 38 | device_t *floppy_0; | |
| 39 | device_t *floppy_1; | |
| 39 | floppy_image_device *floppy_0; | |
| 40 | floppy_image_device *floppy_1; | |
| 41 | ||
| 42 | void fdc_int(bool state) { | |
| 43 | cpu->execute().set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); | |
| 44 | } | |
| 40 | 45 | }; |
| 41 | 46 | |
| 42 | 47 | |
| r18419 | r18420 | |
| 89 | 94 | |
| 90 | 95 | static TIMER_CALLBACK( tf20_upd765_tc_reset ) |
| 91 | 96 | { |
| 92 | upd765_ | |
| 97 | static_cast<upd765a_device *>(ptr)->tc_w(false); | |
| 93 | 98 | } |
| 94 | 99 | |
| 95 | 100 | static READ8_DEVICE_HANDLER( tf20_upd765_tc_r ) |
| 96 | 101 | { |
| 97 | logerror("%s: tf20_upd765_tc_r\n", space.machine().describe_context()); | |
| 102 | tf20_state *tf20 = get_safe_token(device->owner()); | |
| 103 | logerror("%s: tf20_upd765_tc_r\n", device->machine().describe_context()); | |
| 98 | 104 | |
| 99 | 105 | /* toggle tc on read */ |
| 100 | upd765 | |
| 106 | tf20->upd765a->tc_w(true); | |
| 101 | 107 | space.machine().scheduler().timer_set(attotime::zero, FUNC(tf20_upd765_tc_reset), 0, device); |
| 102 | 108 | |
| 103 | 109 | return 0xff; |
| r18419 | r18420 | |
| 109 | 115 | logerror("%s: tf20_fdc_control_w %02x\n", space.machine().describe_context(), data); |
| 110 | 116 | |
| 111 | 117 | /* bit 0, motor on signal */ |
| 112 | floppy_mon_w(tf20->floppy_0, !BIT(data, 0)); | |
| 113 | floppy_mon_w(tf20->floppy_1, !BIT(data, 0)); | |
| 118 | tf20->floppy_0->mon_w(!BIT(data, 0)); | |
| 119 | tf20->floppy_1->mon_w(!BIT(data, 0)); | |
| 114 | 120 | } |
| 115 | 121 | |
| 116 | 122 | static IRQ_CALLBACK( tf20_irq_ack ) |
| r18419 | r18420 | |
| 210 | 216 | AM_RANGE(0xf6, 0xf6) AM_READ_LEGACY(tf20_rom_disable) |
| 211 | 217 | AM_RANGE(0xf7, 0xf7) AM_READ_LEGACY(tf20_dip_r) |
| 212 | 218 | AM_RANGE(0xf8, 0xf8) AM_DEVREAD_LEGACY("5a", tf20_upd765_tc_r) AM_WRITE_LEGACY(tf20_fdc_control_w) |
| 213 | AM_RANGE(0xfa, 0xfa) AM_DEVREAD_LEGACY("5a", upd765_status_r) | |
| 214 | AM_RANGE(0xfb, 0xfb) AM_DEVREADWRITE_LEGACY("5a", upd765_data_r, upd765_data_w) | |
| 219 | AM_RANGE(0xfa, 0xfb) AM_DEVICE("5a", upd765a_device, map) | |
| 215 | 220 | ADDRESS_MAP_END |
| 216 | 221 | |
| 217 | 222 | |
| r18419 | r18420 | |
| 266 | 271 | } |
| 267 | 272 | }; |
| 268 | 273 | |
| 269 | static const upd765_interface tf20_upd765a_intf = | |
| 270 | { | |
| 271 | DEVCB_CPU_INPUT_LINE("tf20", INPUT_LINE_IRQ0), | |
| 272 | DEVCB_NULL, | |
| 273 | NULL, | |
| 274 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 275 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 276 | }; | |
| 277 | ||
| 278 | static const floppy_interface tf20_floppy_interface = | |
| 279 | { | |
| 280 | DEVCB_NULL, | |
| 281 | DEVCB_NULL, | |
| 282 | DEVCB_NULL, | |
| 283 | DEVCB_NULL, | |
| 284 | DEVCB_NULL, | |
| 285 | FLOPPY_STANDARD_5_25_DSDD_40, | |
| 286 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 287 | NULL, | |
| 274 | static const floppy_format_type tf20_floppy_formats[] = { | |
| 275 | FLOPPY_MFI_FORMAT, | |
| 288 | 276 | NULL |
| 289 | 277 | }; |
| 290 | 278 | |
| 279 | static SLOT_INTERFACE_START( tf20_floppies ) | |
| 280 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 281 | SLOT_INTERFACE_END | |
| 282 | ||
| 291 | 283 | static MACHINE_CONFIG_FRAGMENT( tf20 ) |
| 292 | 284 | MCFG_CPU_ADD("tf20", Z80, XTAL_CR1 / 2) /* uPD780C */ |
| 293 | 285 | MCFG_CPU_PROGRAM_MAP(tf20_mem) |
| r18419 | r18420 | |
| 298 | 290 | MCFG_RAM_DEFAULT_SIZE("64k") |
| 299 | 291 | |
| 300 | 292 | /* upd765a floppy controller */ |
| 301 | MCFG_UPD765A_ADD("5a", | |
| 293 | MCFG_UPD765A_ADD("5a", false, true) | |
| 302 | 294 | |
| 303 | 295 | /* upd7201 serial interface */ |
| 304 | 296 | MCFG_UPD7201_ADD("3a", XTAL_CR1 / 2, tf20_upd7201_intf) |
| 305 | 297 | MCFG_TIMER_ADD_PERIODIC("serial_timer", serial_clock, attotime::from_hz(XTAL_CR2 / 128)) |
| 306 | 298 | |
| 307 | 299 | /* 2 floppy drives */ |
| 308 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(tf20_floppy_interface) | |
| 300 | MCFG_FLOPPY_DRIVE_ADD("5a:0", tf20_floppies, "525dd", 0, tf20_floppy_formats) | |
| 301 | MCFG_FLOPPY_DRIVE_ADD("5a:1", tf20_floppies, "525dd", 0, tf20_floppy_formats) | |
| 309 | 302 | MACHINE_CONFIG_END |
| 310 | 303 | |
| 311 | 304 | |
| r18419 | r18420 | |
| 326 | 319 | static DEVICE_START( tf20 ) |
| 327 | 320 | { |
| 328 | 321 | tf20_state *tf20 = get_safe_token(device); |
| 329 | device_t *cpu = device->subdevice("tf20"); | |
| 330 | address_space &prg = cpu->memory().space(AS_PROGRAM); | |
| 322 | tf20->cpu = device->subdevice("tf20"); | |
| 323 | address_space &prg = tf20->cpu->memory().space(AS_PROGRAM); | |
| 331 | 324 | |
| 332 | cpu->execute().set_irq_acknowledge_callback(tf20_irq_ack); | |
| 325 | tf20->cpu->execute().set_irq_acknowledge_callback(tf20_irq_ack); | |
| 333 | 326 | |
| 334 | 327 | /* ram device */ |
| 335 | 328 | tf20->ram = device->subdevice<ram_device>("ram"); |
| r18419 | r18420 | |
| 339 | 332 | throw device_missing_dependencies(); |
| 340 | 333 | |
| 341 | 334 | /* locate child devices */ |
| 342 | tf20->upd765a = device->subdevice("5a"); | |
| 335 | tf20->upd765a = device->subdevice<upd765a_device>("5a"); | |
| 343 | 336 | tf20->upd7201 = downcast<upd7201_device *>(device->subdevice("3a")); |
| 344 | tf20->floppy_0 = device->subdevice(FLOPPY_0); | |
| 345 | tf20->floppy_1 = device->subdevice(FLOPPY_1); | |
| 337 | tf20->floppy_0 = device->subdevice<floppy_connector>("5a:0")->get_device(); | |
| 338 | tf20->floppy_1 = device->subdevice<floppy_connector>("5a:1")->get_device(); | |
| 346 | 339 | |
| 340 | /* hookup the irq */ | |
| 341 | tf20->upd765a->setup_intrq_cb(upd765a_device::line_cb(FUNC(tf20_state::fdc_int), tf20)); | |
| 342 | ||
| 347 | 343 | /* enable second half of ram */ |
| 348 | 344 | prg.install_ram(0x8000, 0xffff, tf20->ram->pointer() + 0x8000); |
| 349 | 345 | } |
| r18419 | r18420 | |
|---|---|---|
| 45 | 45 | #include "sound/wave.h" /* for K7 sound*/ |
| 46 | 46 | #include "sound/discrete.h" /* for 1 Bit sound*/ |
| 47 | 47 | #include "machine/upd765.h" /* for floppy disc controller */ |
| 48 | #include "formats/basicdsk.h" | |
| 49 | 48 | |
| 50 | 49 | #include "formats/hect_tap.h" |
| 51 | 50 | #include "includes/hec2hrp.h" |
| r18419 | r18420 | |
| 876 | 875 | if (with_D2==1) |
| 877 | 876 | |
| 878 | 877 | { |
| 878 | upd765a_device *fdc = machine.device<upd765a_device>("upd765"); | |
| 879 | 879 | machine.device("disc2cpu")->execute().set_input_line(INPUT_LINE_RESET, PULSE_LINE); |
| 880 | device_t *fdc = machine.device("upd765"); | |
| 881 | machine.device("disc2cpu")->execute().set_input_line(INPUT_LINE_RESET, PULSE_LINE); | |
| 882 | upd765_reset(fdc, 1); | |
| 883 | upd765_reset_w(fdc, 1); | |
| 880 | fdc->reset(); | |
| 884 | 881 | } |
| 885 | 882 | } |
| 886 | 883 |
| r18419 | r18420 | |
|---|---|---|
| 57 | 57 | MACHINE CONFIG |
| 58 | 58 | *****************************************************************************/ |
| 59 | 59 | |
| 60 | static const upd765_interface pf10_upd765a_intf = | |
| 61 | { | |
| 62 | DEVCB_NULL, /* interrupt line */ | |
| 63 | DEVCB_NULL, | |
| 64 | NULL, | |
| 65 | UPD765_RDY_PIN_NOT_CONNECTED, /* ??? */ | |
| 66 | {NULL, NULL, NULL, NULL} | |
| 67 | }; | |
| 68 | ||
| 69 | 60 | static MACHINE_CONFIG_FRAGMENT( pf10 ) |
| 70 | 61 | MCFG_CPU_ADD("pf10", M6803, XTAL_2_4576MHz / 4 /* ??? */) /* HD63A03 */ |
| 71 | 62 | MCFG_CPU_PROGRAM_MAP(pf10_mem) |
| 72 | 63 | MCFG_CPU_IO_MAP(pf10_io) |
| 73 | 64 | |
| 74 | MCFG_UPD765A_ADD("upd765a", | |
| 65 | MCFG_UPD765A_ADD("upd765a", false, true) | |
| 75 | 66 | MACHINE_CONFIG_END |
| 76 | 67 | |
| 77 | 68 |
| r18419 | r18420 | |
|---|---|---|
| 170 | 170 | m_ctc(*this, Z80CTC_TAG), |
| 171 | 171 | m_acia(*this, MC6850_TAG), |
| 172 | 172 | m_fdc(*this, UPD765_TAG), |
| 173 | m_floppy(*this, | |
| 173 | m_floppy(*this, UPD765_TAG ":0:525dd") | |
| 174 | 174 | { } |
| 175 | 175 | |
| 176 | 176 | required_device<cpu_device> m_fdccpu; |
| 177 | 177 | required_device<z80ctc_device> m_ctc; |
| 178 | 178 | required_device<acia6850_device> m_acia; |
| 179 | required_device<device_t> m_fdc; | |
| 180 | required_device<device_t> m_floppy; | |
| 179 | required_device<upd765a_device> m_fdc; | |
| 180 | required_device<floppy_image_device> m_floppy; | |
| 181 | 181 | |
| 182 | 182 | virtual void machine_start(); |
| 183 | 183 |
| r18419 | r18420 | |
|---|---|---|
| 51 | 51 | m_epci(*this, SCN2661_TAG), |
| 52 | 52 | m_fdc(*this, UPD765_TAG), |
| 53 | 53 | m_ram(*this, RAM_TAG), |
| 54 | m_floppy0(*this, FLOPPY_0), | |
| 55 | m_floppy1(*this, FLOPPY_1), | |
| 54 | m_floppy0(*this, UPD765_TAG ":0:525dd"), | |
| 55 | m_floppy1(*this, UPD765_TAG ":1:525dd"), | |
| 56 | 56 | m_centronics(*this, CENTRONICS_TAG), |
| 57 | 57 | m_kb(*this, WANGPC_KEYBOARD_TAG), |
| 58 | 58 | m_bus(*this, WANGPC_BUS_TAG), |
| r18419 | r18420 | |
| 82 | 82 | required_device<device_t> m_pit; |
| 83 | 83 | required_device<im6402_device> m_uart; |
| 84 | 84 | required_device<mc2661_device> m_epci; |
| 85 | required_device<device | |
| 85 | required_device<upd765a_device> m_fdc; | |
| 86 | 86 | required_device<ram_device> m_ram; |
| 87 | required_device<legacy_floppy_image_device> m_floppy0; | |
| 88 | required_device<legacy_floppy_image_device> m_floppy1; | |
| 87 | required_device<floppy_image_device> m_floppy0; | |
| 88 | required_device<floppy_image_device> m_floppy1; | |
| 89 | 89 | required_device<centronics_device> m_centronics; |
| 90 | 90 | required_device<wangpc_keyboard_device> m_kb; |
| 91 | 91 | required_device<wangpcbus_device> m_bus; |
| r18419 | r18420 | |
| 161 | 161 | DECLARE_WRITE_LINE_MEMBER( uart_dr_w ); |
| 162 | 162 | DECLARE_WRITE_LINE_MEMBER( uart_tbre_w ); |
| 163 | 163 | DECLARE_WRITE_LINE_MEMBER( epci_irq_w ); |
| 164 | DECLARE_WRITE_LINE_MEMBER( fdc_int_w ); | |
| 165 | DECLARE_WRITE_LINE_MEMBER( fdc_drq_w ); | |
| 166 | 164 | DECLARE_WRITE_LINE_MEMBER( ack_w ); |
| 167 | 165 | DECLARE_WRITE_LINE_MEMBER( busy_w ); |
| 168 | 166 | DECLARE_WRITE_LINE_MEMBER( bus_irq2_w ); |
| 169 | 167 | |
| 170 | static void on_disk0_change(device_image_interface &image); | |
| 171 | static void on_disk1_change(device_image_interface &image); | |
| 168 | void fdc_irq(bool state); | |
| 169 | void fdc_drq(bool state); | |
| 172 | 170 | |
| 171 | int on_disk0_load(floppy_image_device *image); | |
| 172 | void on_disk0_unload(floppy_image_device *image); | |
| 173 | int on_disk1_load(floppy_image_device *image); | |
| 174 | void on_disk1_unload(floppy_image_device *image); | |
| 175 | ||
| 173 | 176 | UINT8 m_dma_page[4]; |
| 174 | 177 | int m_dack; |
| 175 | 178 |
| r18419 | r18420 | |
|---|---|---|
| 110 | 110 | DECLARE_WRITE_LINE_MEMBER(pcw16_com_tx_1); |
| 111 | 111 | DECLARE_WRITE_LINE_MEMBER(pcw16_com_dtr_1); |
| 112 | 112 | DECLARE_WRITE_LINE_MEMBER(pcw16_com_rts_1); |
| 113 | ||
| 114 | void trigger_fdc_int(); | |
| 115 | void fdc_interrupt(bool state); | |
| 113 | 116 | }; |
| 114 | 117 | |
| 115 | 118 | #endif /* PCW16_H_ */ |
| r18419 | r18420 | |
|---|---|---|
| 126 | 126 | DECLARE_WRITE8_MEMBER(mc1502_wd17xx_aux_w); |
| 127 | 127 | DECLARE_READ8_MEMBER(mc1502_wd17xx_drq_r); |
| 128 | 128 | DECLARE_READ8_MEMBER(mc1502_wd17xx_motor_r); |
| 129 | ||
| 130 | void fdc_interrupt(bool state); | |
| 131 | void fdc_dma_drq(bool state); | |
| 129 | 132 | }; |
| 130 | 133 | |
| 131 | 134 | /*----------- defined in machine/pc.c -----------*/ |
| r18419 | r18420 | |
|---|---|---|
| 72 | 72 | DECLARE_READ8_MEMBER(pcw_system_status_r); |
| 73 | 73 | DECLARE_READ8_MEMBER(pcw_expansion_r); |
| 74 | 74 | DECLARE_WRITE8_MEMBER(pcw_expansion_w); |
| 75 | DECLARE_READ8_MEMBER(pcw_fdc_r); | |
| 76 | DECLARE_WRITE8_MEMBER(pcw_fdc_w); | |
| 77 | 75 | DECLARE_WRITE8_MEMBER(pcw_printer_data_w); |
| 78 | 76 | DECLARE_WRITE8_MEMBER(pcw_printer_command_w); |
| 79 | 77 | DECLARE_READ8_MEMBER(pcw_printer_data_r); |
| r18419 | r18420 | |
| 106 | 104 | TIMER_CALLBACK_MEMBER(pcw_pins_callback); |
| 107 | 105 | TIMER_CALLBACK_MEMBER(setup_beep); |
| 108 | 106 | TIMER_DEVICE_CALLBACK_MEMBER(pcw_timer_interrupt); |
| 109 | DECLARE_WRITE_LINE_MEMBER(pcw_fdc_interrupt); | |
| 107 | ||
| 108 | void pcw_fdc_interrupt(bool state); | |
| 110 | 109 | }; |
| 111 | 110 | |
| 112 | 111 | #endif /* PCW_H_ */ |
| r18419 | r18420 | |
|---|---|---|
| 152 | 152 | required_device<centronics_device> m_centronics; |
| 153 | 153 | required_device<i8251_device> m_uart; |
| 154 | 154 | required_device<device_t> m_rtc; |
| 155 | required_device<device | |
| 155 | required_device<upd765a_device> m_fdc; | |
| 156 | 156 | required_device<upd7220_device> m_crtc; |
| 157 | DECLARE_READ16_MEMBER(compis_fdc_dack_r); | |
| 158 | 157 | DECLARE_READ16_MEMBER(compis_usart_r); |
| 159 | 158 | DECLARE_WRITE16_MEMBER(compis_usart_w); |
| 160 | 159 | DECLARE_READ16_MEMBER(compis_i186_internal_port_r); |
| 161 | 160 | DECLARE_WRITE16_MEMBER(compis_i186_internal_port_w); |
| 162 | 161 | DECLARE_WRITE8_MEMBER(vram_w); |
| 163 | DECLARE_WRITE8_MEMBER(compis_fdc_w); | |
| 164 | DECLARE_READ8_MEMBER(compis_fdc_r); | |
| 165 | DECLARE_WRITE_LINE_MEMBER(compis_fdc_int); | |
| 166 | DECLARE_WRITE_LINE_MEMBER(compis_fdc_dma_drq); | |
| 167 | 162 | DECLARE_READ8_MEMBER(compis_ppi_port_b_r); |
| 168 | 163 | DECLARE_WRITE8_MEMBER(compis_ppi_port_c_w); |
| 169 | 164 | DECLARE_READ16_MEMBER(compis_osp_pit_r); |
| r18419 | r18420 | |
| 181 | 176 | void handle_eoi(int data); |
| 182 | 177 | void compis_fdc_tc(int state); |
| 183 | 178 | |
| 179 | void fdc_irq(bool state); | |
| 180 | void fdc_drq(bool state); | |
| 181 | ||
| 184 | 182 | required_shared_ptr<UINT8> m_video_ram; |
| 185 | 183 | DECLARE_DRIVER_INIT(compis); |
| 186 | 184 | virtual void machine_start(); |
| r18419 | r18420 | |
| 201 | 199 | extern const struct pic8259_interface compis_pic8259_master_config; |
| 202 | 200 | extern const struct pic8259_interface compis_pic8259_slave_config; |
| 203 | 201 | extern const i8251_interface compis_usart_interface; |
| 204 | extern const upd765_interface compis_fdc_interface; | |
| 205 | 202 | |
| 206 | 203 | #endif /* COMPIS_H_ */ |
| r18419 | r18420 | |
|---|---|---|
| 27 | 27 | m_cassette(*this, CASSETTE_TAG), |
| 28 | 28 | m_centronics(*this, CENTRONICS_TAG), |
| 29 | 29 | m_ram(*this, RAM_TAG), |
| 30 | m_floppy0(*this, | |
| 30 | m_floppy0(*this, UPD765_TAG ":0:525dd") | |
| 31 | 31 | { } |
| 32 | 32 | |
| 33 | 33 | required_device<cpu_device> m_maincpu; |
| 34 | 34 | required_device<cpu_device> m_fd5cpu; |
| 35 | 35 | required_device<z80ctc_device> m_ctc; |
| 36 | 36 | required_device<i8255_device> m_ppi; |
| 37 | required_device<device | |
| 37 | required_device<upd765a_device> m_fdc; | |
| 38 | 38 | required_device<cassette_image_device> m_cassette; |
| 39 | 39 | required_device<centronics_device> m_centronics; |
| 40 | 40 | required_device<ram_device> m_ram; |
| 41 | required_device<device | |
| 41 | required_device<floppy_image_device> m_floppy0; | |
| 42 | 42 | |
| 43 | 43 | virtual void machine_start(); |
| 44 | 44 | virtual void machine_reset(); |
| r18419 | r18420 | |
| 71 | 71 | DECLARE_DRIVER_INIT(pal); |
| 72 | 72 | DECLARE_DRIVER_INIT(ntsc); |
| 73 | 73 | DECLARE_WRITE_LINE_MEMBER(sordm5_video_interrupt_callback); |
| 74 | ||
| 75 | void fdc_irq(bool state); | |
| 74 | 76 | }; |
| 75 | 77 | |
| 76 | 78 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 39 | 39 | |
| 40 | 40 | #include "machine/upd765.h" |
| 41 | 41 | #include "machine/wd17xx.h" |
| 42 | #include "imagedev/flopdrv.h" | |
| 42 | 43 | |
| 43 | 44 | /* Enum status for high memory bank (c000 - ffff)*/ |
| 44 | 45 | enum |
| r18419 | r18420 | |
| 106 | 107 | UINT8 m_cassette_bit_mem; |
| 107 | 108 | UINT8 m_Data_K7; |
| 108 | 109 | int m_counter_write; |
| 109 | emu_timer *m_DMA_timer; | |
| 110 | emu_timer *m_INT_timer; | |
| 110 | int m_IRQ_current_state; | |
| 111 | 111 | int m_NMI_current_state; |
| 112 | 112 | int m_hector_cmd[10]; |
| 113 | 113 | int m_hector_nb_cde; |
| r18419 | r18420 | |
| 138 | 138 | DECLARE_MACHINE_RESET(hec2mdhrx); |
| 139 | 139 | UINT32 screen_update_hec2hrp(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 140 | 140 | TIMER_CALLBACK_MEMBER(Callback_CK); |
| 141 | ||
| 142 | void disc2_fdc_interrupt(bool state); | |
| 143 | void disc2_fdc_dma_irq(bool state); | |
| 141 | 144 | }; |
| 142 | 145 | |
| 143 | 146 | /*----------- defined in machine/hec2hrp.c -----------*/ |
| r18419 | r18420 | |
| 164 | 167 | /*----------- defined in machine/hecdisk2.c -----------*/ |
| 165 | 168 | |
| 166 | 169 | // disc2 handling |
| 167 | WRITE_LINE_DEVICE_HANDLER( hector_disk2_fdc_interrupt ); | |
| 168 | 170 | DECLARE_READ8_HANDLER( hector_disc2_io00_port_r); |
| 169 | 171 | DECLARE_WRITE8_HANDLER( hector_disc2_io00_port_w); |
| 170 | 172 | DECLARE_READ8_HANDLER( hector_disc2_io20_port_r); |
| r18419 | r18420 | |
| 175 | 177 | DECLARE_WRITE8_HANDLER( hector_disc2_io40_port_w); |
| 176 | 178 | DECLARE_READ8_HANDLER( hector_disc2_io50_port_r); |
| 177 | 179 | DECLARE_WRITE8_HANDLER( hector_disc2_io50_port_w); |
| 178 | DECLARE_READ8_HANDLER( hector_disc2_io61_port_r); | |
| 179 | DECLARE_WRITE8_HANDLER( hector_disc2_io61_port_w); | |
| 180 | DECLARE_READ8_HANDLER( hector_disc2_io70_port_r); | |
| 181 | DECLARE_WRITE8_HANDLER( hector_disc2_io70_port_w); | |
| 182 | 180 | |
| 183 | 181 | void hector_disc2_init( running_machine &machine); |
| 184 | 182 | void hector_minidisc_init( running_machine &machine); |
| 185 | 183 | |
| 186 | extern const upd765_interface hector_disc2_upd765_interface; | |
| 187 | extern const floppy_interface hector_disc2_floppy_interface; | |
| 188 | 184 | extern const wd17xx_interface hector_wd17xx_interface; // Special for minidisc |
| 189 | 185 | extern const floppy_interface minidisc_floppy_interface; |
| r18419 | r18420 | |
|---|---|---|
| 81 | 81 | DECLARE_READ64_MEMBER(scsi53c810_r); |
| 82 | 82 | DECLARE_WRITE64_MEMBER(scsi53c810_w); |
| 83 | 83 | DECLARE_READ64_MEMBER(bb_slave_64be_r); |
| 84 | ||
| 85 | void fdc_interrupt(bool state); | |
| 86 | void fdc_dma_drq(bool state); | |
| 84 | 87 | }; |
| 85 | 88 | |
| 86 | 89 |
| r18419 | r18420 | |
|---|---|---|
| 73 | 73 | DECLARE_WRITE8_MEMBER(nc200_uart_control_w); |
| 74 | 74 | DECLARE_WRITE8_MEMBER(nc200_memory_card_wait_state_w); |
| 75 | 75 | DECLARE_WRITE8_MEMBER(nc200_poweroff_control_w); |
| 76 | ||
| 76 | 77 | virtual void machine_start(); |
| 77 | 78 | virtual void machine_reset(); |
| 78 | 79 | virtual void video_start(); |
| r18419 | r18420 | |
| 91 | 92 | DECLARE_WRITE_LINE_MEMBER(nc200_txrdy_callback); |
| 92 | 93 | DECLARE_WRITE_LINE_MEMBER(nc200_rxrdy_callback); |
| 93 | 94 | DECLARE_WRITE_LINE_MEMBER(nc200_fdc_interrupt); |
| 95 | ||
| 96 | void nc200_fdc_interrupt(bool state); | |
| 94 | 97 | }; |
| 95 | 98 | |
| 96 | 99 |
| r18419 | r18420 | |
|---|---|---|
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "cpu/i86/i86.h" |
| 9 | 9 | #include "cpu/mcs48/mcs48.h" |
| 10 | #include "formats/basicdsk.h" | |
| 11 | 10 | #include "formats/pc_dsk.h" |
| 11 | #include "formats/mfi_dsk.h" | |
| 12 | 12 | #include "imagedev/flopdrv.h" |
| 13 | 13 | #include "machine/am9517a.h" |
| 14 | 14 | #include "machine/ctronics.h" |
| r18419 | r18420 | |
| 19 | 19 | #include "machine/pic8259.h" |
| 20 | 20 | #include "machine/pit8253.h" |
| 21 | 21 | #include "machine/pc1512kb.h" |
| 22 | #include "machine/ | |
| 22 | #include "machine/pc_fdc.h" | |
| 23 | 23 | #include "machine/ram.h" |
| 24 | 24 | #include "sound/speaker.h" |
| 25 | 25 | #include "video/mc6845.h" |
| r18419 | r18420 | |
| 31 | 31 | #define I8259A2_TAG "ic109" |
| 32 | 32 | #define I8253_TAG "ic114" |
| 33 | 33 | #define MC146818_TAG "ic134" |
| 34 | #define | |
| 34 | #define PC_FDC_XT_TAG "ic112" | |
| 35 | 35 | #define INS8250_TAG "ic106" |
| 36 | 36 | #define AMS40041_TAG "ic126" |
| 37 | 37 | #define CENTRONICS_TAG "centronics" |
| r18419 | r18420 | |
| 49 | 49 | m_pic(*this, I8259A2_TAG), |
| 50 | 50 | m_pit(*this, I8253_TAG), |
| 51 | 51 | m_rtc(*this, MC146818_TAG), |
| 52 | m_fdc(*this, | |
| 52 | m_fdc(*this, PC_FDC_XT_TAG), | |
| 53 | 53 | m_uart(*this, INS8250_TAG), |
| 54 | 54 | m_vdu(*this, AMS40041_TAG), |
| 55 | 55 | m_centronics(*this, CENTRONICS_TAG), |
| 56 | 56 | m_speaker(*this, SPEAKER_TAG), |
| 57 | 57 | m_kb(*this, PC1512_KEYBOARD_TAG), |
| 58 | 58 | m_ram(*this, RAM_TAG), |
| 59 | m_floppy0(*this, FLOPPY_0), | |
| 60 | m_floppy1(*this, FLOPPY_1), | |
| 59 | m_floppy0(*this, PC_FDC_XT_TAG ":0:525dd" ), | |
| 60 | m_floppy1(*this, PC_FDC_XT_TAG ":1:525dd" ), | |
| 61 | 61 | m_bus(*this, ISA_BUS_TAG), |
| 62 | 62 | m_pit1(0), |
| 63 | 63 | m_pit2(0), |
| r18419 | r18420 | |
| 84 | 84 | required_device<device_t> m_pic; |
| 85 | 85 | required_device<device_t> m_pit; |
| 86 | 86 | required_device<mc146818_device> m_rtc; |
| 87 | required_device<device | |
| 87 | required_device<pc_fdc_xt_device> m_fdc; | |
| 88 | 88 | required_device<ins8250_device> m_uart; |
| 89 | 89 | required_device<ams40041_device> m_vdu; |
| 90 | 90 | required_device<centronics_device> m_centronics; |
| 91 | 91 | required_device<device_t> m_speaker; |
| 92 | 92 | required_device<pc1512_keyboard_device> m_kb; |
| 93 | 93 | required_device<ram_device> m_ram; |
| 94 | required_device<device_t> m_floppy0; | |
| 95 | optional_device<device_t> m_floppy1; | |
| 94 | required_device<floppy_image_device> m_floppy0; | |
| 95 | optional_device<floppy_image_device> m_floppy1; | |
| 96 | 96 | required_device<isa8_device> m_bus; |
| 97 | 97 | |
| 98 | 98 | virtual void machine_start(); |
| r18419 | r18420 | |
| 234 | 234 | DECLARE_READ8_MEMBER( iga_r ); |
| 235 | 235 | DECLARE_WRITE8_MEMBER( iga_w ); |
| 236 | 236 | DECLARE_READ8_MEMBER( printer_r ); |
| 237 | DECLARE_READ8_MEMBER( io_unmapped_r ); | |
| 237 | 238 | |
| 238 | 239 | // video state |
| 239 | 240 | int m_opt; |
| r18419 | r18420 | |
| 247 | 248 | UINT8 m_crtcar; // CRT controller address register |
| 248 | 249 | UINT8 m_crtcdr[32]; // CRT controller data registers |
| 249 | 250 | UINT8 m_plr; // Plantronics mode register |
| 251 | ||
| 252 | bool test_unmapped; // Temporary for io_r/unmapped_r combination | |
| 250 | 253 | }; |
| 251 | 254 | |
| 252 | 255 | // ---------- defined in video/pc1512.c ---------- |
| r18419 | r18420 | |
|---|---|---|
| 31 | 31 | m_crtc(*this, MC6845_TAG), |
| 32 | 32 | m_centronics(*this, CENTRONICS_TAG), |
| 33 | 33 | m_ram(*this, RAM_TAG), |
| 34 | m_floppy0(*this, FLOPPY_0), | |
| 35 | m_floppy1(*this, FLOPPY_1), | |
| 34 | m_floppy0(*this, UPD765_TAG ":0:525ssdd"), | |
| 35 | m_floppy1(*this, UPD765_TAG ":1:525ssdd"), | |
| 36 | 36 | m_floppy_timer(*this, FLOPPY_TIMER_TAG) |
| 37 | 37 | , |
| 38 | 38 | m_video_ram(*this, "video_ram"){ } |
| r18419 | r18420 | |
| 40 | 40 | required_device<cpu_device> m_maincpu; |
| 41 | 41 | required_device<pia6821_device> m_pia; |
| 42 | 42 | required_device<z80dart_device> m_sio; |
| 43 | required_device<device | |
| 43 | required_device<upd765a_device> m_fdc; | |
| 44 | 44 | required_device<ay3600_device> m_kbc; |
| 45 | 45 | required_device<mc6845_device> m_crtc; |
| 46 | 46 | required_device<centronics_device> m_centronics; |
| 47 | 47 | required_device<ram_device> m_ram; |
| 48 | required_device<device_t> m_floppy0; | |
| 49 | required_device<device_t> m_floppy1; | |
| 48 | required_device<floppy_image_device> m_floppy0; | |
| 49 | required_device<floppy_image_device> m_floppy1; | |
| 50 | 50 | required_device<timer_device> m_floppy_timer; |
| 51 | 51 | |
| 52 | 52 | virtual void machine_start(); |
| r18419 | r18420 | |
| 61 | 61 | |
| 62 | 62 | DECLARE_READ8_MEMBER( ls259_r ); |
| 63 | 63 | DECLARE_WRITE8_MEMBER( ls259_w ); |
| 64 | | |
| 64 | void fdc_intrq_w(bool state); | |
| 65 | 65 | DECLARE_READ8_MEMBER( pia_pa_r ); |
| 66 | 66 | DECLARE_READ_LINE_MEMBER( pia_cb1_r ); |
| 67 | 67 | DECLARE_WRITE_LINE_MEMBER( pia_cb2_w ); |
| r18419 | r18420 | |
|---|---|---|
| 108 | 108 | |
| 109 | 109 | required_device<cpu_device> m_maincpu; |
| 110 | 110 | required_device<device_t> m_ay; |
| 111 | optional_device<device | |
| 111 | optional_device<upd765_family_device> m_fdc; // not on a GX4000 | |
| 112 | 112 | required_device<mc6845_device> m_crtc; |
| 113 | 113 | required_device<screen_device> m_screen; |
| 114 | 114 | required_device<i8255_device> m_ppi; |
| r18419 | r18420 | |
| 184 | 184 | DECLARE_WRITE8_MEMBER(amstrad_ppi_porta_w); |
| 185 | 185 | DECLARE_READ8_MEMBER(amstrad_ppi_portb_r); |
| 186 | 186 | DECLARE_WRITE8_MEMBER(amstrad_ppi_portc_w); |
| 187 | ||
| 188 | void aleste_interrupt(bool state); | |
| 187 | 189 | }; |
| 188 | 190 | |
| 189 | 191 |
| r18419 | r18420 | |
|---|---|---|
| 10 | 10 | #include "machine/mccs1850.h" |
| 11 | 11 | #include "machine/8530scc.h" |
| 12 | 12 | #include "machine/nextkbd.h" |
| 13 | #include "machine/ | |
| 13 | #include "machine/upd765.h" | |
| 14 | 14 | #include "machine/ncr5390.h" |
| 15 | 15 | #include "machine/mb8795.h" |
| 16 | 16 | #include "machine/nextmo.h" |
| r18419 | r18420 | |
|---|---|---|
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "cpu/z80/z80.h" |
| 9 | 9 | #include "cpu/z80/z80daisy.h" |
| 10 | #include "formats/basicdsk.h" | |
| 11 | 10 | #include "imagedev/flopdrv.h" |
| 12 | 11 | #include "machine/ecbbus.h" |
| 13 | 12 | #include "machine/ecb_grip.h" |
| r18419 | r18420 | |
| 38 | 37 | m_rtc(*this, UPD1990A_TAG), |
| 39 | 38 | m_fdc(*this, UPD765_TAG), |
| 40 | 39 | m_ram(*this, RAM_TAG), |
| 41 | m_floppy0(*this, FLOPPY_0), | |
| 42 | m_floppy1(*this, FLOPPY_1), | |
| 40 | m_floppy0(*this, UPD765_TAG ":0:525hd"), | |
| 41 | m_floppy1(*this, UPD765_TAG ":0:525hd"), | |
| 43 | 42 | m_ecb(*this, ECBBUS_TAG) |
| 44 | 43 | { } |
| 45 | 44 | |
| 46 | 45 | required_device<cpu_device> m_maincpu; |
| 47 | 46 | required_device<upd1990a_device> m_rtc; |
| 48 | required_device<device | |
| 47 | required_device<upd765a_device> m_fdc; | |
| 49 | 48 | required_device<ram_device> m_ram; |
| 50 | required_device<device_t> m_floppy0; | |
| 51 | required_device<device_t> m_floppy1; | |
| 49 | optional_device<floppy_image_device> m_floppy0; | |
| 50 | optional_device<floppy_image_device> m_floppy1; | |
| 52 | 51 | required_device<ecbbus_device> m_ecb; |
| 53 | 52 | |
| 54 | 53 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| r18419 | r18420 | |
|---|---|---|
| 140 | 140 | DECLARE_WRITE8_MEMBER(apollo_dma_write_word); |
| 141 | 141 | DECLARE_WRITE8_MEMBER(apollo_rtc_w); |
| 142 | 142 | DECLARE_READ8_MEMBER(apollo_rtc_r); |
| 143 | DECLARE_WRITE8_MEMBER(apollo_fdc_w); | |
| 144 | DECLARE_READ8_MEMBER(apollo_fdc_r); | |
| 145 | 143 | DECLARE_WRITE8_MEMBER(cache_control_register_w); |
| 146 | 144 | DECLARE_READ8_MEMBER(cache_status_register_r); |
| 147 | 145 | DECLARE_WRITE8_MEMBER(task_alias_register_w); |
| r18419 | r18420 | |
| 184 | 182 | virtual void machine_reset(); |
| 185 | 183 | DECLARE_MACHINE_RESET(apollo); |
| 186 | 184 | DECLARE_MACHINE_START(apollo); |
| 185 | ||
| 186 | void fdc_interrupt(bool state); | |
| 187 | void fdc_dma_drq(bool state); | |
| 187 | 188 | }; |
| 188 | 189 | |
| 189 | 190 | MACHINE_CONFIG_EXTERN( apollo ); |
| r18419 | r18420 | |
|---|---|---|
| 10 | 10 | #define X68K_H_ |
| 11 | 11 | |
| 12 | 12 | #include "machine/rp5c15.h" |
| 13 | #include "machine/upd765.h" | |
| 13 | 14 | |
| 14 | 15 | #define MC68901_TAG "mc68901" |
| 15 | 16 | #define RP5C15_TAG "rp5c15" |
| r18419 | r18420 | |
| 67 | 68 | DECLARE_WRITE_LINE_MEMBER( mfp_tdo_w ); |
| 68 | 69 | DECLARE_READ8_MEMBER( mfp_gpio_r ); |
| 69 | 70 | |
| 71 | void fdc_irq(bool state); | |
| 72 | void fdc_drq(bool state); | |
| 73 | ||
| 74 | void floppy_load_unload(); | |
| 75 | int floppy_load(floppy_image_device *dev); | |
| 76 | void floppy_unload(floppy_image_device *dev); | |
| 77 | ||
| 70 | 78 | struct |
| 71 | 79 | { |
| 72 | 80 | int sram_writeprotect; |
| r18419 | r18420 | |
| 77 | 85 | } m_sysport; |
| 78 | 86 | struct |
| 79 | 87 | { |
| 88 | upd72065_device *fdc; | |
| 89 | floppy_image_device *floppy[4]; | |
| 80 | 90 | int led_ctrl[4]; |
| 81 | 91 | int led_eject[4]; |
| 82 | 92 | int eject[4]; |
| 83 | 93 | int motor[4]; |
| 84 | int media_density[4]; | |
| 85 | int disk_inserted[4]; | |
| 86 | 94 | int selected_drive; |
| 87 | 95 | int drq_state; |
| 88 | 96 | } m_fdc; |
| r18419 | r18420 | |
|---|---|---|
| 35 | 35 | m_usart1(*this, I8251_1_TAG), |
| 36 | 36 | m_fdc(*this, UPD765_TAG), |
| 37 | 37 | m_ram(*this, RAM_TAG), |
| 38 | m_floppy0(*this, FLOPPY_0), | |
| 39 | m_floppy1(*this, FLOPPY_1), | |
| 38 | m_floppy0(*this, UPD765_TAG ":0:525dd"), | |
| 39 | m_floppy1(*this, UPD765_TAG ":1:525dd"), | |
| 40 | 40 | m_centronics(*this, CENTRONICS_TAG), |
| 41 | 41 | m_ieee488(*this, IEEE488_TAG), |
| 42 | 42 | m_terminal(*this, TERMINAL_TAG), |
| r18419 | r18420 | |
| 51 | 51 | required_device<device_t> m_pic; |
| 52 | 52 | required_device<i8251_device> m_usart0; |
| 53 | 53 | required_device<i8251_device> m_usart1; |
| 54 | required_device<device | |
| 54 | required_device<upd765a_device> m_fdc; | |
| 55 | 55 | required_device<ram_device> m_ram; |
| 56 | required_device<device_t> m_floppy0; | |
| 57 | required_device<device_t> m_floppy1; | |
| 56 | required_device<floppy_image_device> m_floppy0; | |
| 57 | required_device<floppy_image_device> m_floppy1; | |
| 58 | 58 | required_device<centronics_device> m_centronics; |
| 59 | 59 | required_device<ieee488_device> m_ieee488; |
| 60 | 60 | required_device<generic_terminal_device> m_terminal; |
| 61 | 61 | |
| 62 | virtual void machine_start(); | |
| 62 | 63 | virtual void machine_reset(); |
| 63 | 64 | |
| 64 | 65 | void update_fdc_int(); |
| r18419 | r18420 | |
| 70 | 71 | DECLARE_WRITE8_MEMBER( ppi0_pc_w ); |
| 71 | 72 | DECLARE_READ8_MEMBER( ppi1_pb_r ); |
| 72 | 73 | DECLARE_WRITE8_MEMBER( ppi1_pc_w ); |
| 73 | DECLARE_WRITE_LINE_MEMBER( fdc_int_w ); | |
| 74 | 74 | DECLARE_WRITE_LINE_MEMBER( ack_w ); |
| 75 | 75 | |
| 76 | 76 | DECLARE_WRITE8_MEMBER(kbd_put); |
| 77 | 77 | |
| 78 | 78 | DECLARE_DIRECT_UPDATE_MEMBER(sage2_direct_update_handler); |
| 79 | 79 | |
| 80 | void fdc_irq(bool state); | |
| 81 | ||
| 80 | 82 | int m_reset; |
| 81 | 83 | |
| 82 | 84 | // floppy state |
| r18419 | r18420 | |
|---|---|---|
| 8 | 8 | #include "imagedev/cassette.h" |
| 9 | 9 | #include "machine/ram.h" |
| 10 | 10 | #include "imagedev/printer.h" |
| 11 | #include "formats/basicdsk.h" | |
| 12 | 11 | #include "formats/sc3000_bit.h" |
| 13 | 12 | #include "machine/ctronics.h" |
| 14 | 13 | #include "machine/i8255.h" |
| r18419 | r18420 | |
| 105 | 104 | m_floppy0(*this, FLOPPY_0) |
| 106 | 105 | { } |
| 107 | 106 | |
| 108 | required_device<device | |
| 107 | required_device<upd765a_device> m_fdc; | |
| 109 | 108 | required_device<centronics_device> m_centronics; |
| 110 | 109 | required_device<device_t> m_floppy0; |
| 111 | 110 | |
| r18419 | r18420 | |
| 114 | 113 | |
| 115 | 114 | DECLARE_READ8_MEMBER( ppi_pa_r ); |
| 116 | 115 | DECLARE_WRITE8_MEMBER( ppi_pc_w ); |
| 117 | DECLARE_WRITE_LINE_MEMBER( fdc_intrq_w ); | |
| 118 | 116 | DECLARE_WRITE_LINE_MEMBER(sf7000_fdc_index_callback); |
| 119 | 117 | |
| 118 | void fdc_intrq_w(bool state); | |
| 119 | ||
| 120 | 120 | /* floppy state */ |
| 121 | 121 | int m_fdc_irq; |
| 122 | 122 | int m_fdc_index; |
| r18419 | r18420 | |
|---|---|---|
| 54 | 54 | m_centronics(*this, CENTRONICS_TAG), |
| 55 | 55 | m_speaker(*this, SPEAKER_TAG), |
| 56 | 56 | m_ram(*this, RAM_TAG), |
| 57 | m_floppy0(*this, FLOPPY_0), | |
| 58 | m_floppy1(*this, FLOPPY_1), | |
| 57 | m_floppy0(*this, I8272A_TAG ":0:525qd"), | |
| 58 | m_floppy1(*this, I8272A_TAG ":1:525qd"), | |
| 59 | 59 | m_kb(*this, TANDY2K_KEYBOARD_TAG), |
| 60 | 60 | m_kbdclk(0) |
| 61 | 61 | , |
| r18419 | r18420 | |
| 65 | 65 | required_device<cpu_device> m_maincpu; |
| 66 | 66 | required_device<i8251_device> m_uart; |
| 67 | 67 | required_device<device_t> m_pit; |
| 68 | required_device<device | |
| 68 | required_device<i8272a_device> m_fdc; | |
| 69 | 69 | required_device<device_t> m_pic0; |
| 70 | 70 | required_device<device_t> m_pic1; |
| 71 | 71 | required_device<crt9007_device> m_vpac; |
| r18419 | r18420 | |
| 75 | 75 | required_device<centronics_device> m_centronics; |
| 76 | 76 | required_device<device_t> m_speaker; |
| 77 | 77 | required_device<ram_device> m_ram; |
| 78 | required_device<device_t> m_floppy0; | |
| 79 | required_device<device_t> m_floppy1; | |
| 78 | required_device<floppy_image_device> m_floppy0; | |
| 79 | required_device<floppy_image_device> m_floppy1; | |
| 80 | 80 | required_device<tandy2k_keyboard_device> m_kb; |
| 81 | 81 | |
| 82 | 82 | virtual void machine_start(); |
| r18419 | r18420 | |
| 93 | 93 | DECLARE_READ8_MEMBER( kbint_clr_r ); |
| 94 | 94 | DECLARE_READ16_MEMBER( vpac_r ); |
| 95 | 95 | DECLARE_WRITE16_MEMBER( vpac_w ); |
| 96 | DECLARE_READ8_MEMBER( fldtc_r ); | |
| 97 | DECLARE_WRITE8_MEMBER( fldtc_w ); | |
| 96 | 98 | DECLARE_WRITE8_MEMBER( addr_ctrl_w ); |
| 97 | DECLARE_WRITE_LINE_MEMBER( busdmarq0_w ); | |
| 98 | 99 | DECLARE_WRITE_LINE_MEMBER( rxrdy_w ); |
| 99 | 100 | DECLARE_WRITE_LINE_MEMBER( txrdy_w ); |
| 100 | 101 | DECLARE_WRITE_LINE_MEMBER( outspkr_w ); |
| r18419 | r18420 | |
| 108 | 109 | DECLARE_WRITE_LINE_MEMBER( kbdclk_w ); |
| 109 | 110 | DECLARE_WRITE_LINE_MEMBER( kbddat_w ); |
| 110 | 111 | |
| 112 | void fdc_irq(bool state); | |
| 113 | void fdc_drq(bool state); | |
| 114 | ||
| 111 | 115 | /* DMA state */ |
| 112 | 116 | UINT8 m_dma_mux; |
| 113 | 117 | |
| r18419 | r18420 | |
| 136 | 140 | /* sound state */ |
| 137 | 141 | int m_outspkr; |
| 138 | 142 | int m_spkrdata; |
| 139 | DECLARE_READ8_MEMBER(fldtc_r); | |
| 140 | DECLARE_WRITE8_MEMBER(fldtc_w); | |
| 141 | 143 | }; |
| 142 | 144 | |
| 143 | 145 | #endif |
| r18419 | r18420 | |
|---|---|---|
| 6 | 6 | |
| 7 | 7 | #include "emu.h" |
| 8 | 8 | #include "cpu/i8085/i8085.h" |
| 9 | #include "formats/basicdsk.h" | |
| 10 | 9 | #include "imagedev/flopdrv.h" |
| 11 | 10 | #include "machine/am9517a.h" |
| 12 | 11 | #include "machine/i8212.h" |
| r18419 | r18420 | |
| 42 | 41 | m_mpsc(*this, UPD7201_TAG), |
| 43 | 42 | m_hgdc(*this, UPD7220_TAG), |
| 44 | 43 | m_speaker(*this, SPEAKER_TAG), |
| 45 | m_floppy0(*this, FLOPPY_0), | |
| 46 | m_floppy1(*this, FLOPPY_1), | |
| 44 | m_floppy0(*this, UPD765_TAG ":0:525qd"), | |
| 45 | m_floppy1(*this, UPD765_TAG ":1:525qd"), | |
| 47 | 46 | m_ram(*this, RAM_TAG), |
| 48 | 47 | m_video_ram(*this, "video_ram") |
| 49 | 48 | { } |
| r18419 | r18420 | |
| 53 | 52 | required_device<am9517a_device> m_dmac; |
| 54 | 53 | required_device<device_t> m_pit; |
| 55 | 54 | required_device<device_t> m_crtc; |
| 56 | required_device<device | |
| 55 | required_device<upd765a_device> m_fdc; | |
| 57 | 56 | required_device<upd7201_device> m_mpsc; |
| 58 | 57 | required_device<upd7220_device> m_hgdc; |
| 59 | 58 | required_device<device_t> m_speaker; |
| 60 | required_device<device_t> m_floppy0; | |
| 61 | required_device<device_t> m_floppy1; | |
| 59 | required_device<floppy_image_device> m_floppy0; | |
| 60 | required_device<floppy_image_device> m_floppy1; | |
| 62 | 61 | required_device<ram_device> m_ram; |
| 63 | 62 | required_shared_ptr<UINT8> m_video_ram; |
| 64 | 63 | |
| r18419 | r18420 | |
| 85 | 84 | DECLARE_WRITE_LINE_MEMBER( drq1_w ); |
| 86 | 85 | DECLARE_READ_LINE_MEMBER( dsra_r ); |
| 87 | 86 | DECLARE_PALETTE_INIT(mm1); |
| 87 | DECLARE_READ8_MEMBER(fdc_dma_r); | |
| 88 | DECLARE_WRITE8_MEMBER(fdc_dma_w); | |
| 88 | 89 | |
| 90 | void fdc_irq(bool state); | |
| 91 | void fdc_drq(bool state); | |
| 92 | ||
| 89 | 93 | void scan_keyboard(); |
| 90 | 94 | |
| 91 | 95 | const UINT8 *m_mmu_rom; |
| r18419 | r18420 | |
|---|---|---|
| 244 | 244 | #include "video/upd7220.h" |
| 245 | 245 | #include "imagedev/flopdrv.h" |
| 246 | 246 | #include "machine/ram.h" |
| 247 | #include "formats/mfi_dsk.h" | |
| 247 | 248 | |
| 248 | 249 | #define UPD1990A_TAG "upd1990a" |
| 249 | 250 | #define UPD8251_TAG "upd8251" |
| r18419 | r18420 | |
| 405 | 406 | DECLARE_WRITE8_MEMBER(sdip_a_w); |
| 406 | 407 | DECLARE_WRITE8_MEMBER(sdip_b_w); |
| 407 | 408 | |
| 409 | void fdc_2hd_irq(bool state); | |
| 410 | void fdc_2hd_drq(bool state); | |
| 411 | void fdc_2dd_irq(bool state); | |
| 412 | void fdc_2dd_drq(bool state); | |
| 413 | ||
| 414 | void pc9801rs_fdc_irq(bool state); | |
| 415 | ||
| 408 | 416 | private: |
| 409 | 417 | UINT8 m_sdip_read(UINT16 port, UINT8 sdip_offset); |
| 410 | 418 | void m_sdip_write(UINT16 port, UINT8 sdip_offset,UINT8 data); |
| r18419 | r18420 | |
| 578 | 586 | } |
| 579 | 587 | } |
| 580 | 588 | |
| 589 | static const floppy_format_type pc9801_floppy_formats[] = { | |
| 590 | FLOPPY_MFI_FORMAT, | |
| 591 | NULL | |
| 592 | }; | |
| 581 | 593 | |
| 594 | static SLOT_INTERFACE_START( pc9801_floppies ) | |
| 595 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 596 | SLOT_INTERFACE_END | |
| 597 | ||
| 582 | 598 | static UPD7220_INTERFACE( hgdc_1_intf ) |
| 583 | 599 | { |
| 584 | 600 | "screen", |
| r18419 | r18420 | |
| 1063 | 1079 | { |
| 1064 | 1080 | switch(offset & 6) |
| 1065 | 1081 | { |
| 1066 | case 0: return upd765_status_r(machine().device("upd765_2hd"),space, 0); | |
| 1067 | case 2: return upd765_data_r(machine().device("upd765_2hd"),space, 0); | |
| 1082 | case 0: return machine().device<upd765a_device>("upd765_2hd")->msr_r(space, 0, 0xff); | |
| 1083 | case 2: return machine().device<upd765a_device>("upd765_2hd")->fifo_r(space, 0, 0xff); | |
| 1068 | 1084 | case 4: return 0x5f; //unknown port meaning |
| 1069 | 1085 | } |
| 1070 | 1086 | } |
| r18419 | r18420 | |
| 1090 | 1106 | switch(offset & 6) |
| 1091 | 1107 | { |
| 1092 | 1108 | case 0: printf("Write to undefined port [%02x] <- %02x\n",offset+0x90,data); return; |
| 1093 | case 2: | |
| 1109 | case 2: machine().device<upd765a_device>("upd765_2hd")->fifo_w(space, 0, data, 0xff); return; | |
| 1094 | 1110 | case 4: |
| 1095 | 1111 | printf("%02x ctrl\n",data); |
| 1096 | 1112 | if(((m_fdc_2hd_ctrl & 0x80) == 0) && (data & 0x80)) |
| 1097 | upd765_reset_w(machine().device("upd765_2hd"),1); | |
| 1098 | if((m_fdc_2hd_ctrl & 0x80) && (!(data & 0x80))) | |
| 1099 | upd765_reset_w(machine().device("upd765_2hd"),0); | |
| 1113 | machine().device<upd765a_device>("upd765_2hd")->reset(); | |
| 1100 | 1114 | |
| 1101 | 1115 | m_fdc_2hd_ctrl = data; |
| 1102 | floppy_mon_w(floppy_get_device(machine(), 0), (data & 0x40) ? CLEAR_LINE : ASSERT_LINE); | |
| 1103 | floppy_mon_w(floppy_get_device(machine(), 1), (data & 0x40) ? CLEAR_LINE : ASSERT_LINE); | |
| 1104 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), (data & 0x40), 0); | |
| 1105 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1), (data & 0x40), 0); | |
| 1116 | machine().device<floppy_connector>("upd765_2hd:0")->get_device()->mon_w(!(data & 0x40)); | |
| 1117 | machine().device<floppy_connector>("upd765_2hd:1")->get_device()->mon_w(!(data & 0x40)); | |
| 1106 | 1118 | break; |
| 1107 | 1119 | } |
| 1108 | 1120 | } |
| r18419 | r18420 | |
| 1124 | 1136 | { |
| 1125 | 1137 | switch(offset & 6) |
| 1126 | 1138 | { |
| 1127 | case 0: return upd765_status_r(machine().device("upd765_2dd"),space, 0); | |
| 1128 | case 2: return upd765_data_r(machine().device("upd765_2dd"),space, 0); | |
| 1139 | case 0: return machine().device<upd765a_device>("upd765_2dd")->msr_r(space, 0, 0xff); | |
| 1140 | case 2: return machine().device<upd765a_device>("upd765_2dd")->fifo_r(space, 0, 0xff); | |
| 1129 | 1141 | case 4: return 0x40; //unknown port meaning, might be 0x70 |
| 1130 | 1142 | } |
| 1131 | 1143 | } |
| r18419 | r18420 | |
| 1146 | 1158 | switch(offset & 6) |
| 1147 | 1159 | { |
| 1148 | 1160 | case 0: printf("Write to undefined port [%02x] <- %02x\n",offset+0xc8,data); return; |
| 1149 | case 2: | |
| 1161 | case 2: machine().device<upd765a_device>("upd765_2dd")->fifo_w(space, 0, data, 0xff); return; | |
| 1150 | 1162 | case 4: |
| 1151 | 1163 | printf("%02x ctrl\n",data); |
| 1152 | 1164 | if(((m_fdc_2dd_ctrl & 0x80) == 0) && (data & 0x80)) |
| 1153 | upd765_reset_w(machine().device("upd765_2dd"),1); | |
| 1154 | if((m_fdc_2dd_ctrl & 0x80) && (!(data & 0x80))) | |
| 1155 | upd765_reset_w(machine().device("upd765_2dd"),0); | |
| 1165 | machine().device<upd765a_device>("upd765_2dd")->reset(); | |
| 1156 | 1166 | |
| 1157 | 1167 | m_fdc_2dd_ctrl = data; |
| 1158 | 1168 | //floppy_mon_w(floppy_get_device(machine(), 0), (data & 8) ? CLEAR_LINE : ASSERT_LINE); |
| r18419 | r18420 | |
| 1436 | 1446 | { |
| 1437 | 1447 | switch(offset & 6) |
| 1438 | 1448 | { |
| 1439 | case 0: return upd765_status_r(machine().device("upd765_2hd"),space, 0); | |
| 1440 | case 2: return upd765_data_r(machine().device("upd765_2hd"),space, 0); | |
| 1449 | case 0: return machine().device<upd765a_device>("upd765_2hd")->msr_r(space, 0, 0xff); | |
| 1450 | case 2: return machine().device<upd765a_device>("upd765_2hd")->fifo_r(space, 0, 0xff); | |
| 1441 | 1451 | case 4: return 0x40; //2hd flag |
| 1442 | 1452 | } |
| 1443 | 1453 | } |
| r18419 | r18420 | |
| 1453 | 1463 | { |
| 1454 | 1464 | switch(offset & 6) |
| 1455 | 1465 | { |
| 1456 | case 2: | |
| 1466 | case 2: machine().device<upd765a_device>("upd765_2hd")->fifo_w(space, 0, data, 0xff); return; | |
| 1457 | 1467 | case 4: printf("%02x FDC ctrl\n",data); return; |
| 1458 | 1468 | } |
| 1459 | 1469 | } |
| r18419 | r18420 | |
| 1471 | 1481 | { |
| 1472 | 1482 | switch(offset & 6) |
| 1473 | 1483 | { |
| 1474 | case 0: return upd765_status_r(machine().device("upd765_2hd"),space, 0); | |
| 1475 | case 2: return upd765_data_r(machine().device("upd765_2hd"),space, 0); | |
| 1484 | case 0: return machine().device<upd765a_device>("upd765_2hd")->msr_r(space, 0, 0xff); | |
| 1485 | case 2: return machine().device<upd765a_device>("upd765_2hd")->fifo_r(space, 0, 0xff); | |
| 1476 | 1486 | case 4: return 0x70; //2dd flag |
| 1477 | 1487 | } |
| 1478 | 1488 | } |
| r18419 | r18420 | |
| 1492 | 1502 | { |
| 1493 | 1503 | switch(offset & 6) |
| 1494 | 1504 | { |
| 1495 | case 2: | |
| 1505 | case 2: machine().device<upd765a_device>("upd765_2hd")->fifo_w(space, 0, data, 0xff); return; | |
| 1496 | 1506 | case 4: printf("%02x FDC ctrl\n",data); return; |
| 1497 | 1507 | } |
| 1498 | 1508 | } |
| r18419 | r18420 | |
| 2429 | 2439 | * |
| 2430 | 2440 | ****************************************/ |
| 2431 | 2441 | |
| 2432 | ||
| 2442 | void pc9801_state::fdc_2hd_irq(bool state) | |
| 2433 | 2443 | { |
| 2434 | 2444 | printf("IRQ %d\n",state); |
| 2435 | 2445 | //if(state) |
| 2436 | 2446 | // pic8259_ir3_w(machine().device("pic8259_slave"), state); |
| 2437 | 2447 | } |
| 2438 | 2448 | |
| 2439 | ||
| 2449 | void pc9801_state::fdc_2hd_drq(bool state) | |
| 2440 | 2450 | { |
| 2441 | 2451 | printf("%02x DRQ\n",state); |
| 2442 | 2452 | } |
| 2443 | 2453 | |
| 2444 | ||
| 2454 | void pc9801_state::fdc_2dd_irq(bool state) | |
| 2445 | 2455 | { |
| 2446 | ||
| 2447 | 2456 | printf("IRQ %d\n",state); |
| 2448 | 2457 | |
| 2449 | 2458 | if(m_fdc_2dd_ctrl & 8) |
| r18419 | r18420 | |
| 2452 | 2461 | } |
| 2453 | 2462 | } |
| 2454 | 2463 | |
| 2455 | ||
| 2464 | void pc9801_state::fdc_2dd_drq(bool state) | |
| 2456 | 2465 | { |
| 2457 | 2466 | printf("%02x DRQ\n",state); |
| 2458 | 2467 | } |
| 2459 | 2468 | |
| 2460 | ||
| 2469 | void pc9801_state::pc9801rs_fdc_irq(bool state) | |
| 2461 | 2470 | { |
| 2462 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, fdc_2hd_irq), | |
| 2463 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, fdc_2hd_drq), //DRQ, TODO | |
| 2464 | NULL, | |
| 2465 | UPD765_RDY_PIN_CONNECTED, | |
| 2466 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 2467 | }; | |
| 2468 | ||
| 2469 | static const struct upd765_interface upd765_2dd_intf = | |
| 2470 | { | |
| 2471 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, fdc_2dd_irq), | |
| 2472 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, fdc_2dd_drq), //DRQ, TODO | |
| 2473 | NULL, | |
| 2474 | UPD765_RDY_PIN_CONNECTED, | |
| 2475 | {NULL, NULL, NULL, NULL} | |
| 2476 | }; | |
| 2477 | ||
| 2478 | WRITE_LINE_MEMBER(pc9801_state::pc9801rs_fdc_irq) | |
| 2479 | { | |
| 2480 | ||
| 2481 | 2471 | /* 0xffaf8 */ |
| 2482 | 2472 | |
| 2483 | 2473 | if(m_fdc_ctrl & 1) |
| r18419 | r18420 | |
| 2486 | 2476 | pic8259_ir2_w(machine().device("pic8259_slave"), state); |
| 2487 | 2477 | } |
| 2488 | 2478 | |
| 2489 | static const struct upd765_interface pc9801rs_upd765_intf = | |
| 2490 | { | |
| 2491 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, pc9801rs_fdc_irq), | |
| 2492 | DEVCB_DRIVER_LINE_MEMBER(pc9801_state, fdc_2dd_drq), //DRQ, TODO | |
| 2493 | NULL, | |
| 2494 | UPD765_RDY_PIN_CONNECTED, | |
| 2495 | {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} | |
| 2496 | }; | |
| 2497 | ||
| 2498 | static const floppy_interface pc9801_floppy_interface = | |
| 2499 | { | |
| 2500 | DEVCB_NULL, | |
| 2501 | DEVCB_NULL, | |
| 2502 | DEVCB_NULL, | |
| 2503 | DEVCB_NULL, | |
| 2504 | DEVCB_NULL, | |
| 2505 | FLOPPY_STANDARD_5_25_DSHD, | |
| 2506 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 2507 | "floppy_5_25", | |
| 2508 | NULL | |
| 2509 | }; | |
| 2510 | ||
| 2511 | 2479 | static UPD1990A_INTERFACE( pc9801_upd1990a_intf ) |
| 2512 | 2480 | { |
| 2513 | 2481 | DEVCB_NULL, |
| r18419 | r18420 | |
| 2555 | 2523 | |
| 2556 | 2524 | m_rtc->cs_w(1); |
| 2557 | 2525 | m_rtc->oe_w(1); |
| 2526 | ||
| 2527 | upd765a_device *fdc; | |
| 2528 | fdc = machine().device<upd765a_device>("upd765_2hd"); | |
| 2529 | fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(pc9801_state::fdc_2hd_irq), this)); | |
| 2530 | fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(pc9801_state::fdc_2hd_drq), this)); | |
| 2531 | ||
| 2532 | fdc = machine().device<upd765a_device>("upd765_2dd"); | |
| 2533 | fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(pc9801_state::fdc_2dd_irq), this)); | |
| 2534 | fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(pc9801_state::fdc_2dd_drq), this)); | |
| 2535 | ||
| 2558 | 2536 | } |
| 2559 | 2537 | |
| 2560 | 2538 | MACHINE_RESET_MEMBER(pc9801_state,pc9801) |
| r18419 | r18420 | |
| 2674 | 2652 | MCFG_UPD1990A_ADD(UPD1990A_TAG, XTAL_32_768kHz, pc9801_upd1990a_intf) |
| 2675 | 2653 | MCFG_I8251_ADD(UPD8251_TAG, pc9801_uart_interface) |
| 2676 | 2654 | |
| 2677 | MCFG_UPD765A_ADD("upd765_2hd", upd765_2hd_intf) | |
| 2678 | MCFG_UPD765A_ADD("upd765_2dd", upd765_2dd_intf) | |
| 2679 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(pc9801_floppy_interface) | |
| 2655 | MCFG_UPD765A_ADD("upd765_2hd", true, true) | |
| 2656 | MCFG_UPD765A_ADD("upd765_2dd", true, true) | |
| 2657 | MCFG_FLOPPY_DRIVE_ADD("upd765_2hd:0", pc9801_floppies, "525hd", 0, pc9801_floppy_formats) | |
| 2658 | MCFG_FLOPPY_DRIVE_ADD("upd765_2hd:1", pc9801_floppies, "525hd", 0, pc9801_floppy_formats) | |
| 2659 | ||
| 2680 | 2660 | MCFG_SOFTWARE_LIST_ADD("disk_list","pc98") |
| 2681 | 2661 | |
| 2682 | 2662 | #if 0 |
| r18419 | r18420 | |
| 2737 | 2717 | MCFG_UPD1990A_ADD("upd1990a", XTAL_32_768kHz, pc9801_upd1990a_intf) |
| 2738 | 2718 | MCFG_I8251_ADD(UPD8251_TAG, pc9801_uart_interface) |
| 2739 | 2719 | |
| 2740 | MCFG_UPD765A_ADD("upd765_2hd", | |
| 2720 | MCFG_UPD765A_ADD("upd765_2hd", true, true) | |
| 2741 | 2721 | //"upd765_2dd" |
| 2742 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(pc9801_floppy_interface) | |
| 2722 | MCFG_FLOPPY_DRIVE_ADD("upd765_2hd:0", pc9801_floppies, "525hd", 0, pc9801_floppy_formats) | |
| 2723 | MCFG_FLOPPY_DRIVE_ADD("upd765_2hd:1", pc9801_floppies, "525hd", 0, pc9801_floppy_formats) | |
| 2743 | 2724 | |
| 2744 | 2725 | MCFG_RAM_ADD(RAM_TAG) |
| 2745 | 2726 | MCFG_RAM_DEFAULT_SIZE("640K") |
| r18419 | r18420 | |
| 2797 | 2778 | MCFG_UPD1990A_ADD("upd1990a", XTAL_32_768kHz, pc9801_upd1990a_intf) |
| 2798 | 2779 | MCFG_I8251_ADD(UPD8251_TAG, pc9801_uart_interface) |
| 2799 | 2780 | |
| 2800 | MCFG_UPD765A_ADD("upd765_2hd", | |
| 2781 | MCFG_UPD765A_ADD("upd765_2hd", true, true) | |
| 2801 | 2782 | //"upd765_2dd" |
| 2802 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(pc9801_floppy_interface) | |
| 2783 | MCFG_FLOPPY_DRIVE_ADD("upd765_2hd:0", pc9801_floppies, "525hd", 0, pc9801_floppy_formats) | |
| 2784 | MCFG_FLOPPY_DRIVE_ADD("upd765_2hd:1", pc9801_floppies, "525hd", 0, pc9801_floppy_formats) | |
| 2803 | 2785 | |
| 2804 | 2786 | MCFG_RAM_ADD(RAM_TAG) |
| 2805 | 2787 | MCFG_RAM_DEFAULT_SIZE("640K") |
| r18419 | r18420 | |
|---|---|---|
| 27 | 27 | #include "machine/pit8253.h" |
| 28 | 28 | #include "machine/upd765.h" |
| 29 | 29 | #include "sound/2203intf.h" |
| 30 | #include "formats/basicdsk.h" | |
| 30 | #include "formats/mfi_dsk.h" | |
| 31 | #include "formats/pc_dsk.h" | |
| 32 | #include "formats/xdf_dsk.h" | |
| 31 | 33 | |
| 32 | 34 | struct tsp_t |
| 33 | 35 | { |
| r18419 | r18420 | |
| 119 | 121 | DECLARE_READ8_MEMBER(get_slave_ack); |
| 120 | 122 | DECLARE_WRITE_LINE_MEMBER(pc88va_pit_out0_changed); |
| 121 | 123 | DECLARE_WRITE_LINE_MEMBER(pc88va_upd765_interrupt); |
| 124 | ||
| 125 | void upd765_interrupt(bool state); | |
| 122 | 126 | }; |
| 123 | 127 | |
| 124 | 128 | |
| r18419 | r18420 | |
| 954 | 958 | |
| 955 | 959 | WRITE8_MEMBER(pc88va_state::upd765_mc_w) |
| 956 | 960 | { |
| 957 | floppy_mon_w(floppy_get_device(machine(), 0), (data & 1) ? CLEAR_LINE : ASSERT_LINE); | |
| 958 | floppy_mon_w(floppy_get_device(machine(), 1), (data & 2) ? CLEAR_LINE : ASSERT_LINE); | |
| 959 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), (data & 1), 0); | |
| 960 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1), (data & 2), 0); | |
| 961 | machine().device<floppy_connector>("upd765:0")->get_device()->mon_w(!(data & 1)); | |
| 962 | machine().device<floppy_connector>("upd765:1")->get_device()->mon_w(!(data & 2)); | |
| 961 | 963 | } |
| 962 | 964 | |
| 963 | 965 | TIMER_CALLBACK_MEMBER(pc88va_state::pc8801fd_upd765_tc_to_zero) |
| 964 | 966 | { |
| 965 | ||
| 966 | upd765_tc_w(machine().device("upd765"), 0); | |
| 967 | machine().device<upd765a_device>("upd765")->tc_w(false); | |
| 967 | 968 | } |
| 968 | 969 | |
| 969 | 970 | READ8_MEMBER(pc88va_state::upd765_tc_r) |
| 970 | 971 | { |
| 971 | ||
| 972 | upd765_tc_w(machine().device("upd765"), 1); | |
| 973 | machine().scheduler().timer_set(attotime::from_usec(500), timer_expired_delegate(FUNC(pc88va_state::pc8801fd_upd765_tc_to_zero),this)); | |
| 972 | machine().device<upd765a_device>("upd765")->tc_w(true); | |
| 973 | machine().scheduler().timer_set(attotime::from_usec(50), timer_expired_delegate(FUNC(pc88va_state::pc8801fd_upd765_tc_to_zero),this)); | |
| 974 | 974 | return 0; |
| 975 | 975 | } |
| 976 | 976 | |
| r18419 | r18420 | |
| 986 | 986 | /* ---x ---- RDY: (0) Busy (1) Ready */ |
| 987 | 987 | case 0x06: // FDC control port 2 |
| 988 | 988 | return 0; |
| 989 | case 0x08: return upd765_status_r(machine().device("upd765"), space, 0); | |
| 990 | case 0x0a: return upd765_data_r(machine().device("upd765"), space, 0); | |
| 991 | 989 | } |
| 992 | 990 | |
| 993 | 991 | return 0xff; |
| r18419 | r18420 | |
| 1028 | 1026 | case 0x06: |
| 1029 | 1027 | printf("%02x\n",data); |
| 1030 | 1028 | break; // FDC control port 2 |
| 1031 | case 0x08: break; // UPD765 status | |
| 1032 | case 0x0a: upd765_data_w(machine().device("upd765"), space, 0,data); break; | |
| 1033 | 1029 | } |
| 1034 | 1030 | } |
| 1035 | 1031 | |
| r18419 | r18420 | |
| 1154 | 1150 | AM_RANGE(0x019a, 0x019b) AM_WRITE(backupram_wp_0_w) //Backup RAM write permission |
| 1155 | 1151 | AM_RANGE(0x01a0, 0x01a7) AM_DEVREADWRITE8_LEGACY("pit8253", pit8253_r, pit8253_w, 0x00ff)// vTCU (timer counter unit) |
| 1156 | 1152 | AM_RANGE(0x01a8, 0x01a9) AM_WRITE8(timer3_ctrl_reg_w,0x00ff) // General-purpose timer 3 control port |
| 1157 | AM_RANGE(0x01b0, 0x01bb) AM_READWRITE8(pc88va_fdc_r,pc88va_fdc_w,0x00ff)// FDC related (765) | |
| 1153 | AM_RANGE(0x01b0, 0x01b7) AM_READWRITE8(pc88va_fdc_r,pc88va_fdc_w,0x00ff)// FDC related (765) | |
| 1154 | AM_RANGE(0x01b8, 0x01bb) AM_DEVICE8("upd765", upd765a_device, map, 0x00ff) | |
| 1158 | 1155 | // AM_RANGE(0x01c0, 0x01c1) ? |
| 1159 | 1156 | AM_RANGE(0x01c6, 0x01c7) AM_WRITENOP // ??? |
| 1160 | 1157 | AM_RANGE(0x01c8, 0x01cf) AM_DEVREADWRITE8("d8255_3", i8255_device, read, write,0xff00) //i8255 3 (byte access) |
| r18419 | r18420 | |
| 1187 | 1184 | AM_RANGE(0xf0, 0xf0) AM_WRITE(fdc_irq_vector_w) // Interrupt Opcode Port |
| 1188 | 1185 | // AM_RANGE(0xf4, 0xf4) // Drive Control Port |
| 1189 | 1186 | AM_RANGE(0xf8, 0xf8) AM_READWRITE(upd765_tc_r,upd765_mc_w) // (R) Terminal Count Port (W) Motor Control Port |
| 1190 | AM_RANGE(0xfa, 0xfa) AM_DEVREAD_LEGACY("upd765", upd765_status_r ) | |
| 1191 | AM_RANGE(0xfb, 0xfb) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w ) | |
| 1187 | AM_RANGE(0xfa, 0xfb) AM_DEVICE("upd765", upd765a_device, map ) | |
| 1192 | 1188 | AM_RANGE(0xfc, 0xff) AM_DEVREADWRITE("d8255_2s", i8255_device, read, write) |
| 1193 | 1189 | ADDRESS_MAP_END |
| 1194 | 1190 | |
| r18419 | r18420 | |
| 1545 | 1541 | |
| 1546 | 1542 | m_t3_mouse_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(pc88va_state::t3_mouse_callback),this)); |
| 1547 | 1543 | m_t3_mouse_timer->adjust(attotime::never); |
| 1544 | machine().device<upd765a_device>("upd765")->setup_intrq_cb(upd765a_device::line_cb(FUNC(pc88va_state::upd765_interrupt), this)); | |
| 1548 | 1545 | } |
| 1549 | 1546 | |
| 1550 | 1547 | void pc88va_state::machine_reset() |
| r18419 | r18420 | |
| 1578 | 1575 | pic8259_ir2_w(machine().device("pic8259_master"), 1); |
| 1579 | 1576 | } |
| 1580 | 1577 | |
| 1581 | /* Not sure if parameters are correct for pc88va (copied from x68k) */ | |
| 1582 | static LEGACY_FLOPPY_OPTIONS_START( pc88va ) | |
| 1583 | LEGACY_FLOPPY_OPTION( img2d, "xdf,hdm,2hd", "XDF disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 1584 | HEADS([2]) | |
| 1585 | TRACKS([77]) | |
| 1586 | SECTORS([8]) | |
| 1587 | SECTOR_LENGTH([1024]) | |
| 1588 | FIRST_SECTOR_ID([1])) | |
| 1589 | LEGACY_FLOPPY_OPTIONS_END | |
| 1590 | ||
| 1591 | static const floppy_interface pc88va_floppy_interface = | |
| 1592 | { | |
| 1593 | DEVCB_NULL, | |
| 1594 | DEVCB_NULL, | |
| 1595 | DEVCB_NULL, | |
| 1596 | DEVCB_NULL, | |
| 1597 | DEVCB_NULL, | |
| 1598 | FLOPPY_STANDARD_5_25_DSHD, | |
| 1599 | LEGACY_FLOPPY_OPTIONS_NAME(pc88va), | |
| 1600 | "floppy_5_25", | |
| 1601 | NULL | |
| 1602 | }; | |
| 1603 | ||
| 1604 | ||
| 1605 | 1578 | WRITE_LINE_MEMBER(pc88va_state::pc88va_pit_out0_changed) |
| 1606 | 1579 | { |
| 1607 | 1580 | pic8259_ir0_w(machine().device("pic8259_master"), 1); |
| r18419 | r18420 | |
| 1632 | 1605 | }; |
| 1633 | 1606 | |
| 1634 | 1607 | |
| 1635 | ||
| 1608 | void pc88va_state::upd765_interrupt(bool state) | |
| 1636 | 1609 | { |
| 1637 | 1610 | if(m_fdc_mode) |
| 1638 | 1611 | pic8259_ir3_w(machine().device( "pic8259_slave"), state); |
| 1639 | 1612 | else |
| 1640 | 1613 | machine().device("fdccpu")->execute().set_input_line(0, HOLD_LINE); |
| 1641 | } | |
| 1614 | } | |
| 1642 | 1615 | |
| 1643 | static const struct upd765_interface pc88va_upd765_interface = | |
| 1644 | { | |
| 1645 | DEVCB_DRIVER_LINE_MEMBER(pc88va_state, pc88va_upd765_interrupt), | |
| 1646 | DEVCB_NULL, //DRQ, TODO | |
| 1647 | NULL, | |
| 1648 | UPD765_RDY_PIN_CONNECTED, | |
| 1649 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 1650 | }; | |
| 1651 | 1616 | |
| 1652 | 1617 | static const ym2203_interface pc88va_ym2203_intf = |
| 1653 | 1618 | { |
| r18419 | r18420 | |
| 1662 | 1627 | DEVCB_NULL |
| 1663 | 1628 | }; |
| 1664 | 1629 | |
| 1630 | static const floppy_format_type pc88va_floppy_formats[] = { | |
| 1631 | FLOPPY_PC_FORMAT, | |
| 1632 | FLOPPY_XDF_FORMAT, | |
| 1633 | FLOPPY_MFI_FORMAT, | |
| 1634 | NULL | |
| 1635 | }; | |
| 1636 | ||
| 1637 | static SLOT_INTERFACE_START( pc88va_floppies ) | |
| 1638 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 1639 | SLOT_INTERFACE_END | |
| 1640 | ||
| 1665 | 1641 | static MACHINE_CONFIG_START( pc88va, pc88va_state ) |
| 1666 | 1642 | |
| 1667 | 1643 | MCFG_CPU_ADD("maincpu", V30, 8000000) /* 8 MHz */ |
| r18419 | r18420 | |
| 1695 | 1671 | MCFG_PIC8259_ADD( "pic8259_master", pc88va_pic8259_master_config ) |
| 1696 | 1672 | MCFG_PIC8259_ADD( "pic8259_slave", pc88va_pic8259_slave_config ) |
| 1697 | 1673 | |
| 1698 | MCFG_UPD765A_ADD("upd765", pc88va_upd765_interface) | |
| 1699 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(pc88va_floppy_interface) | |
| 1674 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 1675 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", pc88va_floppies, "525hd", 0, pc88va_floppy_formats) | |
| 1676 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", pc88va_floppies, "525hd", 0, pc88va_floppy_formats) | |
| 1700 | 1677 | MCFG_SOFTWARE_LIST_ADD("disk_list","pc88va") |
| 1701 | 1678 | |
| 1702 | 1679 | MCFG_PIT8253_ADD("pit8253",pc88va_pit8253_config) |
| r18419 | r18420 | |
|---|---|---|
| 458 | 458 | } |
| 459 | 459 | |
| 460 | 460 | |
| 461 | ||
| 462 | 461 | //************************************************************************** |
| 463 | // | |
| 462 | // PC1640 I/O ACCESS | |
| 464 | 463 | //************************************************************************** |
| 465 | 464 | |
| 466 | 465 | //------------------------------------------------- |
| 467 | // | |
| 466 | // io_r - | |
| 468 | 467 | //------------------------------------------------- |
| 469 | 468 | |
| 470 | READ8_MEMBER( pc1 | |
| 469 | READ8_MEMBER( pc1640_state::io_unmapped_r ) | |
| 471 | 470 | { |
| 472 | UINT8 data = 0; | |
| 473 | ||
| 474 | switch (offset) | |
| 475 | { | |
| 476 | case 4: | |
| 477 | data = upd765_status_r(m_fdc, space, 0); | |
| 478 | break; | |
| 479 | ||
| 480 | case 5: | |
| 481 | data = upd765_data_r(m_fdc, space, 0); | |
| 482 | break; | |
| 483 | } | |
| 484 | ||
| 485 | return data; | |
| 471 | test_unmapped = true; | |
| 472 | return 0xff; | |
| 486 | 473 | } |
| 487 | 474 | |
| 488 | 475 | |
| 489 | //------------------------------------------------- | |
| 490 | // fdc_w - | |
| 491 | //------------------------------------------------- | |
| 492 | ||
| 493 | void pc1512_state::set_fdc_dsr(UINT8 data) | |
| 494 | { | |
| 495 | /* | |
| 496 | ||
| 497 | bit description | |
| 498 | ||
| 499 | 0 Drive Select Bit 0 (DS0) | |
| 500 | 1 Drive Select Bit 1 (DS1) | |
| 501 | 2 765A reset | |
| 502 | 3 Allow 765A FDC to interrupt and request DMA | |
| 503 | 4 Switch motor(s) on and enable drive 0 selection | |
| 504 | 5 Switch motor(s) on and enable drive 1 selection | |
| 505 | 6 | |
| 506 | 7 | |
| 507 | ||
| 508 | */ | |
| 509 | ||
| 510 | m_fdc_dsr = data; | |
| 511 | ||
| 512 | m_nden = BIT(data, 3); | |
| 513 | update_fdc_int(); | |
| 514 | update_fdc_drq(); | |
| 515 | update_fdc_tc(); | |
| 516 | ||
| 517 | upd765_reset_w(m_fdc, BIT(data, 2)); | |
| 518 | ||
| 519 | floppy_mon_w(m_floppy0, BIT(data, 4) ? CLEAR_LINE : ASSERT_LINE); | |
| 520 | floppy_mon_w(m_floppy1, BIT(data, 5) ? CLEAR_LINE : ASSERT_LINE); | |
| 521 | } | |
| 522 | ||
| 523 | WRITE8_MEMBER( pc1512_state::fdc_w ) | |
| 524 | { | |
| 525 | switch (offset) | |
| 526 | { | |
| 527 | case 2: | |
| 528 | set_fdc_dsr(data); | |
| 529 | break; | |
| 530 | ||
| 531 | case 5: | |
| 532 | upd765_data_w(m_fdc, space, 0, data); | |
| 533 | break; | |
| 534 | } | |
| 535 | } | |
| 536 | ||
| 537 | ||
| 538 | ||
| 539 | //************************************************************************** | |
| 540 | // PC1640 I/O ACCESS | |
| 541 | //************************************************************************** | |
| 542 | ||
| 543 | //------------------------------------------------- | |
| 544 | // io_r - | |
| 545 | //------------------------------------------------- | |
| 546 | ||
| 547 | 476 | READ8_MEMBER( pc1640_state::io_r ) |
| 548 | 477 | { |
| 549 | UINT8 data = 0; | |
| 550 | offs_t addr = offset & 0x3ff; | |
| 551 | bool decoded = false; | |
| 478 | test_unmapped = false; | |
| 552 | 479 | |
| 553 | if ( addr <= 0x00f) { data = m_dmac->read(space, offset & 0x0f); decoded = true; } | |
| 554 | else if (addr >= 0x020 && addr <= 0x021) { data = pic8259_r(m_pic, space, offset & 0x01); decoded = true; } | |
| 555 | else if (addr >= 0x040 && addr <= 0x043) { data = pit8253_r(m_pit, space, offset & 0x03); decoded = true; } | |
| 556 | else if (addr >= 0x060 && addr <= 0x06f) { data = system_r(space, offset & 0x0f); decoded = true; } | |
| 557 | else if (addr >= 0x070 && addr <= 0x073) { data = m_rtc->read(space, offset & 0x01); decoded = true; } | |
| 558 | else if (addr >= 0x078 && addr <= 0x07f) { data = mouse_r(space, offset & 0x07); decoded = true; } | |
| 559 | else if (addr >= 0x378 && addr <= 0x37b) { data = printer_r(space, offset & 0x03); decoded = true; } | |
| 560 | else if (addr >= 0x3b0 && addr <= 0x3df) { data = iga_r(space, addr - 0x3b0); decoded = true; } | |
| 561 | else if (addr >= 0x3f0 && addr <= 0x3f7) { data = fdc_r(space, offset & 0x07); decoded = true; } | |
| 562 | else if (addr >= 0x3f8 && addr <= 0x3ff) { data = m_uart->ins8250_r(space, offset & 0x07); decoded = true; } | |
| 480 | UINT8 data = space.read_byte(offset + 0x10000); | |
| 563 | 481 | |
| 564 | if ( | |
| 482 | if (!test_unmapped) | |
| 565 | 483 | { |
| 566 | 484 | if (BIT(offset, 7)) |
| 567 | 485 | { |
| r18419 | r18420 | |
| 621 | 539 | AM_RANGE(0x0a0, 0x0a1) AM_WRITE8(nmi_mask_w, 0xff00) |
| 622 | 540 | AM_RANGE(0x378, 0x37b) AM_READWRITE8(printer_r, printer_w, 0xffff) |
| 623 | 541 | AM_RANGE(0x3d0, 0x3df) AM_READWRITE8(vdu_r, vdu_w, 0xffff) |
| 624 | AM_RANGE(0x3f0, 0x3f7) AM_ | |
| 542 | AM_RANGE(0x3f0, 0x3f7) AM_DEVICE8(PC_FDC_XT_TAG, pc_fdc_xt_device, map, 0xffff) | |
| 625 | 543 | AM_RANGE(0x3f8, 0x3ff) AM_DEVREADWRITE8(INS8250_TAG, ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 626 | 544 | ADDRESS_MAP_END |
| 627 | 545 | |
| r18419 | r18420 | |
| 645 | 563 | |
| 646 | 564 | static ADDRESS_MAP_START( pc1640_io, AS_IO, 16, pc1640_state ) |
| 647 | 565 | AM_RANGE(0x0000, 0xffff) AM_READ8(io_r, 0xffff) |
| 648 | AM_RANGE(0x000, 0x00f) AM_DEVWRITE8(I8237A5_TAG, am9517a_device, write, 0xffff) | |
| 649 | AM_RANGE(0x020, 0x021) AM_DEVWRITE8_LEGACY(I8259A2_TAG, pic8259_w, 0xffff) | |
| 650 | AM_RANGE(0x040, 0x043) AM_DEVWRITE8_LEGACY(I8253_TAG, pit8253_w, 0xffff) | |
| 651 | AM_RANGE(0x060, 0x06f) AM_WRITE8(system_w, 0xffff) | |
| 652 | AM_RANGE(0x070, 0x071) AM_MIRROR(0x02) AM_DEVWRITE8(MC146818_TAG, mc146818_device, write, 0xffff) | |
| 653 | AM_RANGE(0x078, 0x07f) AM_WRITE8(mouse_w, 0xffff) | |
| 654 | AM_RANGE(0x080, 0x083) AM_WRITE8(dma_page_w, 0xffff) | |
| 655 | AM_RANGE(0x0a0, 0x0a1) AM_WRITE8(nmi_mask_w, 0xff00) | |
| 656 | AM_RANGE(0x378, 0x37b) AM_WRITE8(printer_w, 0xffff) | |
| 657 | AM_RANGE(0x3b0, 0x3df) AM_WRITE8(iga_w, 0xffff) | |
| 658 | AM_RANGE(0x3f0, 0x3f7) AM_WRITE8(fdc_w, 0xffff) | |
| 659 | AM_RANGE(0x3f8, 0x3ff) AM_DEVWRITE8(INS8250_TAG, ins8250_device, ins8250_w, 0xffff) | |
| 566 | ||
| 567 | // Mirrored over to 10000 for indirect reads through io_r | |
| 568 | ||
| 569 | AM_RANGE(0x000, 0x00f) AM_MIRROR(0x10000) AM_DEVWRITE8(I8237A5_TAG, am9517a_device, write, 0xffff) | |
| 570 | AM_RANGE(0x020, 0x021) AM_MIRROR(0x10000) AM_DEVWRITE8_LEGACY(I8259A2_TAG, pic8259_w, 0xffff) | |
| 571 | AM_RANGE(0x040, 0x043) AM_MIRROR(0x10000) AM_DEVWRITE8_LEGACY(I8253_TAG, pit8253_w, 0xffff) | |
| 572 | AM_RANGE(0x060, 0x06f) AM_MIRROR(0x10000) AM_WRITE8(system_w, 0xffff) | |
| 573 | AM_RANGE(0x070, 0x071) AM_MIRROR(0x10000) AM_MIRROR(0x02) AM_DEVWRITE8(MC146818_TAG, mc146818_device, write, 0xffff) | |
| 574 | AM_RANGE(0x078, 0x07f) AM_MIRROR(0x10000) AM_WRITE8(mouse_w, 0xffff) | |
| 575 | AM_RANGE(0x080, 0x083) AM_MIRROR(0x10000) AM_WRITE8(dma_page_w, 0xffff) | |
| 576 | AM_RANGE(0x0a0, 0x0a1) AM_MIRROR(0x10000) AM_WRITE8(nmi_mask_w, 0xff00) | |
| 577 | AM_RANGE(0x378, 0x37b) AM_MIRROR(0x10000) AM_WRITE8(printer_w, 0xffff) | |
| 578 | AM_RANGE(0x3b0, 0x3df) AM_MIRROR(0x10000) AM_WRITE8(iga_w, 0xffff) | |
| 579 | AM_RANGE(0x3f0, 0x3f7) AM_MIRROR(0x10000) AM_DEVICE8(PC_FDC_XT_TAG, pc_fdc_xt_device, map, 0xffff) | |
| 580 | AM_RANGE(0x3f8, 0x3ff) AM_MIRROR(0x10000) AM_DEVWRITE8(INS8250_TAG, ins8250_device, ins8250_w, 0xffff) | |
| 581 | AM_RANGE(0x10000, 0x1ffff) AM_READ8(io_unmapped_r, 0xffff) | |
| 660 | 582 | ADDRESS_MAP_END |
| 661 | 583 | |
| 662 | 584 | |
| r18419 | r18420 | |
| 865 | 787 | void pc1512_state::update_fdc_tc() |
| 866 | 788 | { |
| 867 | 789 | if (m_nden) |
| 868 | | |
| 790 | m_fdc->tc_w(m_neop); | |
| 869 | 791 | else |
| 870 | | |
| 792 | m_fdc->tc_w(false); | |
| 871 | 793 | } |
| 872 | 794 | |
| 873 | 795 | WRITE_LINE_MEMBER( pc1512_state::hrq_w ) |
| r18419 | r18420 | |
| 910 | 832 | READ8_MEMBER( pc1512_state::ior2_r ) |
| 911 | 833 | { |
| 912 | 834 | if (m_nden) |
| 913 | return | |
| 835 | return m_fdc->dma_r(); | |
| 914 | 836 | else |
| 915 | 837 | return m_bus->dack_r(2); |
| 916 | 838 | } |
| r18419 | r18420 | |
| 934 | 856 | WRITE8_MEMBER( pc1512_state::iow2_w ) |
| 935 | 857 | { |
| 936 | 858 | if (m_nden) |
| 937 | | |
| 859 | m_fdc->dma_w(data); | |
| 938 | 860 | else |
| 939 | 861 | m_bus->dack_w(2, data); |
| 940 | 862 | } |
| r18419 | r18420 | |
| 1105 | 1027 | update_fdc_drq(); |
| 1106 | 1028 | } |
| 1107 | 1029 | |
| 1108 | static UPD765_GET_IMAGE( pc1512_fdc_get_image ) | |
| 1109 | { | |
| 1110 | pc1512_state *state = device->machine().driver_data<pc1512_state>(); | |
| 1111 | ||
| 1112 | if (BIT(state->m_fdc_dsr, 0)) | |
| 1113 | return state->m_floppy1; | |
| 1114 | else | |
| 1115 | return state->m_floppy0; | |
| 1116 | } | |
| 1117 | ||
| 1118 | static const upd765_interface fdc_intf = | |
| 1119 | { | |
| 1120 | DEVCB_DRIVER_LINE_MEMBER(pc1512_state, fdc_int_w), | |
| 1121 | DEVCB_DRIVER_LINE_MEMBER(pc1512_state, fdc_drq_w), | |
| 1122 | pc1512_fdc_get_image, | |
| 1123 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 1124 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 1125 | }; | |
| 1126 | ||
| 1127 | ||
| 1128 | 1030 | //------------------------------------------------- |
| 1129 | 1031 | // ins8250_interface uart_intf |
| 1130 | 1032 | //------------------------------------------------- |
| r18419 | r18420 | |
| 1190 | 1092 | DEVCB_DEVICE_LINE_MEMBER(I8237A5_TAG, am9517a_device, dreq3_w) |
| 1191 | 1093 | }; |
| 1192 | 1094 | |
| 1095 | static const floppy_format_type ibmpc_floppy_formats[] = { | |
| 1096 | FLOPPY_PC_FORMAT, | |
| 1097 | FLOPPY_MFI_FORMAT, | |
| 1098 | NULL | |
| 1099 | }; | |
| 1193 | 1100 | |
| 1101 | static SLOT_INTERFACE_START( ibmpc_floppies ) | |
| 1102 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 1103 | SLOT_INTERFACE_END | |
| 1194 | 1104 | |
| 1105 | ||
| 1195 | 1106 | //************************************************************************** |
| 1196 | 1107 | // MACHINE INITIALIZATION |
| 1197 | 1108 | //************************************************************************** |
| r18419 | r18420 | |
| 1233 | 1144 | save_item(NAME(m_nden)); |
| 1234 | 1145 | save_item(NAME(m_dint)); |
| 1235 | 1146 | save_item(NAME(m_ddrq)); |
| 1236 | save_item(NAME(m_fdc_dsr)); | |
| 1237 | 1147 | save_item(NAME(m_neop)); |
| 1238 | 1148 | save_item(NAME(m_ack_int_enable)); |
| 1239 | 1149 | save_item(NAME(m_ack)); |
| r18419 | r18420 | |
| 1263 | 1173 | m_toggle = 0; |
| 1264 | 1174 | m_kb_bits = 0; |
| 1265 | 1175 | |
| 1266 | set_fdc_dsr(0); | |
| 1267 | ||
| 1268 | 1176 | m_lpen = 0; |
| 1269 | 1177 | m_blink = 0; |
| 1270 | 1178 | m_cursor = 0; |
| r18419 | r18420 | |
| 1307 | 1215 | save_item(NAME(m_nden)); |
| 1308 | 1216 | save_item(NAME(m_dint)); |
| 1309 | 1217 | save_item(NAME(m_ddrq)); |
| 1310 | save_item(NAME(m_fdc_dsr)); | |
| 1311 | 1218 | save_item(NAME(m_neop)); |
| 1312 | 1219 | save_item(NAME(m_ack_int_enable)); |
| 1313 | 1220 | save_item(NAME(m_ack)); |
| r18419 | r18420 | |
| 1325 | 1232 | { |
| 1326 | 1233 | m_nmi_enable = 0; |
| 1327 | 1234 | m_kb_bits = 0; |
| 1328 | ||
| 1329 | set_fdc_dsr(0); | |
| 1330 | ||
| 1331 | 1235 | m_kb->clock_w(0); |
| 1332 | 1236 | } |
| 1333 | 1237 | |
| r18419 | r18420 | |
| 1360 | 1264 | MCFG_PIC8259_ADD(I8259A2_TAG, pic_intf) |
| 1361 | 1265 | MCFG_PIT8253_ADD(I8253_TAG, pit_intf) |
| 1362 | 1266 | MCFG_MC146818_IRQ_ADD(MC146818_TAG, MC146818_STANDARD, rtc_intf) |
| 1363 | MCFG_ | |
| 1267 | MCFG_PC_FDC_XT_ADD(PC_FDC_XT_TAG) | |
| 1364 | 1268 | MCFG_INS8250_ADD(INS8250_TAG, uart_intf, XTAL_1_8432MHz) |
| 1365 | 1269 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 1366 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf) | |
| 1270 | MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1271 | MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1367 | 1272 | |
| 1368 | 1273 | // ISA8 bus |
| 1369 | 1274 | MCFG_ISA8_BUS_ADD(ISA_BUS_TAG, I8086_TAG, isabus_intf) |
| r18419 | r18420 | |
| 1404 | 1309 | MCFG_PIC8259_ADD(I8259A2_TAG, pic_intf) |
| 1405 | 1310 | MCFG_PIT8253_ADD(I8253_TAG, pit_intf) |
| 1406 | 1311 | MCFG_MC146818_IRQ_ADD(MC146818_TAG, MC146818_STANDARD, rtc_intf) |
| 1407 | MCFG_ | |
| 1312 | MCFG_PC_FDC_XT_ADD(PC_FDC_XT_TAG) | |
| 1408 | 1313 | MCFG_INS8250_ADD(INS8250_TAG, uart_intf, XTAL_1_8432MHz) |
| 1409 | 1314 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 1410 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf) | |
| 1315 | MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1316 | MCFG_FLOPPY_DRIVE_ADD(PC_FDC_XT_TAG ":1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1411 | 1317 | |
| 1412 | 1318 | // ISA8 bus |
| 1413 | 1319 | MCFG_ISA8_BUS_ADD(ISA_BUS_TAG, I8086_TAG, isabus_intf) |
| r18419 | r18420 | |
|---|---|---|
| 51 | 51 | */ |
| 52 | 52 | |
| 53 | 53 | #include "includes/mikromik.h" |
| 54 | #include "formats/mfi_dsk.h" | |
| 55 | #include "formats/mm_dsk.h" | |
| 54 | 56 | |
| 55 | 57 | |
| 56 | ||
| 57 | 58 | //************************************************************************** |
| 58 | 59 | // MACROS / CONSTANTS |
| 59 | 60 | //************************************************************************** |
| r18419 | r18420 | |
| 110 | 111 | case 5: |
| 111 | 112 | if (BIT(offset, 0)) |
| 112 | 113 | { |
| 113 | data = | |
| 114 | data = m_fdc->fifo_r(space, 0, 0xff); | |
| 114 | 115 | } |
| 115 | 116 | else |
| 116 | 117 | { |
| 117 | data = | |
| 118 | data = m_fdc->msr_r(space, 0, 0xff); | |
| 118 | 119 | } |
| 119 | 120 | break; |
| 120 | 121 | |
| r18419 | r18420 | |
| 179 | 180 | case 5: |
| 180 | 181 | if (BIT(offset, 0)) |
| 181 | 182 | { |
| 182 | | |
| 183 | m_fdc->fifo_w(space, 0, data, 0xff); | |
| 183 | 184 | } |
| 184 | 185 | break; |
| 185 | 186 | |
| r18419 | r18420 | |
| 220 | 221 | case 1: // RECALL |
| 221 | 222 | if (LOG) logerror("RECALL %u\n", d); |
| 222 | 223 | m_recall = d; |
| 223 | upd765_reset_w(m_fdc, d); | |
| 224 | if(d) | |
| 225 | m_fdc->reset(); | |
| 224 | 226 | break; |
| 225 | 227 | |
| 226 | 228 | case 2: // _RV28/RX21 |
| r18419 | r18420 | |
| 246 | 248 | |
| 247 | 249 | case 7: // MOTOR ON |
| 248 | 250 | if (LOG) logerror("MOTOR %u\n", d); |
| 249 | floppy_mon_w(m_floppy0, !d); | |
| 250 | floppy_mon_w(m_floppy1, !d); | |
| 251 | floppy_drive_set_ready_state(m_floppy0, d, 1); | |
| 252 | floppy_drive_set_ready_state(m_floppy1, d, 1); | |
| 251 | m_floppy0->mon_w(!d); | |
| 252 | m_floppy1->mon_w(!d); | |
| 253 | 253 | |
| 254 | if (ioport("T5")->read()) | |
| 254 | if (ioport("T5")->read()) m_fdc->ready_w(d); | |
| 255 | 255 | break; |
| 256 | 256 | } |
| 257 | 257 | } |
| r18419 | r18420 | |
| 516 | 516 | if (!m_dack3) |
| 517 | 517 | { |
| 518 | 518 | // floppy terminal count |
| 519 | | |
| 519 | m_fdc->tc_w(!state); | |
| 520 | 520 | } |
| 521 | 521 | |
| 522 | 522 | m_tc = !state; |
| r18419 | r18420 | |
| 531 | 531 | if (!m_dack3) |
| 532 | 532 | { |
| 533 | 533 | // floppy terminal count |
| 534 | | |
| 534 | m_fdc->tc_w(m_tc); | |
| 535 | 535 | } |
| 536 | 536 | } |
| 537 | 537 | |
| 538 | 538 | static UINT8 memory_read_byte(address_space &space, offs_t address, UINT8 mem_mask) { return space.read_byte(address); } |
| 539 | 539 | static void memory_write_byte(address_space &space, offs_t address, UINT8 data, UINT8 mem_mask) { space.write_byte(address, data); } |
| 540 | 540 | |
| 541 | READ8_MEMBER( mm1_state::fdc_dma_r ) | |
| 542 | { | |
| 543 | return m_fdc->dma_r(); | |
| 544 | } | |
| 545 | ||
| 546 | WRITE8_MEMBER( mm1_state::fdc_dma_w ) | |
| 547 | { | |
| 548 | m_fdc->dma_w(data); | |
| 549 | } | |
| 550 | ||
| 541 | 551 | static I8237_INTERFACE( dmac_intf ) |
| 542 | 552 | { |
| 543 | 553 | DEVCB_DRIVER_LINE_MEMBER(mm1_state, dma_hrq_changed), |
| 544 | 554 | DEVCB_DRIVER_LINE_MEMBER(mm1_state, tc_w), |
| 545 | 555 | DEVCB_MEMORY_HANDLER(I8085A_TAG, PROGRAM, memory_read_byte), |
| 546 | 556 | DEVCB_MEMORY_HANDLER(I8085A_TAG, PROGRAM, memory_write_byte), |
| 547 | { DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(mm1_state, mpsc_dack_r), DEVCB_DEVICE_HANDLER(UPD765_TAG, upd765_dack_r) }, | |
| 548 | { DEVCB_DEVICE_HANDLER(I8275_TAG, i8275_dack_w), DEVCB_DRIVER_MEMBER(mm1_state, mpsc_dack_w), DEVCB_NULL, DEVCB_DEVICE_HANDLER(UPD765_TAG, upd765_dack_w) }, | |
| 557 | { DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(mm1_state, mpsc_dack_r), DEVCB_DRIVER_MEMBER(mm1_state, fdc_dma_r) }, | |
| 558 | { DEVCB_DEVICE_HANDLER(I8275_TAG, i8275_dack_w), DEVCB_DRIVER_MEMBER(mm1_state, mpsc_dack_w), DEVCB_NULL, DEVCB_DRIVER_MEMBER(mm1_state, fdc_dma_w) }, | |
| 549 | 559 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_LINE_MEMBER(mm1_state, dack3_w) } |
| 550 | 560 | }; |
| 551 | 561 | |
| r18419 | r18420 | |
| 673 | 683 | // upd765_interface fdc_intf |
| 674 | 684 | //------------------------------------------------- |
| 675 | 685 | |
| 676 | static LEGACY_FLOPPY_OPTIONS_START( mm1 ) | |
| 677 | LEGACY_FLOPPY_OPTION( mm1_640kb, "dsk", "Nokia MikroMikko 1 640KB disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 678 | HEADS([2]) | |
| 679 | TRACKS([80]) | |
| 680 | SECTORS([8]) // 3:1 sector skew (1,4,7,2,5,8,3,6) | |
| 681 | SECTOR_LENGTH([512]) | |
| 682 | FIRST_SECTOR_ID([1])) | |
| 683 | LEGACY_FLOPPY_OPTIONS_END | |
| 686 | static const floppy_format_type mm1_floppy_formats[] = { | |
| 687 | FLOPPY_MM1_FORMAT, | |
| 688 | FLOPPY_MFI_FORMAT, | |
| 689 | NULL | |
| 690 | }; | |
| 684 | 691 | |
| 685 | static LEGACY_FLOPPY_OPTIONS_START( mm2 ) | |
| 686 | LEGACY_FLOPPY_OPTION( mm2_360kb, "dsk", "Nokia MikroMikko 2 360KB disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 687 | HEADS([2]) | |
| 688 | TRACKS([40]) | |
| 689 | SECTORS([9]) | |
| 690 | SECTOR_LENGTH([512]) | |
| 691 | FIRST_SECTOR_ID([1])) | |
| 692 | static const floppy_format_type mm2_floppy_formats[] = { | |
| 693 | FLOPPY_MM2_FORMAT, | |
| 694 | FLOPPY_MFI_FORMAT, | |
| 695 | NULL | |
| 696 | }; | |
| 692 | 697 | |
| 693 | LEGACY_FLOPPY_OPTION( mm2_720kb, "dsk", "Nokia MikroMikko 2 720KB disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 694 | HEADS([2]) | |
| 695 | TRACKS([40]) | |
| 696 | SECTORS([18]) | |
| 697 | SECTOR_LENGTH([512]) | |
| 698 | FIRST_SECTOR_ID([1])) | |
| 699 | LEGACY_FLOPPY_OPTIONS_END | |
| 698 | static SLOT_INTERFACE_START( mm1_floppies ) | |
| 699 | SLOT_INTERFACE( "525qd", FLOPPY_525_QD ) | |
| 700 | SLOT_INTERFACE_END | |
| 700 | 701 | |
| 701 | ||
| 702 | void mm1_state::fdc_irq(bool state) | |
| 702 | 703 | { |
| 703 | DEVCB_NULL, | |
| 704 | DEVCB_NULL, | |
| 705 | DEVCB_NULL, | |
| 706 | DEVCB_NULL, | |
| 707 | DEVCB_NULL, | |
| 708 | FLOPPY_STANDARD_5_25_DSQD, | |
| 709 | LEGACY_FLOPPY_OPTIONS_NAME(mm1), | |
| 710 | "floppy_5_25", | |
| 711 | NULL | |
| 712 | }; | |
| 704 | m_maincpu->set_input_line(I8085_RST55_LINE, state ? ASSERT_LINE : CLEAR_LINE); | |
| 705 | } | |
| 713 | 706 | |
| 714 | ||
| 707 | void mm1_state::fdc_drq(bool state) | |
| 715 | 708 | { |
| 716 | DEVCB_CPU_INPUT_LINE(I8085A_TAG, I8085_RST55_LINE), | |
| 717 | DEVCB_DEVICE_LINE_MEMBER(I8237_TAG, am9517a_device, dreq3_w), | |
| 718 | NULL, | |
| 719 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 720 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 721 | }; | |
| 709 | m_dmac->dreq3_w(state); | |
| 710 | } | |
| 722 | 711 | |
| 723 | 712 | |
| 724 | ||
| 725 | 713 | //************************************************************************** |
| 726 | 714 | // MACHINE INITIALIZATION |
| 727 | 715 | //************************************************************************** |
| r18419 | r18420 | |
| 762 | 750 | for (i = 0; i < 8; i++) ls259_w(program, i, 0); |
| 763 | 751 | |
| 764 | 752 | // set FDC ready |
| 765 | if (!ioport("T5")->read()) | |
| 753 | if (!ioport("T5")->read()) m_fdc->ready_w(true); | |
| 766 | 754 | |
| 767 | 755 | // reset FDC |
| 768 | upd765_reset_w(m_fdc, 1); | |
| 769 | upd765_reset_w(m_fdc, 0); | |
| 756 | m_fdc->reset(); | |
| 770 | 757 | } |
| 771 | 758 | |
| 772 | 759 | |
| r18419 | r18420 | |
| 796 | 783 | MCFG_I8212_ADD(I8212_TAG, iop_intf) |
| 797 | 784 | MCFG_I8237_ADD(I8237_TAG, XTAL_6_144MHz/2, dmac_intf) |
| 798 | 785 | MCFG_PIT8253_ADD(I8253_TAG, pit_intf) |
| 799 | MCFG_UPD765A_ADD(UPD765_TAG, /* XTAL_16MHz/2/2 */ | |
| 786 | MCFG_UPD765A_ADD(UPD765_TAG, /* XTAL_16MHz/2/2 */ true, true) | |
| 800 | 787 | MCFG_UPD7201_ADD(UPD7201_TAG, XTAL_6_144MHz/2, mpsc_intf) |
| 801 | 788 | |
| 802 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(mm1_floppy_interface) | |
| 789 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", mm1_floppies, "525qd", 0, mm1_floppy_formats) | |
| 790 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", mm1_floppies, "525qd", 0, mm1_floppy_formats) | |
| 803 | 791 | |
| 804 | 792 | // internal ram |
| 805 | 793 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 13 | 13 | #include "machine/upd765.h" |
| 14 | 14 | #include "machine/8237dma.h" |
| 15 | 15 | #include "video/upd7220.h" |
| 16 | #include "formats/ | |
| 16 | #include "formats/mfi_dsk.h" | |
| 17 | 17 | #include "dmv.lh" |
| 18 | 18 | |
| 19 | 19 | class dmv_state : public driver_device |
| r18419 | r18420 | |
| 24 | 24 | m_maincpu(*this, "maincpu"), |
| 25 | 25 | m_hgdc(*this, "upd7220"), |
| 26 | 26 | m_dmac(*this, "dma8237"), |
| 27 | m_floppy0(*this, FLOPPY_0), | |
| 28 | m_floppy1(*this, FLOPPY_1), | |
| 27 | m_fdc(*this, "upd765"), | |
| 28 | m_floppy0(*this, "upd765:0:525dd"), | |
| 29 | m_floppy1(*this, "upd765:1:525dd"), | |
| 29 | 30 | m_video_ram(*this, "video_ram") |
| 30 | 31 | { } |
| 31 | 32 | |
| 32 | 33 | required_device<cpu_device> m_maincpu; |
| 33 | 34 | required_device<upd7220_device> m_hgdc; |
| 34 | required_device<device_t> m_dmac; | |
| 35 | required_device<device_t> m_floppy0; | |
| 36 | required_device<device_t> m_floppy1; | |
| 35 | required_device<i8237_device> m_dmac; | |
| 36 | required_device<upd765a_device> m_fdc; | |
| 37 | required_device<floppy_image_device> m_floppy0; | |
| 38 | required_device<floppy_image_device> m_floppy1; | |
| 37 | 39 | |
| 38 | 40 | virtual void video_start(); |
| 41 | virtual void machine_start(); | |
| 39 | 42 | virtual void machine_reset(); |
| 40 | 43 | |
| 41 | 44 | DECLARE_WRITE8_MEMBER(leds_w); |
| 42 | DECLARE_WRITE_LINE_MEMBER(fdc_irq_w); | |
| 43 | 45 | DECLARE_WRITE_LINE_MEMBER(dma_hrq_changed); |
| 44 | 46 | DECLARE_WRITE8_MEMBER(fdd_motor_w); |
| 45 | 47 | DECLARE_READ8_MEMBER(sys_status_r); |
| 46 | 48 | DECLARE_READ8_MEMBER(kb_ctrl_mcu_r); |
| 47 | 49 | DECLARE_WRITE8_MEMBER(kb_ctrl_mcu_w); |
| 50 | DECLARE_READ8_MEMBER(fdc_dma_r); | |
| 51 | DECLARE_WRITE8_MEMBER(fdc_dma_w); | |
| 48 | 52 | |
| 53 | void fdc_irq(bool state); | |
| 54 | void fdc_drq(bool state); | |
| 55 | ||
| 49 | 56 | required_shared_ptr<UINT8> m_video_ram; |
| 50 | 57 | int m_fdc_int_line; |
| 51 | 58 | }; |
| r18419 | r18420 | |
| 71 | 78 | output_set_led_value(8-i, BIT(data, i)); |
| 72 | 79 | } |
| 73 | 80 | |
| 74 | ||
| 81 | void dmv_state::fdc_irq(bool state) | |
| 75 | 82 | { |
| 76 | 83 | m_fdc_int_line = state; |
| 77 | 84 | } |
| 78 | 85 | |
| 86 | void dmv_state::fdc_drq(bool state) | |
| 87 | { | |
| 88 | m_dmac->i8237_drq_write(3, state); | |
| 89 | } | |
| 90 | ||
| 91 | READ8_MEMBER(dmv_state::fdc_dma_r) | |
| 92 | { | |
| 93 | return m_fdc->dma_r(); | |
| 94 | } | |
| 95 | ||
| 96 | WRITE8_MEMBER(dmv_state::fdc_dma_w) | |
| 97 | { | |
| 98 | m_fdc->dma_w(data); | |
| 99 | } | |
| 100 | ||
| 79 | 101 | WRITE8_MEMBER(dmv_state::fdd_motor_w) |
| 80 | 102 | { |
| 81 | 103 | // bit 0 defines the state of the FDD motor |
| 82 | 104 | |
| 83 | floppy_mon_w(m_floppy0, BIT(data, 0) ? 0 : 1); | |
| 84 | floppy_mon_w(m_floppy1, BIT(data, 0) ? 0 : 1); | |
| 85 | floppy_drive_set_ready_state(m_floppy0, 1, BIT(data, 0)); | |
| 86 | floppy_drive_set_ready_state(m_floppy1, 1, BIT(data, 0)); | |
| 105 | m_floppy0->mon_w(!BIT(data, 0)); | |
| 106 | m_floppy1->mon_w(!BIT(data, 0)); | |
| 87 | 107 | } |
| 88 | 108 | |
| 89 | 109 | READ8_MEMBER(dmv_state::sys_status_r) |
| r18419 | r18420 | |
| 160 | 180 | } |
| 161 | 181 | } |
| 162 | 182 | |
| 183 | static const floppy_format_type dmv_floppy_formats[] = { | |
| 184 | FLOPPY_MFI_FORMAT, | |
| 185 | NULL | |
| 186 | }; | |
| 187 | ||
| 188 | static SLOT_INTERFACE_START( dmv_floppies ) | |
| 189 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 190 | SLOT_INTERFACE_END | |
| 191 | ||
| 163 | 192 | static ADDRESS_MAP_START(dmv_mem, AS_PROGRAM, 8, dmv_state) |
| 164 | 193 | ADDRESS_MAP_UNMAP_HIGH |
| 165 | 194 | AM_RANGE( 0x0000, 0x1fff ) AM_ROM |
| r18419 | r18420 | |
| 174 | 203 | AM_RANGE(0x14, 0x14) AM_WRITE(fdd_motor_w) |
| 175 | 204 | AM_RANGE(0x20, 0x2f) AM_DEVREADWRITE_LEGACY("dma8237", i8237_r, i8237_w) |
| 176 | 205 | AM_RANGE(0x40, 0x41) AM_READWRITE(kb_ctrl_mcu_r, kb_ctrl_mcu_w) |
| 177 | AM_RANGE(0x50, 0x50) AM_DEVREAD_LEGACY("upd765", upd765_status_r) | |
| 178 | AM_RANGE(0x51, 0x51) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w) | |
| 206 | AM_RANGE(0x50, 0x51) AM_DEVICE("upd765", upd765a_device, map) | |
| 179 | 207 | AM_RANGE(0xa0, 0xa1) AM_DEVREADWRITE("upd7220", upd7220_device, read, write) |
| 180 | 208 | |
| 181 | 209 | //AM_RANGE(0x10, 0x11) boot ROM bankswitch (0x0000-0x1fff) |
| r18419 | r18420 | |
| 204 | 232 | INPUT_PORTS_START( dmv ) |
| 205 | 233 | INPUT_PORTS_END |
| 206 | 234 | |
| 235 | void dmv_state::machine_start() | |
| 236 | { | |
| 237 | m_fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(dmv_state::fdc_irq), this)); | |
| 238 | m_fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(dmv_state::fdc_drq), this)); | |
| 239 | } | |
| 240 | ||
| 207 | 241 | void dmv_state::machine_reset() |
| 208 | 242 | { |
| 209 | 243 | } |
| r18419 | r18420 | |
| 241 | 275 | DEVCB_NULL |
| 242 | 276 | }; |
| 243 | 277 | |
| 244 | static const floppy_interface dmv_floppy_interface = | |
| 245 | { | |
| 246 | DEVCB_NULL, | |
| 247 | DEVCB_NULL, | |
| 248 | DEVCB_NULL, | |
| 249 | DEVCB_NULL, | |
| 250 | DEVCB_NULL, | |
| 251 | FLOPPY_STANDARD_5_25_DSDD, | |
| 252 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 253 | "floppy_5_25", | |
| 254 | NULL | |
| 255 | }; | |
| 256 | 278 | |
| 257 | ||
| 258 | static const upd765_interface dmv_interface = | |
| 259 | { | |
| 260 | DEVCB_DRIVER_LINE_MEMBER(dmv_state, fdc_irq_w), | |
| 261 | DEVCB_DEVICE_LINE("dma8237", i8237_dreq3_w), | |
| 262 | NULL, | |
| 263 | UPD765_RDY_PIN_CONNECTED, | |
| 264 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 265 | }; | |
| 266 | ||
| 267 | ||
| 268 | 279 | //------------------------------------------------------------------------------------ |
| 269 | 280 | // I8237_INTERFACE |
| 270 | 281 | //------------------------------------------------------------------------------------ |
| r18419 | r18420 | |
| 286 | 297 | DEVCB_NULL, |
| 287 | 298 | DEVCB_MEMORY_HANDLER("maincpu", PROGRAM, memory_read_byte), |
| 288 | 299 | DEVCB_MEMORY_HANDLER("maincpu", PROGRAM, memory_write_byte), |
| 289 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_HANDLER("upd765", upd765_dack_r) }, | |
| 290 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DEVICE_HANDLER("upd765", upd765_dack_w) }, | |
| 300 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(dmv_state, fdc_dma_r) }, | |
| 301 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_DRIVER_MEMBER(dmv_state, fdc_dma_w) }, | |
| 291 | 302 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL } |
| 292 | 303 | }; |
| 293 | 304 | |
| r18419 | r18420 | |
| 321 | 332 | // devices |
| 322 | 333 | MCFG_UPD7220_ADD( "upd7220", XTAL_4MHz, hgdc_intf, upd7220_map ) |
| 323 | 334 | MCFG_I8237_ADD( "dma8237", XTAL_4MHz, dmv_dma8237_config ) |
| 324 | MCFG_UPD765A_ADD( "upd765", dmv_interface ) | |
| 325 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD( dmv_floppy_interface ) | |
| 335 | MCFG_UPD765A_ADD( "upd765", true, true ) | |
| 336 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", dmv_floppies, "525dd", 0, dmv_floppy_formats) | |
| 337 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", dmv_floppies, "525dd", 0, dmv_floppy_formats) | |
| 326 | 338 | MACHINE_CONFIG_END |
| 327 | 339 | |
| 328 | 340 | /* ROM definition */ |
| r18419 | r18420 | |
|---|---|---|
| 91 | 91 | #include "imagedev/harddriv.h" |
| 92 | 92 | #include "imagedev/cassette.h" |
| 93 | 93 | #include "imagedev/cartslot.h" |
| 94 | #include "formats/mfi_dsk.h" | |
| 94 | 95 | #include "formats/pc_dsk.h" |
| 95 | 96 | |
| 96 | 97 | #include "machine/8237dma.h" |
| r18419 | r18420 | |
| 206 | 207 | AM_RANGE(0x0378, 0x037f) AM_DEVREADWRITE_LEGACY("lpt_1", pc_lpt_r, pc_lpt_w) |
| 207 | 208 | AM_RANGE(0x03bc, 0x03be) AM_DEVREADWRITE_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w) |
| 208 | 209 | AM_RANGE(0x03e8, 0x03ef) AM_DEVREADWRITE("ins8250_2", ins8250_device, ins8250_r, ins8250_w) |
| 209 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 210 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE("fdc", pc_fdc_interface, map) | |
| 210 | 211 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE("ins8250_0", ins8250_device, ins8250_r, ins8250_w) |
| 211 | 212 | ADDRESS_MAP_END |
| 212 | 213 | |
| r18419 | r18420 | |
| 232 | 233 | AM_RANGE(0x0378, 0x037f) AM_DEVREADWRITE8_LEGACY("lpt_1", pc_lpt_r, pc_lpt_w, 0xffff) |
| 233 | 234 | AM_RANGE(0x03bc, 0x03bf) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0xffff) |
| 234 | 235 | AM_RANGE(0x03e8, 0x03ef) AM_DEVREADWRITE8("ins8250_2", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 235 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 236 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_interface, map, 0xffff) | |
| 236 | 237 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ins8250_0", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 237 | 238 | ADDRESS_MAP_END |
| 238 | 239 | |
| r18419 | r18420 | |
| 252 | 253 | // AM_RANGE(0x02f8, 0x02f8) AM_DEVREADWRITE8_LEGACY("upd8251_1", i8251_device, data_r, data_w, 0x00ff) |
| 253 | 254 | // AM_RANGE(0x02f9, 0x02f9) AM_DEVREADWRITE8_LEGACY("upd8251_1", i8251_device, status_r, control_w, 0xff00) |
| 254 | 255 | AM_RANGE(0x0378, 0x037f) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0xffff) |
| 255 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 256 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_interface, map, 0xffff) | |
| 256 | 257 | // AM_RANGE(0x03f8, 0x03f9) AM_DEVREADWRITE8_LEGACY("upd8251_0", i8251_device, data_r, data_w, 0x00ff) |
| 257 | 258 | // AM_RANGE(0x03f8, 0x03f9) AM_DEVREADWRITE8_LEGACY("upd8251_0", i8251_device, status_r, control_w, 0xff00) |
| 258 | 259 | ADDRESS_MAP_END |
| r18419 | r18420 | |
| 273 | 274 | AM_RANGE(0x0340, 0x0357) AM_NOP /* anonymous bios should not recogniced realtimeclock */ |
| 274 | 275 | AM_RANGE(0x0378, 0x037f) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0xffff) |
| 275 | 276 | // AM_RANGE(0x03e8, 0x03ef) AM_DEVREADWRITE8("ins8250_2", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 276 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 277 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_interface, map, 0xffff) | |
| 277 | 278 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ins8250_0", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 278 | 279 | ADDRESS_MAP_END |
| 279 | 280 | |
| r18419 | r18420 | |
| 307 | 308 | AM_RANGE(0x0378, 0x037f) AM_DEVREADWRITE8_LEGACY("lpt_1", pc_lpt_r, pc_lpt_w, 0xffff) |
| 308 | 309 | AM_RANGE(0x03bc, 0x03bf) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0xffff) |
| 309 | 310 | AM_RANGE(0x03e8, 0x03ef) AM_DEVREADWRITE8("ins8250_2", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 310 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 311 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_interface, map, 0xffff) | |
| 311 | 312 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ins8250_0", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 312 | 313 | ADDRESS_MAP_END |
| 313 | 314 | |
| r18419 | r18420 | |
| 338 | 339 | AM_RANGE(0x0378, 0x037b) AM_DEVREADWRITE_LEGACY("lpt_1", pc_lpt_r, pc_lpt_w) |
| 339 | 340 | // AM_RANGE(0x03bc, 0x03bf) AM_DEVREADWRITE_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w) |
| 340 | 341 | AM_RANGE(0x03e8, 0x03ef) AM_DEVREADWRITE("ins8250_2", ins8250_device, ins8250_r, ins8250_w) |
| 341 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 342 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE("fdc", pc_fdc_interface, map) | |
| 342 | 343 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE("ins8250_0", ins8250_device, ins8250_r, ins8250_w) |
| 343 | 344 | ADDRESS_MAP_END |
| 344 | 345 | |
| r18419 | r18420 | |
| 368 | 369 | AM_RANGE(0x02f8, 0x02ff) AM_DEVREADWRITE("ins8250_1", ins8250_device, ins8250_r, ins8250_w) |
| 369 | 370 | AM_RANGE(0x0378, 0x037f) AM_READWRITE_LEGACY(pc_t1t_p37x_r, pc_t1t_p37x_w) |
| 370 | 371 | AM_RANGE(0x03bc, 0x03be) AM_DEVREADWRITE_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w) |
| 371 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 372 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE("fdc", pc_fdc_interface, map) | |
| 372 | 373 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE("ins8250_0", ins8250_device, ins8250_r, ins8250_w) |
| 373 | 374 | ADDRESS_MAP_END |
| 374 | 375 | |
| r18419 | r18420 | |
| 398 | 399 | AM_RANGE(0x02f8, 0x02ff) AM_DEVREADWRITE8("ins8250_1", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 399 | 400 | AM_RANGE(0x0378, 0x037f) AM_READWRITE8_LEGACY(pc_t1t_p37x_r, pc_t1t_p37x_w, 0xffff) |
| 400 | 401 | AM_RANGE(0x03bc, 0x03bf) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0xffff) |
| 401 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 402 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_interface, map, 0xffff) | |
| 402 | 403 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ins8250_0", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 403 | 404 | AM_RANGE(0xffea, 0xffeb) AM_READWRITE8_LEGACY(tandy1000_bank_r, tandy1000_bank_w, 0xffff) |
| 404 | 405 | ADDRESS_MAP_END |
| r18419 | r18420 | |
| 429 | 430 | AM_RANGE(0x02f8, 0x02ff) AM_DEVREADWRITE8("ins8250_1", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 430 | 431 | AM_RANGE(0x0378, 0x037f) AM_READWRITE8_LEGACY(pc_t1t_p37x_r, pc_t1t_p37x_w, 0xffff) |
| 431 | 432 | AM_RANGE(0x03bc, 0x03bf) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0xffff) |
| 432 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 433 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_interface, map, 0xffff) | |
| 433 | 434 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ins8250_0", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 434 | 435 | ADDRESS_MAP_END |
| 435 | 436 | |
| r18419 | r18420 | |
| 455 | 456 | AM_RANGE(0x0080, 0x0087) AM_READWRITE(pc_page_r, pc_page_w) |
| 456 | 457 | AM_RANGE(0x00a0, 0x00a0) AM_READWRITE(pcjr_nmi_enable_r, pc_nmi_enable_w ) |
| 457 | 458 | AM_RANGE(0x00c0, 0x00c0) AM_DEVWRITE("sn76496", sn76496_device, write) |
| 458 | AM_RANGE(0x00f0, 0x00f7) AM_ | |
| 459 | AM_RANGE(0x00f0, 0x00f7) AM_DEVICE("fdc", pc_fdc_interface, map) | |
| 459 | 460 | AM_RANGE(0x0200, 0x0207) AM_READWRITE_LEGACY(pc_JOY_r, pc_JOY_w) |
| 460 | 461 | AM_RANGE(0x02f8, 0x02ff) AM_DEVREADWRITE("ins8250_1", ins8250_device, ins8250_r, ins8250_w) |
| 461 | 462 | AM_RANGE(0x0378, 0x037f) AM_READWRITE_LEGACY(pc_t1t_p37x_r, pc_t1t_p37x_w) |
| r18419 | r18420 | |
| 856 | 857 | DEVCB_CPU_INPUT_LINE("maincpu", 0) |
| 857 | 858 | }; |
| 858 | 859 | |
| 859 | static const floppy_interface ibmpc_floppy_interface = | |
| 860 | { | |
| 861 | DEVCB_NULL, | |
| 862 | DEVCB_NULL, | |
| 863 | DEVCB_NULL, | |
| 864 | DEVCB_NULL, | |
| 865 | DEVCB_NULL, | |
| 866 | FLOPPY_STANDARD_5_25_DSHD, | |
| 867 | LEGACY_FLOPPY_OPTIONS_NAME(pc), | |
| 868 | "floppy_5_25", | |
| 860 | static const floppy_format_type ibmpc_floppy_formats[] = { | |
| 861 | FLOPPY_PC_FORMAT, | |
| 862 | FLOPPY_MFI_FORMAT, | |
| 869 | 863 | NULL |
| 870 | 864 | }; |
| 871 | 865 | |
| 866 | static SLOT_INTERFACE_START( ibmpc_floppies ) | |
| 867 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 868 | SLOT_INTERFACE_END | |
| 869 | ||
| 872 | 870 | SLOT_INTERFACE_START(ibm5150_com) |
| 873 | 871 | SLOT_INTERFACE("microsoft_mouse", MSFT_SERIAL_MOUSE) |
| 874 | 872 | SLOT_INTERFACE("mouse_systems_mouse", MSYSTEM_SERIAL_MOUSE) |
| r18419 | r18420 | |
| 996 | 994 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 997 | 995 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 998 | 996 | |
| 999 | MCFG_ | |
| 997 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1000 | 998 | |
| 1001 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 999 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1000 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1002 | 1001 | |
| 1003 | 1002 | /* internal ram */ |
| 1004 | 1003 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1076 | 1075 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1077 | 1076 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1078 | 1077 | |
| 1079 | MCFG_ | |
| 1078 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1080 | 1079 | |
| 1081 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1080 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1081 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1082 | 1082 | |
| 1083 | 1083 | /* internal ram */ |
| 1084 | 1084 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1125 | 1125 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1126 | 1126 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1127 | 1127 | |
| 1128 | MCFG_ | |
| 1128 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1129 | 1129 | |
| 1130 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1130 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1131 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1131 | 1132 | |
| 1132 | 1133 | /* internal ram */ |
| 1133 | 1134 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1174 | 1175 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1175 | 1176 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1176 | 1177 | |
| 1177 | MCFG_ | |
| 1178 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1178 | 1179 | |
| 1179 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1180 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1181 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1180 | 1182 | |
| 1181 | 1183 | /* internal ram */ |
| 1182 | 1184 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1223 | 1225 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1224 | 1226 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1225 | 1227 | |
| 1226 | MCFG_ | |
| 1228 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1227 | 1229 | |
| 1228 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1230 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1231 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1229 | 1232 | |
| 1230 | 1233 | /* internal ram */ |
| 1231 | 1234 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1295 | 1298 | /* cassette */ |
| 1296 | 1299 | MCFG_CASSETTE_ADD( CASSETTE_TAG, ibm5150_cassette_interface ) |
| 1297 | 1300 | |
| 1298 | MCFG_ | |
| 1301 | MCFG_PC_FDC_JR_ADD("fdc") | |
| 1299 | 1302 | |
| 1300 | MCFG_ | |
| 1303 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1301 | 1304 | |
| 1302 | 1305 | /* cartridge */ |
| 1303 | 1306 | MCFG_CARTSLOT_ADD("cart1") |
| r18419 | r18420 | |
| 1371 | 1374 | MCFG_CASSETTE_ADD( CASSETTE_TAG, mc1502_cassette_interface ) // has no motor control |
| 1372 | 1375 | |
| 1373 | 1376 | MCFG_FD1793_ADD( "vg93", default_wd17xx_interface_2_drives ) |
| 1374 | MCFG_ | |
| 1377 | MCFG_FLOPPY_DRIVE_ADD(FLOPPY_0, ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1375 | 1378 | |
| 1376 | 1379 | /* internal ram */ |
| 1377 | 1380 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1413 | 1416 | /* printer */ |
| 1414 | 1417 | MCFG_PC_LPT_ADD("lpt_0", pc_lpt_config) |
| 1415 | 1418 | |
| 1416 | MCFG_ | |
| 1419 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1417 | 1420 | |
| 1418 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1421 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1422 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1419 | 1423 | |
| 1420 | 1424 | /* keyboard -- needs dump */ |
| 1421 | 1425 | MCFG_PC_KBDC_ADD("pc_kbdc", pc_kbdc_intf) |
| r18419 | r18420 | |
| 1472 | 1476 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1473 | 1477 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1474 | 1478 | |
| 1475 | MCFG_ | |
| 1479 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1476 | 1480 | |
| 1477 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1481 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1482 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1478 | 1483 | |
| 1479 | 1484 | /* internal ram */ |
| 1480 | 1485 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1525 | 1530 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1526 | 1531 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1527 | 1532 | |
| 1528 | MCFG_ | |
| 1533 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1529 | 1534 | |
| 1530 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1535 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1536 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1531 | 1537 | |
| 1532 | 1538 | /* internal ram */ |
| 1533 | 1539 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1579 | 1585 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1580 | 1586 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1581 | 1587 | |
| 1582 | MCFG_ | |
| 1588 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1583 | 1589 | |
| 1584 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1590 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1591 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1585 | 1592 | |
| 1586 | 1593 | /* internal ram */ |
| 1587 | 1594 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1632 | 1639 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1633 | 1640 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1634 | 1641 | |
| 1635 | MCFG_ | |
| 1642 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1636 | 1643 | |
| 1637 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1644 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1645 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1638 | 1646 | |
| 1639 | 1647 | /* internal ram */ |
| 1640 | 1648 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1685 | 1693 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1686 | 1694 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1687 | 1695 | |
| 1688 | MCFG_ | |
| 1696 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1689 | 1697 | |
| 1690 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1698 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1699 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1691 | 1700 | |
| 1692 | 1701 | /* internal ram */ |
| 1693 | 1702 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 1738 | 1747 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 1739 | 1748 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 1740 | 1749 | |
| 1741 | MCFG_ | |
| 1750 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 1742 | 1751 | |
| 1743 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 1752 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1753 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1744 | 1754 | |
| 1745 | 1755 | /* internal ram */ |
| 1746 | 1756 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 1 | 1 | #include "includes/newbrain.h" |
| 2 | #include "formats/mfi_dsk.h" | |
| 2 | 3 | |
| 3 | 4 | /* |
| 4 | 5 | |
| r18419 | r18420 | |
| 582 | 583 | |
| 583 | 584 | */ |
| 584 | 585 | |
| 585 | floppy_mon_w(m_floppy, !BIT(data, 0)); | |
| 586 | floppy_drive_set_ready_state(m_floppy, 1, 0); | |
| 586 | m_floppy->mon_w(!BIT(data, 0)); | |
| 587 | 587 | |
| 588 | upd765_reset_w(m_fdc, BIT(data, 1)); | |
| 588 | if(BIT(data, 1)) | |
| 589 | m_fdc->reset(); | |
| 589 | 590 | |
| 590 | | |
| 591 | m_fdc->tc_w(BIT(data, 2)); | |
| 591 | 592 | } |
| 592 | 593 | |
| 593 | 594 | READ8_MEMBER( newbrain_eim_state::fdc_control_r ) |
| r18419 | r18420 | |
| 1048 | 1049 | static ADDRESS_MAP_START( newbrain_fdc_io_map, AS_IO, 8, newbrain_eim_state ) |
| 1049 | 1050 | ADDRESS_MAP_UNMAP_HIGH |
| 1050 | 1051 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 1051 | AM_RANGE(0x00, 0x00) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) | |
| 1052 | AM_RANGE(0x01, 0x01) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) | |
| 1052 | AM_RANGE(0x00, 0x01) AM_DEVICE(UPD765_TAG, upd765a_device, map) | |
| 1053 | 1053 | AM_RANGE(0x20, 0x20) AM_WRITE(fdc_auxiliary_w) |
| 1054 | 1054 | AM_RANGE(0x40, 0x40) AM_READ(fdc_control_r) |
| 1055 | 1055 | ADDRESS_MAP_END |
| r18419 | r18420 | |
| 1188 | 1188 | m_fdc_int = state; |
| 1189 | 1189 | } |
| 1190 | 1190 | |
| 1191 | static const upd765_interface fdc_intf = | |
| 1192 | { | |
| 1193 | DEVCB_DRIVER_LINE_MEMBER(newbrain_eim_state, fdc_interrupt), | |
| 1194 | DEVCB_NULL, | |
| 1195 | NULL, | |
| 1196 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 1197 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 1198 | }; | |
| 1199 | ||
| 1200 | 1191 | WRITE_LINE_MEMBER( newbrain_eim_state::ctc_z0_w ) |
| 1201 | 1192 | { |
| 1202 | 1193 | /* connected to the ACIA receive clock */ |
| r18419 | r18420 | |
| 1398 | 1389 | MCFG_RAM_DEFAULT_SIZE("32K") |
| 1399 | 1390 | MACHINE_CONFIG_END |
| 1400 | 1391 | |
| 1401 | static LEGACY_FLOPPY_OPTIONS_START(newbrain) | |
| 1402 | // 180K img | |
| 1403 | LEGACY_FLOPPY_OPTIONS_END | |
| 1404 | ||
| 1405 | static const floppy_interface newbrain_floppy_interface = | |
| 1406 | { | |
| 1407 | DEVCB_NULL, | |
| 1408 | DEVCB_NULL, | |
| 1409 | DEVCB_NULL, | |
| 1410 | DEVCB_NULL, | |
| 1411 | DEVCB_NULL, | |
| 1412 | FLOPPY_STANDARD_5_25_DSDD, | |
| 1413 | LEGACY_FLOPPY_OPTIONS_NAME(newbrain), | |
| 1414 | NULL, | |
| 1392 | static const floppy_format_type newbrain_floppy_formats[] = { | |
| 1393 | FLOPPY_MFI_FORMAT, | |
| 1415 | 1394 | NULL |
| 1416 | 1395 | }; |
| 1417 | 1396 | |
| 1397 | static SLOT_INTERFACE_START( newbrain_floppies ) | |
| 1398 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 1399 | SLOT_INTERFACE_END | |
| 1400 | ||
| 1418 | 1401 | static MACHINE_CONFIG_DERIVED_CLASS( newbrain_eim, newbrain_a, newbrain_eim_state ) |
| 1419 | 1402 | // basic system hardware |
| 1420 | 1403 | MCFG_CPU_MODIFY(Z80_TAG) |
| r18419 | r18420 | |
| 1429 | 1412 | MCFG_TIMER_DRIVER_ADD_PERIODIC("z80ctc_c2", newbrain_eim_state, ctc_c2_tick, attotime::from_hz(XTAL_16MHz/4/13)) |
| 1430 | 1413 | MCFG_ADC0808_ADD(ADC0809_TAG, 500000, adc_intf) |
| 1431 | 1414 | MCFG_ACIA6850_ADD(MC6850_TAG, acia_intf) |
| 1432 | MCFG_UPD765A_ADD(UPD765_TAG, fdc_intf) | |
| 1433 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(newbrain_floppy_interface) | |
| 1415 | MCFG_UPD765A_ADD(UPD765_TAG, false, true) | |
| 1416 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", newbrain_floppies, "525dd", 0, newbrain_floppy_formats) | |
| 1417 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", newbrain_floppies, "525dd", 0, newbrain_floppy_formats) | |
| 1434 | 1418 | |
| 1435 | 1419 | // internal ram |
| 1436 | 1420 | MCFG_RAM_MODIFY(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 65 | 65 | |
| 66 | 66 | |
| 67 | 67 | #include "includes/sg1000.h" |
| 68 | #include "formats/mfi_dsk.h" | |
| 68 | 69 | |
| 69 | 70 | |
| 70 | ||
| 71 | 71 | /*************************************************************************** |
| 72 | 72 | READ/WRITE HANDLERS |
| 73 | 73 | ***************************************************************************/ |
| r18419 | r18420 | |
| 239 | 239 | AM_RANGE(0xbe, 0xbe) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, vram_read, vram_write) |
| 240 | 240 | AM_RANGE(0xbf, 0xbf) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, register_read, register_write) |
| 241 | 241 | AM_RANGE(0xdc, 0xdf) AM_DEVREADWRITE(UPD9255_0_TAG, i8255_device, read, write) |
| 242 | AM_RANGE(0xe0, 0xe0) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) | |
| 243 | AM_RANGE(0xe1, 0xe1) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) | |
| 242 | AM_RANGE(0xe0, 0xe1) AM_DEVICE(UPD765_TAG, upd765a_device, map) | |
| 244 | 243 | AM_RANGE(0xe4, 0xe7) AM_DEVREADWRITE(UPD9255_1_TAG, i8255_device, read, write) |
| 245 | 244 | AM_RANGE(0xe8, 0xe8) AM_DEVREADWRITE(UPD8251_TAG, i8251_device, data_r, data_w) |
| 246 | 245 | AM_RANGE(0xe9, 0xe9) AM_DEVREADWRITE(UPD8251_TAG, i8251_device, status_r, control_w) |
| r18419 | r18420 | |
| 924 | 923 | floppy_drive_set_ready_state(m_floppy0, 1, 1); |
| 925 | 924 | |
| 926 | 925 | /* FDC terminal count */ |
| 927 | | |
| 926 | m_fdc->tc_w(BIT(data, 2)); | |
| 928 | 927 | |
| 929 | 928 | /* FDC reset */ |
| 930 | 929 | if (BIT(data, 3)) |
| 931 | 930 | { |
| 932 | | |
| 931 | m_fdc->reset(); | |
| 933 | 932 | } |
| 934 | 933 | |
| 935 | 934 | /* ROM selection */ |
| r18419 | r18420 | |
| 953 | 952 | upd765_interface sf7000_upd765_interface |
| 954 | 953 | -------------------------------------------------*/ |
| 955 | 954 | |
| 956 | ||
| 955 | void sf7000_state::fdc_intrq_w(bool state) | |
| 957 | 956 | { |
| 958 | 957 | m_fdc_irq = state; |
| 959 | 958 | } |
| 960 | 959 | |
| 961 | static const struct upd765_interface sf7000_upd765_interface = | |
| 962 | { | |
| 963 | DEVCB_DRIVER_LINE_MEMBER(sf7000_state, fdc_intrq_w), | |
| 964 | DEVCB_NULL, | |
| 965 | NULL, | |
| 966 | UPD765_RDY_PIN_CONNECTED, | |
| 967 | { FLOPPY_0, NULL, NULL, NULL } | |
| 968 | }; | |
| 969 | ||
| 970 | 960 | /*------------------------------------------------- |
| 971 | LEGACY_FLOPPY_OPTIONS( sf7000 ) | |
| 972 | -------------------------------------------------*/ | |
| 973 | ||
| 974 | static LEGACY_FLOPPY_OPTIONS_START( sf7000 ) | |
| 975 | LEGACY_FLOPPY_OPTION(sf7000, "sf7", "SF7 disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 976 | HEADS([1]) | |
| 977 | TRACKS([40]) | |
| 978 | SECTORS([16]) | |
| 979 | SECTOR_LENGTH([256]) | |
| 980 | FIRST_SECTOR_ID([1])) | |
| 981 | LEGACY_FLOPPY_OPTIONS_END | |
| 982 | ||
| 983 | /*------------------------------------------------- | |
| 984 | 961 | sf7000_fdc_index_callback - |
| 985 | 962 | -------------------------------------------------*/ |
| 986 | 963 | |
| r18419 | r18420 | |
| 993 | 970 | floppy_interface sf7000_floppy_interface |
| 994 | 971 | -------------------------------------------------*/ |
| 995 | 972 | |
| 996 | static const floppy_interface sf7000_floppy_interface = | |
| 997 | { | |
| 998 | DEVCB_DRIVER_LINE_MEMBER(sf7000_state,sf7000_fdc_index_callback), | |
| 999 | DEVCB_NULL, | |
| 1000 | DEVCB_NULL, | |
| 1001 | DEVCB_NULL, | |
| 1002 | DEVCB_NULL, | |
| 1003 | FLOPPY_STANDARD_5_25_DSHD, | |
| 1004 | LEGACY_FLOPPY_OPTIONS_NAME(sf7000), | |
| 1005 | "floppy_3", | |
| 973 | static const floppy_format_type sf7000_floppy_formats[] = { | |
| 974 | FLOPPY_MFI_FORMAT, | |
| 1006 | 975 | NULL |
| 1007 | 976 | }; |
| 1008 | 977 | |
| 978 | static SLOT_INTERFACE_START( sf7000_floppies ) | |
| 979 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 980 | SLOT_INTERFACE_END | |
| 981 | ||
| 1009 | 982 | /*------------------------------------------------- |
| 1010 | 983 | sn76496_config psg_intf |
| 1011 | 984 | -------------------------------------------------*/ |
| r18419 | r18420 | |
| 1078 | 1051 | membank("bank1")->configure_entry(1, m_ram->pointer()); |
| 1079 | 1052 | membank("bank2")->configure_entry(0, m_ram->pointer()); |
| 1080 | 1053 | |
| 1054 | m_fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(sf7000_state::fdc_intrq_w), this)); | |
| 1055 | ||
| 1081 | 1056 | /* register for state saving */ |
| 1082 | 1057 | save_item(NAME(m_keylatch)); |
| 1083 | 1058 | save_item(NAME(m_fdc_irq)); |
| r18419 | r18420 | |
| 1218 | 1193 | MCFG_I8255_ADD(UPD9255_0_TAG, sc3000_ppi_intf) |
| 1219 | 1194 | MCFG_I8255_ADD(UPD9255_1_TAG, sf7000_ppi_intf) |
| 1220 | 1195 | MCFG_I8251_ADD(UPD8251_TAG, default_i8251_interface) |
| 1221 | MCFG_UPD765A_ADD(UPD765_TAG, sf7000_upd765_interface) | |
| 1222 | MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, sf7000_floppy_interface) | |
| 1196 | MCFG_UPD765A_ADD(UPD765_TAG, true, true) | |
| 1197 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", sf7000_floppies, "525hd", 0, sf7000_floppy_formats) | |
| 1223 | 1198 | // MCFG_PRINTER_ADD("sp400") /* serial printer */ |
| 1224 | 1199 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics) |
| 1225 | 1200 | MCFG_CASSETTE_ADD(CASSETTE_TAG, sc3000_cassette_interface) |
| r18419 | r18420 | |
|---|---|---|
| 101 | 101 | #include "machine/ctronics.h" |
| 102 | 102 | |
| 103 | 103 | /* Devices */ |
| 104 | #include "imagedev/flopdrv.h" | |
| 105 | #include "formats/basicdsk.h" | |
| 106 | #include "formats/msx_dsk.h" | |
| 104 | #include "formats/mfi_dsk.h" | |
| 107 | 105 | #include "imagedev/snapquik.h" |
| 108 | 106 | #include "imagedev/cartslot.h" |
| 109 | 107 | #include "imagedev/cassette.h" |
| r18419 | r18420 | |
| 134 | 132 | DEVCB_DRIVER_MEMBER(amstrad_state,amstrad_ppi_portc_w) /* port C write */ |
| 135 | 133 | }; |
| 136 | 134 | |
| 137 | ||
| 138 | /* Amstrad UPD765 interface doesn't use interrupts or DMA! */ | |
| 139 | static const upd765_interface amstrad_upd765_interface = | |
| 140 | { | |
| 141 | DEVCB_NULL, | |
| 142 | DEVCB_NULL, | |
| 143 | NULL, | |
| 144 | UPD765_RDY_PIN_CONNECTED, | |
| 145 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 146 | }; | |
| 147 | ||
| 148 | /* Aleste uses an 8272A, with the interrupt flag visible on PPI port B */ | |
| 149 | static const upd765_interface aleste_8272_interface = | |
| 150 | { | |
| 151 | DEVCB_DRIVER_LINE_MEMBER(amstrad_state,aleste_interrupt), | |
| 152 | DEVCB_NULL, | |
| 153 | NULL, | |
| 154 | UPD765_RDY_PIN_CONNECTED, | |
| 155 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 156 | }; | |
| 157 | ||
| 158 | ||
| 159 | 135 | DRIVER_INIT_MEMBER(amstrad_state,aleste) |
| 160 | 136 | { |
| 137 | m_fdc->setup_intrq_cb(i8272a_device::line_cb(FUNC(amstrad_state::aleste_interrupt), this)); | |
| 161 | 138 | } |
| 162 | 139 | |
| 163 | 140 | |
| r18419 | r18420 | |
| 829 | 806 | NULL |
| 830 | 807 | }; |
| 831 | 808 | |
| 832 | static const floppy_interface cpc6128_floppy_interface = | |
| 833 | { | |
| 834 | DEVCB_NULL, | |
| 835 | DEVCB_NULL, | |
| 836 | DEVCB_NULL, | |
| 837 | DEVCB_NULL, | |
| 838 | DEVCB_NULL, | |
| 839 | FLOPPY_STANDARD_3_SSDD, | |
| 840 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 841 | "floppy_3", | |
| 809 | ||
| 810 | static const floppy_format_type amstrad_floppy_formats[] = { | |
| 811 | FLOPPY_MFI_FORMAT, | |
| 842 | 812 | NULL |
| 843 | 813 | }; |
| 844 | 814 | |
| 845 | static const floppy_interface aleste_floppy_interface = | |
| 846 | { | |
| 847 | DEVCB_NULL, | |
| 848 | DEVCB_NULL, | |
| 849 | DEVCB_NULL, | |
| 850 | DEVCB_NULL, | |
| 851 | DEVCB_NULL, | |
| 852 | FLOPPY_STANDARD_5_25_DSHD, | |
| 853 | LEGACY_FLOPPY_OPTIONS_NAME(msx), | |
| 854 | NULL, | |
| 815 | static const floppy_format_type aleste_floppy_formats[] = { | |
| 816 | FLOPPY_MFI_FORMAT, | |
| 855 | 817 | NULL |
| 856 | 818 | }; |
| 857 | 819 | |
| 820 | static SLOT_INTERFACE_START( amstrad_floppies ) | |
| 821 | SLOT_INTERFACE( "3ssdd", FLOPPY_3_SSDD ) | |
| 822 | SLOT_INTERFACE_END | |
| 823 | ||
| 824 | static SLOT_INTERFACE_START( aleste_floppies ) | |
| 825 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 826 | SLOT_INTERFACE_END | |
| 827 | ||
| 858 | 828 | CPC_EXPANSION_INTERFACE(cpc_exp_intf) |
| 859 | 829 | { |
| 860 | 830 | DEVCB_CPU_INPUT_LINE("maincpu", 0), |
| r18419 | r18420 | |
| 873 | 843 | MCFG_SOFTWARE_LIST_ADD("cart_list","gx4000") |
| 874 | 844 | MACHINE_CONFIG_END |
| 875 | 845 | |
| 876 | static MACHINE_CONFIG_START( amstrad, amstrad_state ) | |
| 846 | static MACHINE_CONFIG_START( amstrad_nofdc, amstrad_state ) | |
| 877 | 847 | /* Machine hardware */ |
| 878 | 848 | MCFG_CPU_ADD("maincpu", Z80, XTAL_16MHz / 4) |
| 879 | 849 | MCFG_CPU_PROGRAM_MAP(amstrad_mem) |
| r18419 | r18420 | |
| 918 | 888 | MCFG_CASSETTE_ADD( CASSETTE_TAG, amstrad_cassette_interface ) |
| 919 | 889 | MCFG_SOFTWARE_LIST_ADD("cass_list","cpc_cass") |
| 920 | 890 | |
| 921 | MCFG_UPD765A_ADD("upd765", amstrad_upd765_interface) | |
| 922 | ||
| 923 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(cpc6128_floppy_interface) | |
| 924 | MCFG_SOFTWARE_LIST_ADD("flop_list","cpc_flop") | |
| 925 | ||
| 926 | 891 | MCFG_CPC_EXPANSION_SLOT_ADD("exp",cpc_exp_intf,cpc_exp_cards,NULL,NULL) |
| 927 | 892 | |
| 928 | 893 | /* internal ram */ |
| r18419 | r18420 | |
| 931 | 896 | MACHINE_CONFIG_END |
| 932 | 897 | |
| 933 | 898 | |
| 899 | static MACHINE_CONFIG_DERIVED( amstrad, amstrad_nofdc ) | |
| 900 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 901 | ||
| 902 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", amstrad_floppies, "3ssdd", 0, amstrad_floppy_formats) | |
| 903 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", amstrad_floppies, "3ssdd", 0, amstrad_floppy_formats) | |
| 904 | ||
| 905 | MCFG_SOFTWARE_LIST_ADD("flop_list","cpc_flop") | |
| 906 | MACHINE_CONFIG_END | |
| 907 | ||
| 908 | ||
| 934 | 909 | static MACHINE_CONFIG_DERIVED( kccomp, amstrad ) |
| 935 | 910 | MCFG_MACHINE_START_OVERRIDE(amstrad_state,kccomp) |
| 936 | 911 | MCFG_MACHINE_RESET_OVERRIDE(amstrad_state,kccomp) |
| r18419 | r18420 | |
| 983 | 958 | |
| 984 | 959 | MCFG_CASSETTE_ADD( CASSETTE_TAG, amstrad_cassette_interface ) |
| 985 | 960 | |
| 986 | MCFG_UPD765A_ADD("upd765", | |
| 961 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 987 | 962 | |
| 988 | 963 | MCFG_FRAGMENT_ADD(cpcplus_cartslot) |
| 989 | 964 | |
| 990 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(cpc6128_floppy_interface) | |
| 965 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", amstrad_floppies, "3ssdd", 0, amstrad_floppy_formats) | |
| 966 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", amstrad_floppies, "3ssdd", 0, amstrad_floppy_formats) | |
| 991 | 967 | |
| 992 | 968 | MCFG_CPC_EXPANSION_SLOT_ADD("exp",cpc_exp_intf,cpc_exp_cards,NULL,NULL) |
| 993 | 969 | |
| r18419 | r18420 | |
| 1049 | 1025 | MCFG_PALETTE_LENGTH(32+64) |
| 1050 | 1026 | MCFG_PALETTE_INIT_OVERRIDE(amstrad_state,aleste) |
| 1051 | 1027 | MCFG_MC146818_ADD( "rtc", MC146818_IGNORE_CENTURY ) |
| 1052 | MCFG_UPD765A_MODIFY("upd765", aleste_8272_interface) | |
| 1053 | 1028 | |
| 1054 | MCFG_ | |
| 1029 | MCFG_I8272A_ADD("upd765", true) | |
| 1055 | 1030 | |
| 1031 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", aleste_floppies, "525hd", 0, aleste_floppy_formats) | |
| 1032 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", aleste_floppies, "525hd", 0, aleste_floppy_formats) | |
| 1033 | ||
| 1056 | 1034 | /* internal ram */ |
| 1057 | 1035 | MCFG_RAM_MODIFY(RAM_TAG) |
| 1058 | 1036 | MCFG_RAM_DEFAULT_SIZE("2M") |
| r18419 | r18420 | |
|---|---|---|
| 2 | 2 | |
| 3 | 3 | drivers/genpc.c |
| 4 | 4 | |
| 5 | Driver file for ge | |
| 5 | Driver file for generic PC machines | |
| 6 | 6 | |
| 7 | 7 | ***************************************************************************/ |
| 8 | 8 | |
| r18419 | r18420 | |
| 98 | 98 | SLOT_INTERFACE("ega", ISA8_EGA) |
| 99 | 99 | SLOT_INTERFACE("svga_et4k", ISA8_SVGA_ET4K) |
| 100 | 100 | SLOT_INTERFACE("com", ISA8_COM) |
| 101 | SLOT_INTERFACE("fdc", ISA8_FDC) | |
| 101 | SLOT_INTERFACE("fdc", ISA8_FDC_SUPERIO) | |
| 102 | SLOT_INTERFACE("fdc_xt", ISA8_FDC_XT) | |
| 103 | SLOT_INTERFACE("fdc_at", ISA8_FDC_AT) | |
| 104 | SLOT_INTERFACE("fdc_smc", ISA8_FDC_SMC) | |
| 105 | SLOT_INTERFACE("fdc_ps2", ISA8_FDC_PS2) | |
| 102 | 106 | SLOT_INTERFACE("finalchs", ISA8_FINALCHS) |
| 103 | 107 | SLOT_INTERFACE("hdc", ISA8_HDC) |
| 104 | 108 | SLOT_INTERFACE("adlib", ISA8_ADLIB) |
| r18419 | r18420 | |
|---|---|---|
| 55 | 55 | #include "imagedev/cassette.h" |
| 56 | 56 | #include "imagedev/cartslot.h" |
| 57 | 57 | #include "formats/pc_dsk.h" |
| 58 | #include "formats/mfi_dsk.h" | |
| 58 | 59 | |
| 59 | 60 | #include "machine/8237dma.h" |
| 60 | 61 | #include "sound/sn76496.h" |
| r18419 | r18420 | |
| 95 | 96 | AM_RANGE(0x0378, 0x037b) AM_READ8_LEGACY(pc200_port378_r, 0xffff) AM_DEVWRITE8_LEGACY("lpt_1", pc_lpt_w, 0x00ff) |
| 96 | 97 | AM_RANGE(0x03bc, 0x03bf) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0x00ff) |
| 97 | 98 | AM_RANGE(0x03e8, 0x03ef) AM_DEVREADWRITE8("ins8250_2", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 98 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 99 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_xt_device, map, 0xffff) | |
| 99 | 100 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ins8250_0", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 100 | 101 | ADDRESS_MAP_END |
| 101 | 102 | |
| r18419 | r18420 | |
| 123 | 124 | AM_RANGE(0x0378, 0x037b) AM_READ8_LEGACY(pc200_port378_r, 0xffff) AM_DEVWRITE8_LEGACY("lpt_1", pc_lpt_w, 0x00ff) |
| 124 | 125 | AM_RANGE(0x03bc, 0x03bf) AM_DEVREADWRITE8_LEGACY("lpt_0", pc_lpt_r, pc_lpt_w, 0x00ff) |
| 125 | 126 | AM_RANGE(0x03e8, 0x03ef) AM_DEVREADWRITE8("ins8250_2", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 126 | AM_RANGE(0x03f0, 0x03f7) AM_ | |
| 127 | AM_RANGE(0x03f0, 0x03f7) AM_DEVICE8("fdc", pc_fdc_xt_device, map, 0xffff) | |
| 127 | 128 | AM_RANGE(0x03f8, 0x03ff) AM_DEVREADWRITE8("ins8250_0", ins8250_device, ins8250_r, ins8250_w, 0xffff) |
| 128 | 129 | ADDRESS_MAP_END |
| 129 | 130 | |
| r18419 | r18420 | |
| 219 | 220 | DEVCB_CPU_INPUT_LINE("maincpu", 0) |
| 220 | 221 | }; |
| 221 | 222 | |
| 222 | static const floppy_interface ibmpc_floppy_interface = | |
| 223 | { | |
| 224 | DEVCB_NULL, | |
| 225 | DEVCB_NULL, | |
| 226 | DEVCB_NULL, | |
| 227 | DEVCB_NULL, | |
| 228 | DEVCB_NULL, | |
| 229 | FLOPPY_STANDARD_5_25_DSHD, | |
| 230 | LEGACY_FLOPPY_OPTIONS_NAME(pc), | |
| 231 | NULL, | |
| 223 | static const floppy_format_type ibmpc_floppy_formats[] = { | |
| 224 | FLOPPY_PC_FORMAT, | |
| 225 | FLOPPY_MFI_FORMAT, | |
| 232 | 226 | NULL |
| 233 | 227 | }; |
| 234 | 228 | |
| 229 | static SLOT_INTERFACE_START( ibmpc_floppies ) | |
| 230 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 231 | SLOT_INTERFACE_END | |
| 232 | ||
| 235 | 233 | SLOT_INTERFACE_START(amstr_com) |
| 236 | 234 | SLOT_INTERFACE("microsoft_mouse", MSFT_SERIAL_MOUSE) |
| 237 | 235 | SLOT_INTERFACE("mouse_systems_mouse", MSYSTEM_SERIAL_MOUSE) |
| r18419 | r18420 | |
| 300 | 298 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 301 | 299 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 302 | 300 | |
| 303 | MCFG_ | |
| 301 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 304 | 302 | |
| 305 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 303 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 304 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 306 | 305 | |
| 307 | 306 | /* internal ram */ |
| 308 | 307 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
| 370 | 369 | MCFG_PC_LPT_ADD("lpt_1", pc_lpt_config) |
| 371 | 370 | MCFG_PC_LPT_ADD("lpt_2", pc_lpt_config) |
| 372 | 371 | |
| 373 | MCFG_ | |
| 372 | MCFG_PC_FDC_XT_ADD("fdc") | |
| 374 | 373 | |
| 375 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(ibmpc_floppy_interface) | |
| 374 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 375 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 376 | 376 | |
| 377 | 377 | MCFG_MC146818_ADD( "rtc", MC146818_IGNORE_CENTURY ) |
| 378 | 378 |
| r18419 | r18420 | |
|---|---|---|
| 17 | 17 | */ |
| 18 | 18 | |
| 19 | 19 | #include "includes/wangpc.h" |
| 20 | #include "formats/mfi_dsk.h" | |
| 20 | 21 | |
| 21 | 22 | |
| 22 | ||
| 23 | 23 | //************************************************************************** |
| 24 | 24 | // MACROS/CONSTANTS |
| 25 | 25 | //************************************************************************** |
| r18419 | r18420 | |
| 46 | 46 | if (!drive) |
| 47 | 47 | { |
| 48 | 48 | m_ds1 = state; |
| 49 | if(state) | |
| 50 | m_fdc->set_floppy(m_floppy0); | |
| 49 | 51 | } |
| 50 | 52 | else |
| 51 | 53 | { |
| 52 | 54 | m_ds2 = state; |
| 55 | if(state) | |
| 56 | m_fdc->set_floppy(m_floppy1); | |
| 53 | 57 | } |
| 58 | if(!m_ds1 && !m_ds2) | |
| 59 | m_fdc->set_floppy(NULL); | |
| 54 | 60 | } |
| 55 | 61 | |
| 56 | 62 | void wangpc_state::set_motor(int drive, bool motor) |
| r18419 | r18420 | |
| 61 | 67 | |
| 62 | 68 | if (!drive) |
| 63 | 69 | { |
| 64 | floppy | |
| 70 | m_floppy0->mon_w(state); | |
| 65 | 71 | } |
| 66 | 72 | else |
| 67 | 73 | { |
| 68 | floppy | |
| 74 | m_floppy1->mon_w(state); | |
| 69 | 75 | } |
| 70 | 76 | } |
| 71 | 77 | |
| r18419 | r18420 | |
| 73 | 79 | { |
| 74 | 80 | if (LOG) logerror("%s: FDC reset\n", machine().describe_context()); |
| 75 | 81 | |
| 76 | upd765_reset_w(m_fdc, 1); | |
| 77 | upd765_reset_w(m_fdc, 0); | |
| 82 | m_fdc->reset(); | |
| 78 | 83 | } |
| 79 | 84 | |
| 80 | 85 | void wangpc_state::fdc_tc() |
| 81 | 86 | { |
| 82 | 87 | if (LOG) logerror("%s: FDC TC\n", machine().describe_context()); |
| 83 | 88 | |
| 84 | upd765_tc_w(m_fdc, 1); | |
| 85 | upd765_tc_w(m_fdc, 0); | |
| 89 | m_fdc->tc_w(true); | |
| 90 | m_fdc->tc_w(false); | |
| 86 | 91 | } |
| 87 | 92 | |
| 88 | 93 | WRITE8_MEMBER( wangpc_state::fdc_ctrl_w ) |
| r18419 | r18420 | |
| 296 | 301 | UINT8 data = 0x03; |
| 297 | 302 | |
| 298 | 303 | // floppy interrupts |
| 299 | data |= | |
| 304 | data |= m_fdc->get_irq() << 3; | |
| 300 | 305 | data |= m_fdc_dd0 << 4; |
| 301 | 306 | data |= m_fdc_dd1 << 5; |
| 302 | 307 | data |= m_floppy0->exists() ? 0 : 0x40; |
| r18419 | r18420 | |
| 555 | 560 | UINT8 data = 0; |
| 556 | 561 | |
| 557 | 562 | // FDC interrupt |
| 558 | data |= (m_fdc_dd0 | m_fdc_dd1 | | |
| 563 | data |= (m_fdc_dd0 | m_fdc_dd1 | m_fdc->get_irq()) << 7; | |
| 559 | 564 | |
| 560 | 565 | return data; |
| 561 | 566 | } |
| r18419 | r18420 | |
| 593 | 598 | AM_RANGE(0x100e, 0x100f) AM_READWRITE8(motor1_on_r, motor1_on_w, 0x00ff) |
| 594 | 599 | AM_RANGE(0x1010, 0x1011) AM_READWRITE8(motor2_off_r, motor2_off_w, 0x00ff) |
| 595 | 600 | AM_RANGE(0x1012, 0x1013) AM_READWRITE8(motor2_on_r, motor2_on_w, 0x00ff) |
| 596 | AM_RANGE(0x1014, 0x1015) AM_DEVREAD8_LEGACY(UPD765_TAG, upd765_status_r, 0x00ff) | |
| 597 | AM_RANGE(0x1016, 0x1017) AM_DEVREADWRITE8_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w, 0x00ff) | |
| 601 | AM_RANGE(0x1014, 0x1017) AM_DEVICE8(UPD765_TAG, upd765a_device, map, 0x00ff) | |
| 598 | 602 | AM_RANGE(0x1018, 0x1019) AM_MIRROR(0x0002) AM_READWRITE8(fdc_reset_r, fdc_reset_w, 0x00ff) |
| 599 | 603 | AM_RANGE(0x101c, 0x101d) AM_MIRROR(0x0002) AM_READWRITE8(fdc_tc_r, fdc_tc_w, 0x00ff) |
| 600 | 604 | AM_RANGE(0x1020, 0x1027) AM_DEVREADWRITE8(I8255A_TAG, i8255_device, read, write, 0x00ff) |
| r18419 | r18420 | |
| 663 | 667 | void wangpc_state::update_fdc_tc() |
| 664 | 668 | { |
| 665 | 669 | if (m_enable_eop) |
| 666 | | |
| 670 | m_fdc->tc_w(m_fdc_tc); | |
| 667 | 671 | else |
| 668 | | |
| 672 | m_fdc->tc_w(false); | |
| 669 | 673 | } |
| 670 | 674 | |
| 671 | 675 | WRITE_LINE_MEMBER( wangpc_state::hrq_w ) |
| r18419 | r18420 | |
| 715 | 719 | if (m_disable_dreq2) |
| 716 | 720 | return m_bus->dack_r(space, 2); |
| 717 | 721 | else |
| 718 | return | |
| 722 | return m_fdc->dma_r(); | |
| 719 | 723 | } |
| 720 | 724 | |
| 721 | 725 | WRITE8_MEMBER( wangpc_state::iow2_w ) |
| r18419 | r18420 | |
| 723 | 727 | if (m_disable_dreq2) |
| 724 | 728 | m_bus->dack_w(space, 2, data); |
| 725 | 729 | else |
| 726 | | |
| 730 | m_fdc->dma_w(data); | |
| 727 | 731 | } |
| 728 | 732 | |
| 729 | 733 | WRITE_LINE_MEMBER( wangpc_state::dack0_w ) |
| r18419 | r18420 | |
| 780 | 784 | |
| 781 | 785 | void wangpc_state::check_level2_interrupts() |
| 782 | 786 | { |
| 783 | int state = !m_dma_eop || m_uart_dr || m_uart_tbre || m_fdc_dd0 || m_fdc_dd1 || | |
| 787 | int state = !m_dma_eop || m_uart_dr || m_uart_tbre || m_fdc_dd0 || m_fdc_dd1 || m_fdc->get_irq() || m_fpu_irq || m_bus_irq2; | |
| 784 | 788 | |
| 785 | 789 | pic8259_ir2_w(m_pic, state); |
| 786 | 790 | } |
| r18419 | r18420 | |
| 868 | 872 | data |= m_uart_dr << 5; |
| 869 | 873 | |
| 870 | 874 | // FDC interrupt |
| 871 | data |= | |
| 875 | data |= m_fdc->get_irq() << 6; | |
| 872 | 876 | |
| 873 | 877 | // 8087 interrupt |
| 874 | 878 | data |= m_fpu_irq << 7; |
| r18419 | r18420 | |
| 1028 | 1032 | // upd765_interface fdc_intf |
| 1029 | 1033 | //------------------------------------------------- |
| 1030 | 1034 | |
| 1031 | static const floppy_interface floppy_intf = | |
| 1032 | { | |
| 1033 | DEVCB_NULL, | |
| 1034 | DEVCB_NULL, | |
| 1035 | DEVCB_NULL, | |
| 1036 | DEVCB_NULL, | |
| 1037 | DEVCB_NULL, | |
| 1038 | FLOPPY_STANDARD_5_25_DSDD, | |
| 1039 | LEGACY_FLOPPY_OPTIONS_NAME(pc), | |
| 1040 | "floppy_5_25", | |
| 1035 | ||
| 1036 | static const floppy_format_type wangpc_floppy_formats[] = { | |
| 1037 | FLOPPY_MFI_FORMAT, | |
| 1041 | 1038 | NULL |
| 1042 | 1039 | }; |
| 1043 | 1040 | |
| 1044 | WRITE_LINE_MEMBER( wangpc_state::fdc_int_w ) | |
| 1041 | static SLOT_INTERFACE_START( wangpc_floppies ) | |
| 1042 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 1043 | SLOT_INTERFACE_END | |
| 1044 | ||
| 1045 | void wangpc_state::fdc_irq(bool state) | |
| 1045 | 1046 | { |
| 1046 | 1047 | if (LOG) logerror("FDC INT %u\n", state); |
| 1047 | 1048 | |
| 1048 | 1049 | check_level2_interrupts(); |
| 1049 | 1050 | } |
| 1050 | 1051 | |
| 1051 | ||
| 1052 | void wangpc_state::fdc_drq(bool state) | |
| 1052 | 1053 | { |
| 1053 | 1054 | if (LOG) logerror("FDC DRQ %u\n", state); |
| 1054 | 1055 | |
| r18419 | r18420 | |
| 1064 | 1065 | m_dmac->dreq2_w(!m_fdc_drq); |
| 1065 | 1066 | } |
| 1066 | 1067 | |
| 1067 | static UPD765_GET_IMAGE( wangpc_fdc_get_image ) | |
| 1068 | { | |
| 1069 | wangpc_state *state = device->machine().driver_data<wangpc_state>(); | |
| 1070 | 1068 | |
| 1071 | if (!state->m_ds1) return state->m_floppy0; | |
| 1072 | if (!state->m_ds2) return state->m_floppy1; | |
| 1073 | ||
| 1074 | return NULL; | |
| 1075 | } | |
| 1076 | ||
| 1077 | static const upd765_interface fdc_intf = | |
| 1078 | { | |
| 1079 | DEVCB_DRIVER_LINE_MEMBER(wangpc_state, fdc_int_w), | |
| 1080 | DEVCB_DRIVER_LINE_MEMBER(wangpc_state, fdc_drq_w), | |
| 1081 | wangpc_fdc_get_image, | |
| 1082 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 1083 | { NULL, NULL, NULL, NULL } | |
| 1084 | }; | |
| 1085 | ||
| 1086 | ||
| 1087 | 1069 | //------------------------------------------------- |
| 1088 | 1070 | // centronics_interface centronics_intf |
| 1089 | 1071 | //------------------------------------------------- |
| r18419 | r18420 | |
| 1171 | 1153 | m_uart->connect(m_kb); |
| 1172 | 1154 | |
| 1173 | 1155 | // connect floppy callbacks |
| 1174 | floppy_install_unload_proc(m_floppy0, wangpc_state::on_disk0_change); | |
| 1175 | floppy_install_load_proc(m_floppy0, wangpc_state::on_disk0_change); | |
| 1176 | floppy_install_unload_proc(m_floppy1, wangpc_state::on_disk1_change); | |
| 1177 | floppy_install_load_proc(m_floppy1, wangpc_state::on_disk1_change); | |
| 1156 | m_floppy0->setup_load_cb(floppy_image_device::load_cb(FUNC(wangpc_state::on_disk0_load), this)); | |
| 1157 | m_floppy0->setup_unload_cb(floppy_image_device::unload_cb(FUNC(wangpc_state::on_disk0_unload), this)); | |
| 1158 | m_floppy1->setup_load_cb(floppy_image_device::load_cb(FUNC(wangpc_state::on_disk1_load), this)); | |
| 1159 | m_floppy1->setup_unload_cb(floppy_image_device::unload_cb(FUNC(wangpc_state::on_disk1_unload), this)); | |
| 1178 | 1160 | |
| 1161 | m_fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(wangpc_state::fdc_irq), this)); | |
| 1162 | m_fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(wangpc_state::fdc_drq), this)); | |
| 1163 | ||
| 1179 | 1164 | // state saving |
| 1180 | 1165 | save_item(NAME(m_dma_page)); |
| 1181 | 1166 | save_item(NAME(m_dack)); |
| r18419 | r18420 | |
| 1215 | 1200 | // on_disk0_change - |
| 1216 | 1201 | //------------------------------------------------- |
| 1217 | 1202 | |
| 1218 | ||
| 1203 | int wangpc_state::on_disk0_load(floppy_image_device *image) | |
| 1219 | 1204 | { |
| 1220 | wangpc_state *state = static_cast<wangpc_state *>(image.device().owner()); | |
| 1205 | on_disk0_unload(image); | |
| 1206 | return IMAGE_INIT_PASS; | |
| 1207 | } | |
| 1221 | 1208 | |
| 1209 | void wangpc_state::on_disk0_unload(floppy_image_device *image) | |
| 1210 | { | |
| 1222 | 1211 | if (LOG) logerror("Door 1 disturbed\n"); |
| 1223 | 1212 | |
| 1224 | state->m_fdc_dd0 = 1; | |
| 1225 | ||
| 1226 | state->check_level2_interrupts(); | |
| 1213 | m_fdc_dd0 = 1; | |
| 1214 | check_level2_interrupts(); | |
| 1227 | 1215 | } |
| 1228 | 1216 | |
| 1229 | 1217 | |
| r18419 | r18420 | |
| 1231 | 1219 | // on_disk1_change - |
| 1232 | 1220 | //------------------------------------------------- |
| 1233 | 1221 | |
| 1234 | ||
| 1222 | int wangpc_state::on_disk1_load(floppy_image_device *image) | |
| 1235 | 1223 | { |
| 1236 | wangpc_state *state = static_cast<wangpc_state *>(image.device().owner()); | |
| 1224 | on_disk0_unload(image); | |
| 1225 | return IMAGE_INIT_PASS; | |
| 1226 | } | |
| 1237 | 1227 | |
| 1228 | void wangpc_state::on_disk1_unload(floppy_image_device *image) | |
| 1229 | { | |
| 1238 | 1230 | if (LOG) logerror("Door 2 disturbed\n"); |
| 1239 | 1231 | |
| 1240 | state->m_fdc_dd1 = 1; | |
| 1241 | ||
| 1242 | state->check_level2_interrupts(); | |
| 1232 | m_fdc_dd1 = 1; | |
| 1233 | check_level2_interrupts(); | |
| 1243 | 1234 | } |
| 1244 | 1235 | |
| 1245 | 1236 | |
| r18419 | r18420 | |
| 1264 | 1255 | MCFG_PIT8253_ADD(I8253_TAG, pit_intf) |
| 1265 | 1256 | MCFG_IM6402_ADD(IM6402_TAG, uart_intf) |
| 1266 | 1257 | MCFG_MC2661_ADD(SCN2661_TAG, 0, epci_intf) |
| 1267 | MCFG_UPD765A_ADD(UPD765_TAG, fdc_intf) | |
| 1268 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf) | |
| 1258 | MCFG_UPD765A_ADD(UPD765_TAG, false, false) | |
| 1259 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", wangpc_floppies, "525dd", 0, wangpc_floppy_formats) | |
| 1260 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", wangpc_floppies, "525dd", 0, wangpc_floppy_formats) | |
| 1269 | 1261 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 1270 | 1262 | MCFG_WANGPC_KEYBOARD_ADD() |
| 1271 | 1263 |
| r18419 | r18420 | |
|---|---|---|
| 22 | 22 | #include "machine/upd765.h" |
| 23 | 23 | #include "sound/sn76496.h" |
| 24 | 24 | #include "video/mc6845.h" |
| 25 | #include "formats/mfi_dsk.h" | |
| 25 | 26 | #include "rendlay.h" |
| 26 | 27 | #include "includes/pasopia.h" |
| 27 | 28 | |
| r18419 | r18420 | |
| 38 | 39 | m_pio(*this, "z80pio"), |
| 39 | 40 | m_crtc(*this, "crtc"), |
| 40 | 41 | m_fdc(*this, "fdc"), |
| 42 | m_floppy(*this, "fdc:0:525hd"), | |
| 41 | 43 | m_sn1(*this, "sn1"), |
| 42 | 44 | m_sn2(*this, "sn2") |
| 43 | 45 | { } |
| r18419 | r18420 | |
| 49 | 51 | required_device<z80ctc_device> m_ctc; |
| 50 | 52 | required_device<z80pio_device> m_pio; |
| 51 | 53 | required_device<mc6845_device> m_crtc; |
| 52 | required_device<device_t> m_fdc; | |
| 54 | required_device<upd765a_device> m_fdc; | |
| 55 | required_device<floppy_image_device> m_floppy; | |
| 53 | 56 | required_device<sn76489a_device> m_sn1; |
| 54 | 57 | required_device<sn76489a_device> m_sn2; |
| 55 | 58 | DECLARE_READ8_MEMBER(vram_r); |
| 56 | 59 | DECLARE_WRITE8_MEMBER(vram_w); |
| 57 | 60 | DECLARE_WRITE8_MEMBER(pasopia7_memory_ctrl_w); |
| 58 | DECLARE_READ8_MEMBER(fdc_r); | |
| 59 | 61 | DECLARE_WRITE8_MEMBER(pac2_w); |
| 60 | 62 | DECLARE_READ8_MEMBER(pac2_r); |
| 61 | 63 | DECLARE_WRITE8_MEMBER(ram_bank_w); |
| 62 | 64 | DECLARE_WRITE8_MEMBER(pasopia7_6845_w); |
| 63 | DECLARE_READ8_MEMBER(pasopia7_fdc_r); | |
| 64 | DECLARE_WRITE8_MEMBER(pasopia7_fdc_w); | |
| 65 | 65 | DECLARE_READ8_MEMBER(pasopia7_io_r); |
| 66 | 66 | DECLARE_WRITE8_MEMBER(pasopia7_io_w); |
| 67 | DECLARE_READ8_MEMBER(pasopia7_fdc_r); | |
| 68 | DECLARE_WRITE8_MEMBER(pasopia7_fdc_w); | |
| 67 | 69 | DECLARE_READ8_MEMBER(mux_r); |
| 68 | 70 | DECLARE_READ8_MEMBER(keyb_r); |
| 69 | 71 | DECLARE_WRITE8_MEMBER(mux_w); |
| r18419 | r18420 | |
| 110 | 112 | DECLARE_PALETTE_INIT(p7_raster); |
| 111 | 113 | DECLARE_PALETTE_INIT(p7_lcd); |
| 112 | 114 | UINT32 screen_update_pasopia7(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 115 | ||
| 116 | void fdc_irq(bool state); | |
| 113 | 117 | }; |
| 114 | 118 | |
| 115 | 119 | #define VDP_CLOCK XTAL_3_579545MHz/4 |
| r18419 | r18420 | |
| 549 | 553 | { |
| 550 | 554 | switch(offset) |
| 551 | 555 | { |
| 552 | case 4: return upd765_status_r(m_fdc, space, 0); | |
| 553 | case 5: return upd765_data_r(m_fdc, space, 0); | |
| 556 | case 4: return m_fdc->msr_r(space, 0, 0xff); | |
| 557 | case 5: return m_fdc->fifo_r(space, 0, 0xff); | |
| 554 | 558 | //case 6: bit 7 interrupt bit |
| 555 | 559 | } |
| 556 | 560 | |
| r18419 | r18420 | |
| 561 | 565 | { |
| 562 | 566 | switch(offset) |
| 563 | 567 | { |
| 564 | case 0: upd765_tc_w(m_fdc, 0); break; | |
| 565 | case 2: upd765_tc_w(m_fdc, 1); break; | |
| 566 | case 5: upd765_data_w(m_fdc, space, 0, data); break; | |
| 568 | case 0: m_fdc->tc_w(false); break; | |
| 569 | case 2: m_fdc->tc_w(true); break; | |
| 570 | case 5: m_fdc->fifo_w(space, 0, data, 0xff); break; | |
| 567 | 571 | case 6: |
| 568 | upd765_reset_w(m_fdc, data & 0x80); | |
| 569 | floppy_mon_w(floppy_get_device(machine(), 0), (data & 0x40) ? CLEAR_LINE : ASSERT_LINE); | |
| 570 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), (data & 0x40), 0); | |
| 572 | if(data & 0x80) | |
| 573 | m_fdc->reset(); | |
| 574 | m_floppy->mon_w(!(data & 0x40)); | |
| 571 | 575 | break; |
| 572 | 576 | } |
| 573 | 577 | } |
| r18419 | r18420 | |
| 968 | 972 | palette_set_color_rgb(machine(), i, 0x30, 0x38, 0x10); |
| 969 | 973 | } |
| 970 | 974 | |
| 971 | ||
| 975 | void pasopia7_state::fdc_irq(bool state) | |
| 972 | 976 | { |
| 973 | DEVCB_CPU_INPUT_LINE("maincpu", INPUT_LINE_IRQ0), | |
| 974 | DEVCB_NULL, //DRQ, TODO | |
| 975 | NULL, | |
| 976 | UPD765_RDY_PIN_CONNECTED, | |
| 977 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 978 | }; | |
| 977 | m_maincpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); | |
| 978 | } | |
| 979 | 979 | |
| 980 | static const floppy_interface pasopia7_floppy_interface = | |
| 981 | { | |
| 982 | DEVCB_NULL, | |
| 983 | DEVCB_NULL, | |
| 984 | DEVCB_NULL, | |
| 985 | DEVCB_NULL, | |
| 986 | DEVCB_NULL, | |
| 987 | FLOPPY_STANDARD_5_25_DSHD, | |
| 988 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 989 | NULL, | |
| 980 | static const floppy_format_type pasopia7_floppy_formats[] = { | |
| 981 | FLOPPY_MFI_FORMAT, | |
| 990 | 982 | NULL |
| 991 | 983 | }; |
| 992 | 984 | |
| 985 | static SLOT_INTERFACE_START( pasopia7_floppies ) | |
| 986 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 987 | SLOT_INTERFACE_END | |
| 993 | 988 | |
| 994 | 989 | /************************************* |
| 995 | 990 | * |
| r18419 | r18420 | |
| 1007 | 1002 | DEVCB_NULL |
| 1008 | 1003 | }; |
| 1009 | 1004 | |
| 1010 | ||
| 1011 | 1005 | static MACHINE_CONFIG_START( p7_base, pasopia7_state ) |
| 1012 | 1006 | /* basic machine hardware */ |
| 1013 | 1007 | MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) |
| r18419 | r18420 | |
| 1031 | 1025 | MCFG_I8255_ADD( "ppi8255_0", ppi8255_intf_0 ) |
| 1032 | 1026 | MCFG_I8255_ADD( "ppi8255_1", ppi8255_intf_1 ) |
| 1033 | 1027 | MCFG_I8255_ADD( "ppi8255_2", ppi8255_intf_2 ) |
| 1034 | MCFG_UPD765A_ADD("fdc", pasopia7_upd765_interface) | |
| 1035 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(pasopia7_floppy_interface) | |
| 1028 | MCFG_UPD765A_ADD("fdc", true, true) | |
| 1029 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", pasopia7_floppies, "525hd", 0, pasopia7_floppy_formats) | |
| 1030 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", pasopia7_floppies, "525hd", 0, pasopia7_floppy_formats) | |
| 1036 | 1031 | MACHINE_CONFIG_END |
| 1037 | 1032 | |
| 1038 | 1033 | static MACHINE_CONFIG_DERIVED( p7_raster, p7_base ) |
| r18419 | r18420 | |
|---|---|---|
| 25 | 25 | */ |
| 26 | 26 | |
| 27 | 27 | #include "includes/tandy2k.h" |
| 28 | #include "formats/mfi_dsk.h" | |
| 28 | 29 | |
| 29 | 30 | enum |
| 30 | 31 | { |
| r18419 | r18420 | |
| 118 | 119 | pit8253_gate2_w(m_pit, BIT(data, 4)); |
| 119 | 120 | |
| 120 | 121 | // FDC reset |
| 121 | upd765_reset_w(m_fdc, BIT(data, 5)); | |
| 122 | if(BIT(data, 5)) | |
| 123 | m_fdc->reset(); | |
| 122 | 124 | |
| 123 | 125 | // timer 0 enable |
| 124 | 126 | m_maincpu->set_input_line(INPUT_LINE_TMRIN0, BIT(data, 6)); |
| r18419 | r18420 | |
| 195 | 197 | } |
| 196 | 198 | } |
| 197 | 199 | |
| 198 | READ8_MEMBER(tandy2k_state::fldtc_r) | |
| 200 | READ8_MEMBER( tandy2k_state::fldtc_r ) | |
| 199 | 201 | { |
| 200 | device_t *device = machine().device("AM_RANGE(0x00004, 0x00005) AM_READWRITE8(I8272A_TAG, fldtc_r, fldtc_w, 0x00ff)"); | |
| 201 | upd765_tc_w(device, 1); | |
| 202 | upd765_tc_w(device, 0); | |
| 202 | m_fdc->tc_w(true); | |
| 203 | m_fdc->tc_w(false); | |
| 203 | 204 | |
| 204 | 205 | return 0; |
| 205 | 206 | } |
| 206 | 207 | |
| 207 | WRITE8_MEMBER(tandy2k_state::fldtc_w) | |
| 208 | WRITE8_MEMBER( tandy2k_state::fldtc_w ) | |
| 208 | 209 | { |
| 209 | device_t *device = machine().device(I8272A_TAG); | |
| 210 | upd765_tc_w(device, 1); | |
| 211 | upd765_tc_w(device, 0); | |
| 210 | m_fdc->tc_w(true); | |
| 211 | m_fdc->tc_w(false); | |
| 212 | 212 | } |
| 213 | 213 | |
| 214 | 214 | WRITE8_MEMBER( tandy2k_state::addr_ctrl_w ) |
| r18419 | r18420 | |
| 273 | 273 | AM_RANGE(0x00002, 0x00003) AM_WRITE8(dma_mux_w, 0x00ff) |
| 274 | 274 | AM_RANGE(0x00004, 0x00005) AM_READWRITE8(fldtc_r, fldtc_w, 0x00ff) |
| 275 | 275 | AM_RANGE(0x00010, 0x00013) AM_DEVREADWRITE8(I8251A_TAG, i8251_device, data_r, data_w, 0x00ff) |
| 276 | AM_RANGE(0x00030, 0x00031) AM_DEVREAD8_LEGACY(I8272A_TAG, upd765_status_r, 0x00ff) | |
| 277 | AM_RANGE(0x00032, 0x00033) AM_DEVREADWRITE8_LEGACY(I8272A_TAG, upd765_data_r, upd765_data_w, 0x00ff) | |
| 276 | AM_RANGE(0x00030, 0x00033) AM_DEVICE8(I8272A_TAG, i8272a_device, map, 0x00ff) | |
| 278 | 277 | AM_RANGE(0x00040, 0x00047) AM_DEVREADWRITE8_LEGACY(I8253_TAG, pit8253_r, pit8253_w, 0x00ff) |
| 279 | 278 | AM_RANGE(0x00052, 0x00053) AM_READ8(kbint_clr_r, 0x00ff) |
| 280 | 279 | AM_RANGE(0x00050, 0x00057) AM_DEVREADWRITE8(I8255A_TAG, i8255_device, read, write, 0x00ff) |
| 281 | 280 | AM_RANGE(0x00060, 0x00063) AM_DEVREADWRITE8_LEGACY(I8259A_0_TAG, pic8259_r, pic8259_w, 0x00ff) |
| 282 | 281 | AM_RANGE(0x00070, 0x00073) AM_DEVREADWRITE8_LEGACY(I8259A_1_TAG, pic8259_r, pic8259_w, 0x00ff) |
| 283 | AM_RANGE(0x00080, 0x00081) AM_DEVREADWRITE8 | |
| 282 | AM_RANGE(0x00080, 0x00081) AM_DEVREADWRITE8(I8272A_TAG, i8272a_device, mdma_r, mdma_w, 0x00ff) | |
| 284 | 283 | // AM_RANGE(0x00100, 0x0017f) AM_DEVREADWRITE8(CRT9007_TAG, crt9007_device, read, write, 0x00ff) AM_WRITE8(addr_ctrl_w, 0xff00) |
| 285 | 284 | AM_RANGE(0x00100, 0x0017f) AM_READWRITE(vpac_r, vpac_w) |
| 286 | 285 | // AM_RANGE(0x00180, 0x00180) AM_READ8(hires_status_r, 0x00ff) |
| r18419 | r18420 | |
| 614 | 613 | |
| 615 | 614 | // Intel 8272 Interface |
| 616 | 615 | |
| 617 | ||
| 616 | void tandy2k_state::fdc_irq(bool state) | |
| 618 | 617 | { |
| 618 | pic8259_ir4_w(m_pic0, state); | |
| 619 | } | |
| 620 | ||
| 621 | void tandy2k_state::fdc_drq(bool state) | |
| 622 | { | |
| 619 | 623 | dma_request(0, state); |
| 620 | 624 | } |
| 621 | 625 | |
| 622 | static const struct upd765_interface fdc_intf = | |
| 623 | { | |
| 624 | DEVCB_DEVICE_LINE(I8259A_0_TAG, pic8259_ir4_w), | |
| 625 | DEVCB_DRIVER_LINE_MEMBER(tandy2k_state, busdmarq0_w), | |
| 626 | NULL, | |
| 627 | UPD765_RDY_PIN_CONNECTED, | |
| 628 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 626 | static const floppy_format_type tandy2k_floppy_formats[] = { | |
| 627 | FLOPPY_MFI_FORMAT, | |
| 628 | NULL | |
| 629 | 629 | }; |
| 630 | 630 | |
| 631 | static SLOT_INTERFACE_START( tandy2k_floppies ) | |
| 632 | SLOT_INTERFACE( "525qd", FLOPPY_525_QD ) | |
| 633 | SLOT_INTERFACE_END | |
| 634 | ||
| 631 | 635 | // Centronics Interface |
| 632 | 636 | |
| 633 | 637 | static const centronics_interface centronics_intf = |
| r18419 | r18420 | |
| 678 | 682 | |
| 679 | 683 | program.install_ram(0x00000, ram_size - 1, ram); |
| 680 | 684 | |
| 685 | m_fdc->setup_intrq_cb(i8272a_device::line_cb(FUNC(tandy2k_state::fdc_irq), this)); | |
| 686 | m_fdc->setup_drq_cb(i8272a_device::line_cb(FUNC(tandy2k_state::fdc_drq), this)); | |
| 687 | ||
| 681 | 688 | // patch out i186 relocation register check |
| 682 | 689 | UINT8 *rom = memregion(I80186_TAG)->base(); |
| 683 | 690 | rom[0x1f16] = 0x90; |
| r18419 | r18420 | |
| 731 | 738 | MCFG_PIT8253_ADD(I8253_TAG, pit_intf) |
| 732 | 739 | MCFG_PIC8259_ADD(I8259A_0_TAG, pic0_intf) |
| 733 | 740 | MCFG_PIC8259_ADD(I8259A_1_TAG, pic1_intf) |
| 734 | MCFG_UPD765A_ADD(I8272A_TAG, fdc_intf) | |
| 735 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(tandy2k_floppy_interface) | |
| 741 | MCFG_UPD765A_ADD(I8272A_TAG, true, true) | |
| 742 | MCFG_FLOPPY_DRIVE_ADD(I8272A_TAG ":0", tandy2k_floppies, "525qd", 0, tandy2k_floppy_formats) | |
| 743 | MCFG_FLOPPY_DRIVE_ADD(I8272A_TAG ":1", tandy2k_floppies, "525qd", 0, tandy2k_floppy_formats) | |
| 736 | 744 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics) |
| 737 | 745 | MCFG_TANDY2K_KEYBOARD_ADD(kb_intf) |
| 738 | 746 |
| r18419 | r18420 | |
|---|---|---|
| 104 | 104 | // pcw/pcw16 beeper |
| 105 | 105 | #include "sound/beep.h" |
| 106 | 106 | #include "machine/ram.h" |
| 107 | #include "formats/pc_dsk.h" | |
| 108 | #include "formats/mfi_dsk.h" | |
| 107 | 109 | |
| 108 | 110 | #include "pcw.lh" |
| 109 | 111 | |
| r18419 | r18420 | |
| 113 | 115 | static const UINT8 half_step_table[4] = { 0x01, 0x02, 0x04, 0x08 }; |
| 114 | 116 | static const UINT8 full_step_table[4] = { 0x03, 0x06, 0x0c, 0x09 }; |
| 115 | 117 | |
| 116 | ||
| 117 | ||
| 118 | 118 | static void pcw_update_interrupt_counter(pcw_state *state) |
| 119 | 119 | { |
| 120 | 120 | /* never increments past 15! */ |
| r18419 | r18420 | |
| 125 | 125 | state->m_interrupt_counter++; |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | /* PCW uses UPD765 in NON-DMA mode. FDC Ints are connected to /INT or | |
| 129 | /NMI depending on choice (see system control below) */ | |
| 130 | static const upd765_interface pcw_upd765_interface = | |
| 131 | { | |
| 132 | DEVCB_DRIVER_LINE_MEMBER(pcw_state,pcw_fdc_interrupt), | |
| 133 | DEVCB_NULL, | |
| 134 | NULL, | |
| 135 | UPD765_RDY_PIN_CONNECTED, | |
| 136 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 137 | }; | |
| 138 | 128 | |
| 139 | 129 | // set/reset INT and NMI lines |
| 140 | 130 | static void pcw_update_irqs(running_machine &machine) |
| r18419 | r18420 | |
| 178 | 168 | machine().scheduler().timer_set(attotime::from_usec(100), timer_expired_delegate(FUNC(pcw_state::pcw_timer_pulse),this)); |
| 179 | 169 | } |
| 180 | 170 | |
| 181 | /* fdc interrupt callback. set/clear fdc int */ | |
| 182 | WRITE_LINE_MEMBER(pcw_state::pcw_fdc_interrupt) | |
| 171 | /* PCW uses UPD765 in NON-DMA mode. FDC Ints are connected to /INT or | |
| 172 | * /NMI depending on choice (see system control below) | |
| 173 | * fdc interrupt callback. set/clear fdc int */ | |
| 174 | void pcw_state::pcw_fdc_interrupt(bool state) | |
| 183 | 175 | { |
| 184 | if (state | |
| 176 | if (!state) | |
| 185 | 177 | m_system_status &= ~(1<<5); |
| 186 | 178 | else |
| 187 | 179 | { |
| r18419 | r18420 | |
| 416 | 408 | |
| 417 | 409 | WRITE8_MEMBER(pcw_state::pcw_system_control_w) |
| 418 | 410 | { |
| 419 | device | |
| 411 | upd765a_device *fdc = machine().device<upd765a_device>("upd765"); | |
| 420 | 412 | device_t *speaker = machine().device(BEEPER_TAG); |
| 421 | 413 | LOG(("SYSTEM CONTROL: %d\n",data)); |
| 422 | 414 | |
| r18419 | r18420 | |
| 503 | 495 | /* set fdc terminal count */ |
| 504 | 496 | case 5: |
| 505 | 497 | { |
| 506 | | |
| 498 | fdc->tc_w(true); | |
| 507 | 499 | } |
| 508 | 500 | break; |
| 509 | 501 | |
| 510 | 502 | /* clear fdc terminal count */ |
| 511 | 503 | case 6: |
| 512 | 504 | { |
| 513 | | |
| 505 | fdc->tc_w(false); | |
| 514 | 506 | } |
| 515 | 507 | break; |
| 516 | 508 | |
| r18419 | r18420 | |
| 532 | 524 | /* disc motor on */ |
| 533 | 525 | case 9: |
| 534 | 526 | { |
| 535 | floppy_mon_w(floppy_get_device(machine(), 0), CLEAR_LINE); | |
| 536 | floppy_mon_w(floppy_get_device(machine(), 1), CLEAR_LINE); | |
| 537 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 1,1); | |
| 538 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 1,1); | |
| 527 | floppy_image_device *floppy; | |
| 528 | floppy = machine().device<floppy_connector>(":upd765:0")->get_device(); | |
| 529 | if(floppy) | |
| 530 | floppy->mon_w(0); | |
| 531 | floppy = machine().device<floppy_connector>(":upd765:1")->get_device(); | |
| 532 | if(floppy) | |
| 533 | floppy->mon_w(0); | |
| 539 | 534 | } |
| 540 | 535 | break; |
| 541 | 536 | |
| 542 | 537 | /* disc motor off */ |
| 543 | 538 | case 10: |
| 544 | 539 | { |
| 545 | floppy_mon_w(floppy_get_device(machine(), 0), ASSERT_LINE); | |
| 546 | floppy_mon_w(floppy_get_device(machine(), 1), ASSERT_LINE); | |
| 547 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 0,1); | |
| 548 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 0,1); | |
| 540 | floppy_image_device *floppy; | |
| 541 | floppy = machine().device<floppy_connector>(":upd765:0")->get_device(); | |
| 542 | if(floppy) | |
| 543 | floppy->mon_w(1); | |
| 544 | floppy = machine().device<floppy_connector>(":upd765:1")->get_device(); | |
| 545 | if(floppy) | |
| 546 | floppy->mon_w(1); | |
| 549 | 547 | } |
| 550 | 548 | break; |
| 551 | 549 | |
| r18419 | r18420 | |
| 632 | 630 | logerror("pcw expansion w: %04x %02x\n",offset+0x080, data); |
| 633 | 631 | } |
| 634 | 632 | |
| 635 | READ8_MEMBER(pcw_state::pcw_fdc_r) | |
| 636 | { | |
| 637 | device_t *fdc = machine().device("upd765"); | |
| 638 | /* from Jacob Nevins docs. FDC I/O is not fully decoded */ | |
| 639 | if (offset & 1) | |
| 640 | { | |
| 641 | return upd765_data_r(fdc, space, 0); | |
| 642 | } | |
| 643 | ||
| 644 | return upd765_status_r(fdc, space, 0); | |
| 645 | } | |
| 646 | ||
| 647 | WRITE8_MEMBER(pcw_state::pcw_fdc_w) | |
| 648 | { | |
| 649 | device_t *fdc = machine().device("upd765"); | |
| 650 | /* from Jacob Nevins docs. FDC I/O is not fully decoded */ | |
| 651 | if (offset & 1) | |
| 652 | { | |
| 653 | upd765_data_w(fdc, space, 0,data); | |
| 654 | } | |
| 655 | } | |
| 656 | ||
| 657 | 633 | static void pcw_printer_fire_pins(running_machine &machine, UINT16 pins) |
| 658 | 634 | { |
| 659 | 635 | pcw_state *state = machine.driver_data<pcw_state>(); |
| r18419 | r18420 | |
| 985 | 961 | |
| 986 | 962 | static ADDRESS_MAP_START(pcw_io, AS_IO, 8, pcw_state ) |
| 987 | 963 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 988 | AM_RANGE(0x000, 0x07f) AM_R | |
| 964 | AM_RANGE(0x000, 0x07f) AM_MIRROR(0xfe) AM_DEVICE("upd765", upd765a_device, map) | |
| 989 | 965 | AM_RANGE(0x080, 0x0ef) AM_READWRITE(pcw_expansion_r, pcw_expansion_w) |
| 990 | 966 | AM_RANGE(0x0f0, 0x0f3) AM_WRITE( pcw_bank_select_w) |
| 991 | 967 | AM_RANGE(0x0f4, 0x0f4) AM_READWRITE(pcw_interrupt_counter_r, pcw_bank_force_selection_w) |
| r18419 | r18420 | |
| 1001 | 977 | |
| 1002 | 978 | static ADDRESS_MAP_START(pcw9512_io, AS_IO, 8, pcw_state ) |
| 1003 | 979 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 1004 | AM_RANGE(0x000, 0x07f) AM_R | |
| 980 | AM_RANGE(0x000, 0x07f) AM_MIRROR(0xfe) AM_DEVICE("upd765", upd765a_device, map) | |
| 1005 | 981 | AM_RANGE(0x080, 0x0ef) AM_READWRITE(pcw_expansion_r, pcw_expansion_w) |
| 1006 | 982 | AM_RANGE(0x0f0, 0x0f3) AM_WRITE( pcw_bank_select_w) |
| 1007 | 983 | AM_RANGE(0x0f4, 0x0f4) AM_READWRITE(pcw_interrupt_counter_r, pcw_bank_force_selection_w) |
| r18419 | r18420 | |
| 1290 | 1266 | PORT_BIT( 0xff, 0x00, IPT_UNUSED) |
| 1291 | 1267 | INPUT_PORTS_END |
| 1292 | 1268 | |
| 1293 | static const floppy_interface pcw_floppy_interface = | |
| 1294 | { | |
| 1295 | DEVCB_NULL, | |
| 1296 | DEVCB_NULL, | |
| 1297 | DEVCB_NULL, | |
| 1298 | DEVCB_NULL, | |
| 1299 | DEVCB_NULL, | |
| 1300 | FLOPPY_STANDARD_5_25_DSHD, | |
| 1301 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 1302 | "floppy_5_25", | |
| 1269 | static const floppy_format_type pcw_floppy_formats[] = { | |
| 1270 | FLOPPY_MFI_FORMAT, | |
| 1303 | 1271 | NULL |
| 1304 | 1272 | }; |
| 1305 | 1273 | |
| 1274 | static SLOT_INTERFACE_START( pcw_floppies ) | |
| 1275 | SLOT_INTERFACE( "3dsdd", FLOPPY_3_DSDD ) | |
| 1276 | SLOT_INTERFACE_END | |
| 1277 | ||
| 1306 | 1278 | /* PCW8256, PCW8512, PCW9256 */ |
| 1307 | 1279 | static MACHINE_CONFIG_START( pcw, pcw_state ) |
| 1308 | 1280 | /* basic machine hardware */ |
| r18419 | r18420 | |
| 1336 | 1308 | MCFG_SOUND_ADD(BEEPER_TAG, BEEP, 0) |
| 1337 | 1309 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 1338 | 1310 | |
| 1339 | MCFG_UPD765A_ADD("upd765", | |
| 1311 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 1340 | 1312 | |
| 1341 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(pcw_floppy_interface) | |
| 1313 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", pcw_floppies, "3dsdd", 0, pcw_floppy_formats) | |
| 1314 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", pcw_floppies, "3dsdd", 0, pcw_floppy_formats) | |
| 1315 | ||
| 1342 | 1316 | MCFG_SOFTWARE_LIST_ADD("disk_list","pcw") |
| 1343 | 1317 | |
| 1344 | 1318 | /* internal ram */ |
| r18419 | r18420 | |
|---|---|---|
| 41 | 41 | #include "video/upd7220.h" |
| 42 | 42 | #include "machine/upd765.h" |
| 43 | 43 | #include "machine/ram.h" |
| 44 | #include "formats/mfi_dsk.h" | |
| 44 | 45 | |
| 45 | 46 | #define MAIN_CLK 15974400 |
| 46 | 47 | |
| r18419 | r18420 | |
| 75 | 76 | required_device<i8255_device> m_ppi; |
| 76 | 77 | required_device<i8237_device> m_dma_1; |
| 77 | 78 | required_device<i8237_device> m_dma_2; |
| 78 | required_device<device | |
| 79 | required_device<upd765a_device> m_fdc; | |
| 79 | 80 | required_device<upd7220_device> m_hgdc; |
| 80 | 81 | required_device<mc146818_device> m_rtc; |
| 81 | 82 | UINT8 m_vram_bank; |
| r18419 | r18420 | |
| 91 | 92 | DECLARE_WRITE8_MEMBER( qx10_18_w ); |
| 92 | 93 | DECLARE_WRITE8_MEMBER( prom_sel_w ); |
| 93 | 94 | DECLARE_WRITE8_MEMBER( cmos_sel_w ); |
| 94 | DECLARE_WRITE_LINE_MEMBER( qx10_upd765_interrupt ); | |
| 95 | DECLARE_WRITE_LINE_MEMBER( drq_w ); | |
| 95 | void qx10_upd765_interrupt(bool state); | |
| 96 | void drq_w(bool state); | |
| 97 | DECLARE_READ8_MEMBER( fdc_dma_r ); | |
| 98 | DECLARE_WRITE8_MEMBER( fdc_dma_w ); | |
| 96 | 99 | DECLARE_WRITE8_MEMBER( fdd_motor_w ); |
| 97 | 100 | DECLARE_READ8_MEMBER( qx10_30_r ); |
| 98 | 101 | DECLARE_READ8_MEMBER( gdc_dack_r ); |
| r18419 | r18420 | |
| 267 | 270 | } |
| 268 | 271 | } |
| 269 | 272 | |
| 273 | READ8_MEMBER( qx10_state::fdc_dma_r ) | |
| 274 | { | |
| 275 | return m_fdc->dma_r(); | |
| 276 | } | |
| 277 | ||
| 278 | WRITE8_MEMBER( qx10_state::fdc_dma_w ) | |
| 279 | { | |
| 280 | m_fdc->dma_w(data); | |
| 281 | } | |
| 282 | ||
| 283 | ||
| 270 | 284 | WRITE8_MEMBER( qx10_state::qx10_18_w ) |
| 271 | 285 | { |
| 272 | 286 | m_membank = (data >> 4) & 0x0f; |
| r18419 | r18420 | |
| 289 | 303 | FDD |
| 290 | 304 | */ |
| 291 | 305 | |
| 292 | static const floppy_interface qx10_floppy_interface = | |
| 293 | { | |
| 294 | DEVCB_NULL, | |
| 295 | DEVCB_NULL, | |
| 296 | DEVCB_NULL, | |
| 297 | DEVCB_NULL, | |
| 298 | DEVCB_NULL, | |
| 299 | FLOPPY_STANDARD_5_25_DSHD, | |
| 300 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 301 | NULL, | |
| 306 | static const floppy_format_type qx10_floppy_formats[] = { | |
| 307 | FLOPPY_MFI_FORMAT, | |
| 302 | 308 | NULL |
| 303 | 309 | }; |
| 304 | 310 | |
| 305 | WRITE_LINE_MEMBER( qx10_state::qx10_upd765_interrupt ) | |
| 311 | static SLOT_INTERFACE_START( qx10_floppies ) | |
| 312 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 313 | SLOT_INTERFACE_END | |
| 314 | ||
| 315 | void qx10_state::qx10_upd765_interrupt(bool state) | |
| 306 | 316 | { |
| 307 | 317 | m_fdcint = state; |
| 308 | 318 | |
| 309 | 319 | //logerror("Interrupt from upd765: %d\n", state); |
| 310 | 320 | // signal interrupt |
| 311 | 321 | pic8259_ir6_w(m_pic_m, state); |
| 312 | } | |
| 322 | } | |
| 313 | 323 | |
| 314 | ||
| 324 | void qx10_state::drq_w(bool state) | |
| 315 | 325 | { |
| 316 | 326 | i8237_dreq0_w(m_dma_1, !state); |
| 317 | 327 | } |
| 318 | 328 | |
| 319 | static const struct upd765_interface qx10_upd765_interface = | |
| 320 | { | |
| 321 | DEVCB_DRIVER_LINE_MEMBER(qx10_state, qx10_upd765_interrupt), | |
| 322 | DEVCB_DRIVER_LINE_MEMBER(qx10_state, drq_w), | |
| 323 | NULL, | |
| 324 | UPD765_RDY_PIN_CONNECTED, | |
| 325 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 326 | }; | |
| 327 | ||
| 328 | 329 | WRITE8_MEMBER( qx10_state::fdd_motor_w ) |
| 329 | 330 | { |
| 330 | 331 | m_fdcmotor = 1; |
| 331 | 332 | |
| 332 | floppy_mon_w(floppy_get_device(machine(), 0), CLEAR_LINE); | |
| 333 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 1,1); | |
| 333 | machine().device<floppy_connector>("upd765:0")->get_device()->mon_w(false); | |
| 334 | 334 | // motor off controlled by clock |
| 335 | } | |
| 335 | } | |
| 336 | 336 | |
| 337 | 337 | READ8_MEMBER( qx10_state::qx10_30_r ) |
| 338 | 338 | { |
| 339 | floppy_image_ | |
| 339 | floppy_image_device *floppy1,*floppy2; | |
| 340 | 340 | |
| 341 | floppy1 = flopimg_get_image(floppy_get_device(machine(), 0)); | |
| 342 | floppy2 = flopimg_get_image(floppy_get_device(machine(), 1)); | |
| 341 | floppy1 = machine().device<floppy_connector>("upd765:0")->get_device(); | |
| 342 | floppy2 = machine().device<floppy_connector>("upd765:1")->get_device(); | |
| 343 | 343 | |
| 344 | 344 | return m_fdcint | |
| 345 | 345 | /*m_fdcmotor*/ 0 << 1 | |
| 346 | 346 | ((floppy1 != NULL) || (floppy2 != NULL) ? 1 : 0) << 3 | |
| 347 | 347 | m_membank << 4; |
| 348 | } | |
| 348 | } | |
| 349 | 349 | |
| 350 | 350 | /* |
| 351 | 351 | DMA8237 |
| r18419 | r18420 | |
| 371 | 371 | WRITE_LINE_MEMBER( qx10_state::tc_w ) |
| 372 | 372 | { |
| 373 | 373 | /* floppy terminal count */ |
| 374 | | |
| 374 | m_fdc->tc_w(!state); | |
| 375 | 375 | } |
| 376 | 376 | |
| 377 | 377 | /* |
| r18419 | r18420 | |
| 389 | 389 | DEVCB_DRIVER_LINE_MEMBER(qx10_state, tc_w), |
| 390 | 390 | DEVCB_MEMORY_HANDLER("maincpu", PROGRAM, memory_read_byte), |
| 391 | 391 | DEVCB_MEMORY_HANDLER("maincpu", PROGRAM, memory_write_byte), |
| 392 | { DEVCB_DEVICE_HANDLER("upd765", upd765_dack_r), DEVCB_DRIVER_MEMBER(qx10_state, gdc_dack_r),/*DEVCB_DEVICE_HANDLER("upd7220", upd7220_dack_r)*/ DEVCB_NULL, DEVCB_NULL }, | |
| 393 | { DEVCB_DEVICE_HANDLER("upd765", upd765_dack_w), DEVCB_DRIVER_MEMBER(qx10_state, gdc_dack_w),/*DEVCB_DEVICE_HANDLER("upd7220", upd7220_dack_w)*/ DEVCB_NULL, DEVCB_NULL }, | |
| 392 | { DEVCB_DRIVER_MEMBER(qx10_state, fdc_dma_r), DEVCB_DRIVER_MEMBER(qx10_state, gdc_dack_r),/*DEVCB_DEVICE_HANDLER("upd7220", upd7220_dack_r)*/ DEVCB_NULL, DEVCB_NULL }, | |
| 393 | { DEVCB_DRIVER_MEMBER(qx10_state, fdc_dma_w), DEVCB_DRIVER_MEMBER(qx10_state, gdc_dack_w),/*DEVCB_DEVICE_HANDLER("upd7220", upd7220_dack_w)*/ DEVCB_NULL, DEVCB_NULL }, | |
| 394 | 394 | { DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL } |
| 395 | 395 | }; |
| 396 | 396 | |
| r18419 | r18420 | |
| 431 | 431 | READ8_MEMBER( qx10_state::mc146818_data_r ) |
| 432 | 432 | { |
| 433 | 433 | return m_rtc->read(space, m_mc146818_offset); |
| 434 | } | |
| 434 | } | |
| 435 | 435 | |
| 436 | 436 | WRITE8_MEMBER( qx10_state::mc146818_data_w ) |
| 437 | 437 | { |
| 438 | 438 | m_rtc->write(space, m_mc146818_offset, data); |
| 439 | } | |
| 439 | } | |
| 440 | 440 | |
| 441 | 441 | WRITE8_MEMBER( qx10_state::mc146818_offset_w ) |
| 442 | 442 | { |
| 443 | 443 | m_mc146818_offset = data; |
| 444 | } | |
| 444 | } | |
| 445 | 445 | |
| 446 | 446 | /* |
| 447 | 447 | UPD7201 |
| r18419 | r18420 | |
| 675 | 675 | AM_RANGE(0x2c, 0x2c) AM_READ_PORT("CONFIG") |
| 676 | 676 | AM_RANGE(0x2d, 0x2d) AM_READWRITE(vram_bank_r,vram_bank_w) |
| 677 | 677 | AM_RANGE(0x30, 0x33) AM_READWRITE(qx10_30_r, fdd_motor_w) |
| 678 | AM_RANGE(0x34, 0x34) AM_DEVREAD_LEGACY("upd765", upd765_status_r) | |
| 679 | AM_RANGE(0x35, 0x35) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w) | |
| 678 | AM_RANGE(0x34, 0x35) AM_DEVICE("upd765", upd765a_device, map) | |
| 680 | 679 | AM_RANGE(0x38, 0x39) AM_DEVREADWRITE("upd7220", upd7220_device, read, write) |
| 681 | 680 | // AM_RANGE(0x3a, 0x3a) GDC zoom |
| 682 | 681 | // AM_RANGE(0x3b, 0x3b) GDC light pen req |
| r18419 | r18420 | |
| 903 | 902 | void qx10_state::machine_start() |
| 904 | 903 | { |
| 905 | 904 | machine().device("maincpu")->execute().set_irq_acknowledge_callback(irq_callback); |
| 905 | m_fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(qx10_state::qx10_upd765_interrupt), this)); | |
| 906 | m_fdc->setup_drq_cb(upd765a_device::line_cb(FUNC(qx10_state::drq_w), this)); | |
| 906 | 907 | } |
| 907 | 908 | |
| 908 | 909 | void qx10_state::machine_reset() |
| r18419 | r18420 | |
| 1034 | 1035 | MCFG_I8237_ADD("8237dma_2", MAIN_CLK/4, qx10_dma8237_2_interface) |
| 1035 | 1036 | MCFG_UPD7220_ADD("upd7220", MAIN_CLK/4, hgdc_intf, upd7220_map) |
| 1036 | 1037 | MCFG_MC146818_ADD( "rtc", MC146818_STANDARD ) |
| 1037 | MCFG_UPD765A_ADD("upd765", qx10_upd765_interface) | |
| 1038 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(qx10_floppy_interface) | |
| 1038 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 1039 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", qx10_floppies, "525hd", 0, qx10_floppy_formats) | |
| 1040 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", qx10_floppies, "525hd", 0, qx10_floppy_formats) | |
| 1039 | 1041 | |
| 1040 | 1042 | /* internal ram */ |
| 1041 | 1043 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 41 | 41 | ******************************************************************************/ |
| 42 | 42 | |
| 43 | 43 | #include "includes/compis.h" |
| 44 | #include "formats/mfi_dsk.h" | |
| 44 | 45 | |
| 45 | 46 | #if 0 |
| 46 | 47 | /* TODO: this is likely to come from a RAMdac ... */ |
| r18419 | r18420 | |
| 165 | 166 | //AM_RANGE( 0x0288, 0x028f) AM_DEVREADWRITE_LEGACY("pit8254", compis_osp_pit_r, compis_osp_pit_w ) /* PIT 8254 (80150/80130) */ |
| 166 | 167 | AM_RANGE( 0x0310, 0x031f) AM_READWRITE( compis_usart_r, compis_usart_w ) /* USART 8251 Keyboard */ |
| 167 | 168 | AM_RANGE( 0x0330, 0x0333) AM_DEVREADWRITE8("upd7220", upd7220_device, read, write, 0x00ff) /* GDC 82720 PCS6:6 */ |
| 168 | AM_RANGE( 0x0340, 0x0343) AM_READWRITE8( compis_fdc_r, compis_fdc_w, 0xffff ) /* iSBX0 (J8) FDC 8272 */ | |
| 169 | AM_RANGE( 0x0350, 0x0351) AM_READ(compis_fdc_dack_r) /* iSBX0 (J8) DMA ACK */ | |
| 169 | AM_RANGE( 0x0340, 0x0343) AM_DEVICE8("i8272a", i8272a_device, map, 0x00ff) /* iSBX0 (J8) FDC 8272 */ | |
| 170 | AM_RANGE( 0x0350, 0x0351) AM_DEVREADWRITE8("i8272a", i8272a_device, mdma_r, mdma_w, 0x00ff) /* iSBX0 (J8) DMA ACK */ | |
| 170 | 171 | AM_RANGE( 0xff00, 0xffff) AM_READWRITE( compis_i186_internal_port_r, compis_i186_internal_port_w)/* CPU 80186 */ |
| 171 | 172 | //{ 0x0100, 0x017e, compis_null_r }, /* RTC */ |
| 172 | 173 | //{ 0x0180, 0x01ff, compis_null_r }, /* PCS3? */ |
| r18419 | r18420 | |
| 334 | 335 | 1 /* first day of week */ |
| 335 | 336 | }; |
| 336 | 337 | |
| 337 | static const floppy_interface compis_floppy_interface = | |
| 338 | { | |
| 339 | DEVCB_NULL, | |
| 340 | DEVCB_NULL, | |
| 341 | DEVCB_NULL, | |
| 342 | DEVCB_NULL, | |
| 343 | DEVCB_NULL, | |
| 344 | FLOPPY_STANDARD_5_25_DSQD, | |
| 345 | LEGACY_FLOPPY_OPTIONS_NAME(compis), | |
| 346 | "floppy_5_25", | |
| 338 | ||
| 339 | static const floppy_format_type compis_floppy_formats[] = { | |
| 340 | FLOPPY_MFI_FORMAT, | |
| 347 | 341 | NULL |
| 348 | 342 | }; |
| 349 | 343 | |
| 344 | static SLOT_INTERFACE_START( compis_floppies ) | |
| 345 | SLOT_INTERFACE( "525qd", FLOPPY_525_QD ) | |
| 346 | SLOT_INTERFACE_END | |
| 347 | ||
| 350 | 348 | static ADDRESS_MAP_START( upd7220_map, AS_0, 8, compis_state ) |
| 351 | 349 | ADDRESS_MAP_GLOBAL_MASK(0x1ffff) |
| 352 | 350 | AM_RANGE(0x00000, 0x1ffff) AM_RAM AM_SHARE("video_ram") |
| r18419 | r18420 | |
| 387 | 385 | MCFG_CENTRONICS_PRINTER_ADD("centronics", standard_centronics) |
| 388 | 386 | MCFG_I8251_ADD("uart", compis_usart_interface) |
| 389 | 387 | MCFG_MM58274C_ADD("mm58274c", compis_mm58274c_interface) |
| 390 | MCFG_UPD765A_ADD("upd765", compis_fdc_interface) | |
| 391 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(compis_floppy_interface) | |
| 388 | MCFG_I8272A_ADD("i8272a", true) | |
| 389 | MCFG_FLOPPY_DRIVE_ADD("i8272a:0", compis_floppies, "525qd", 0, compis_floppy_formats) | |
| 390 | MCFG_FLOPPY_DRIVE_ADD("i8272a:1", compis_floppies, "525qd", 0, compis_floppy_formats) | |
| 392 | 391 | MCFG_COMPIS_KEYBOARD_ADD() |
| 393 | 392 | |
| 394 | 393 | /* software lists */ |
| r18419 | r18420 | |
| 426 | 425 | MCFG_CENTRONICS_PRINTER_ADD("centronics", standard_centronics) |
| 427 | 426 | MCFG_I8251_ADD("uart", compis_usart_interface) |
| 428 | 427 | MCFG_MM58274C_ADD("mm58274c", compis_mm58274c_interface) |
| 429 | MCFG_UPD765A_ADD("upd765", compis_fdc_interface) | |
| 430 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(compis_floppy_interface) | |
| 428 | MCFG_I8272A_ADD("i8272a", true) | |
| 429 | MCFG_FLOPPY_DRIVE_ADD("i8272a:0", compis_floppies, "525qd", 0, compis_floppy_formats) | |
| 430 | MCFG_FLOPPY_DRIVE_ADD("i8272a:1", compis_floppies, "525qd", 0, compis_floppy_formats) | |
| 431 | 431 | MCFG_COMPIS_KEYBOARD_ADD() |
| 432 | 432 | |
| 433 | 433 | /* software lists */ |
| r18419 | r18420 | |
|---|---|---|
| 31 | 31 | */ |
| 32 | 32 | |
| 33 | 33 | #include "includes/sage2.h" |
| 34 | #include "formats/mfi_dsk.h" | |
| 34 | 35 | |
| 35 | 36 | |
| 36 | ||
| 37 | 37 | //************************************************************************** |
| 38 | 38 | // MEMORY MANAGEMENT UNIT |
| 39 | 39 | //************************************************************************** |
| r18419 | r18420 | |
| 90 | 90 | AM_RANGE(0xffc030, 0xffc031) AM_DEVREADWRITE8(I8251_1_TAG, i8251_device, data_r, data_w, 0x00ff) |
| 91 | 91 | AM_RANGE(0xffc032, 0xffc033) AM_DEVREADWRITE8(I8251_1_TAG, i8251_device, status_r, control_w, 0x00ff) |
| 92 | 92 | AM_RANGE(0xffc040, 0xffc043) AM_DEVREADWRITE8_LEGACY(I8259_TAG, pic8259_r, pic8259_w, 0x00ff) |
| 93 | AM_RANGE(0xffc050, 0xffc051) AM_DEVREAD8_LEGACY(UPD765_TAG, upd765_status_r, 0x00ff) | |
| 94 | AM_RANGE(0xffc052, 0xffc053) AM_DEVREADWRITE8_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w, 0x00ff) | |
| 93 | AM_RANGE(0xffc050, 0xffc053) AM_DEVICE8(UPD765_TAG, upd765a_device, map, 0x00ff) | |
| 95 | 94 | AM_RANGE(0xffc060, 0xffc067) AM_DEVREADWRITE8(I8255A_0_TAG, i8255_device, read, write, 0x00ff) // i8255, Printer |
| 96 | 95 | AM_RANGE(0xffc070, 0xffc071) AM_DEVREAD8(I8251_0_TAG, i8251_device, data_r, 0x00ff) AM_DEVWRITE8(TERMINAL_TAG, generic_terminal_device, write, 0x00ff) |
| 97 | 96 | // AM_RANGE(0xffc070, 0xffc071) AM_DEVREADWRITE8(I8251_0_TAG, i8251_device, data_r, data_w, 0x00ff) |
| r18419 | r18420 | |
| 238 | 237 | */ |
| 239 | 238 | |
| 240 | 239 | // floppy terminal count |
| 241 | | |
| 240 | m_fdc->tc_w(BIT(data, 0)); | |
| 242 | 241 | |
| 243 | 242 | // floppy ready |
| 244 | | |
| 243 | m_fdc->ready_w(BIT(data, 1)); | |
| 245 | 244 | |
| 246 | 245 | // floppy interrupt enable |
| 247 | 246 | m_fdie = BIT(data, 2); |
| r18419 | r18420 | |
| 251 | 250 | m_sl0 = BIT(data, 3); |
| 252 | 251 | m_sl1 = BIT(data, 4); |
| 253 | 252 | |
| 253 | if(m_sl0) | |
| 254 | m_fdc->set_floppy(m_floppy0); | |
| 255 | else if(m_sl1) | |
| 256 | m_fdc->set_floppy(m_floppy1); | |
| 257 | else | |
| 258 | m_fdc->set_floppy(NULL); | |
| 259 | ||
| 254 | 260 | // floppy motor |
| 255 | floppy_mon_w(m_floppy0, BIT(data, 5)); | |
| 256 | floppy_mon_w(m_floppy1, BIT(data, 5)); | |
| 261 | m_floppy0->mon_w(BIT(data, 5)); | |
| 262 | m_floppy1->mon_w(BIT(data, 5)); | |
| 257 | 263 | |
| 258 | 264 | // FDC reset |
| 259 | upd765_reset_w(m_fdc, BIT(data, 7)); | |
| 265 | if(BIT(data, 7)) | |
| 266 | m_fdc->reset(); | |
| 260 | 267 | } |
| 261 | 268 | |
| 262 | 269 | static I8255A_INTERFACE( ppi0_intf ) |
| r18419 | r18420 | |
| 294 | 301 | UINT8 data = 0; |
| 295 | 302 | |
| 296 | 303 | // floppy interrupt |
| 297 | data = | |
| 304 | data = m_fdc->get_irq(); | |
| 298 | 305 | |
| 299 | 306 | // floppy write protected |
| 300 | 307 | if (!m_sl0) data |= floppy_wpt_r(m_floppy0) << 1; |
| r18419 | r18420 | |
| 470 | 477 | // upd765_interface fdc_intf |
| 471 | 478 | //------------------------------------------------- |
| 472 | 479 | |
| 473 | static const floppy_interface floppy_intf = | |
| 474 | { | |
| 475 | DEVCB_NULL, | |
| 476 | DEVCB_NULL, | |
| 477 | DEVCB_NULL, | |
| 478 | DEVCB_NULL, | |
| 479 | DEVCB_NULL, | |
| 480 | FLOPPY_STANDARD_5_25_DSDD, | |
| 481 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 482 | "floppy_5_25", | |
| 480 | static const floppy_format_type sage2_floppy_formats[] = { | |
| 481 | FLOPPY_MFI_FORMAT, | |
| 483 | 482 | NULL |
| 484 | 483 | }; |
| 485 | 484 | |
| 485 | static SLOT_INTERFACE_START( sage2_floppies ) | |
| 486 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 487 | SLOT_INTERFACE_END | |
| 488 | ||
| 486 | 489 | void sage2_state::update_fdc_int() |
| 487 | 490 | { |
| 488 | 491 | m_maincpu->set_input_line(M68K_IRQ_6, m_fdie & m_fdc_int); |
| 489 | 492 | } |
| 490 | 493 | |
| 491 | ||
| 494 | void sage2_state::fdc_irq(bool state) | |
| 492 | 495 | { |
| 493 | 496 | m_fdc_int = state; |
| 494 | 497 | update_fdc_int(); |
| 495 | 498 | } |
| 496 | 499 | |
| 497 | ||
| 500 | void sage2_state::machine_start() | |
| 498 | 501 | { |
| 499 | sage2_state *state = device->machine().driver_data<sage2_state>(); | |
| 500 | ||
| 501 | if (!state->m_sl0) return state->m_floppy0; | |
| 502 | if (!state->m_sl1) return state->m_floppy1; | |
| 503 | ||
| 504 | return NULL; | |
| 502 | m_fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(sage2_state::fdc_irq), this)); | |
| 505 | 503 | } |
| 506 | 504 | |
| 507 | static const upd765_interface fdc_intf = | |
| 508 | { | |
| 509 | DEVCB_DRIVER_LINE_MEMBER(sage2_state, fdc_int_w), | |
| 510 | DEVCB_NULL, | |
| 511 | fdc_get_image, | |
| 512 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 513 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 514 | }; | |
| 515 | ||
| 516 | ||
| 517 | 505 | //------------------------------------------------- |
| 518 | 506 | // centronics_interface centronics_intf |
| 519 | 507 | //------------------------------------------------- |
| r18419 | r18420 | |
| 606 | 594 | MCFG_PIT8253_ADD(I8253_1_TAG, pit1_intf) |
| 607 | 595 | MCFG_I8251_ADD(I8251_0_TAG, usart0_intf) |
| 608 | 596 | MCFG_I8251_ADD(I8251_1_TAG, usart1_intf) |
| 609 | MCFG_UPD765A_ADD(UPD765_TAG, f | |
| 597 | MCFG_UPD765A_ADD(UPD765_TAG, false, false) | |
| 610 | 598 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, centronics_intf) |
| 611 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf) | |
| 599 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", sage2_floppies, "525dd", 0, sage2_floppy_formats) | |
| 600 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", sage2_floppies, "525dd", 0, sage2_floppy_formats) | |
| 612 | 601 | MCFG_IEEE488_BUS_ADD(ieee488_intf) |
| 613 | 602 | |
| 614 | 603 | // internal ram |
| r18419 | r18420 | |
|---|---|---|
| 355 | 355 | SLOT_INTERFACE("svga_dm",ISA8_SVGA_CIRRUS) |
| 356 | 356 | SLOT_INTERFACE("com", ISA8_COM) |
| 357 | 357 | SLOT_INTERFACE("comat", ISA8_COM_AT) |
| 358 | SLOT_INTERFACE("fdc", ISA8_FDC) | |
| 358 | SLOT_INTERFACE("fdc", ISA8_FDC_AT) | |
| 359 | 359 | SLOT_INTERFACE("hdc", ISA8_HDC) |
| 360 | 360 | SLOT_INTERFACE("adlib", ISA8_ADLIB) |
| 361 | 361 | SLOT_INTERFACE("hercules", ISA8_HERCULES) |
| r18419 | r18420 | |
|---|---|---|
| 14 | 14 | #include "machine/z80ctc.h" |
| 15 | 15 | #include "machine/upd765.h" |
| 16 | 16 | #include "imagedev/flopdrv.h" |
| 17 | #include "formats/basicdsk.h" | |
| 17 | #include "formats/mfi_dsk.h" | |
| 18 | #include "formats/nanos_dsk.h" | |
| 18 | 19 | #include "machine/ram.h" |
| 19 | 20 | |
| 20 | 21 | |
| r18419 | r18420 | |
| 43 | 44 | required_device<z80sio_device> m_sio_1; |
| 44 | 45 | required_device<z80ctc_device> m_ctc_0; |
| 45 | 46 | required_device<z80ctc_device> m_ctc_1; |
| 46 | required_device<device | |
| 47 | required_device<upd765a_device> m_fdc; | |
| 47 | 48 | required_device<device_t> m_key_t; |
| 48 | 49 | const UINT8 *m_p_chargen; |
| 49 | 50 | UINT8 m_key_command; |
| r18419 | r18420 | |
| 73 | 74 | |
| 74 | 75 | WRITE8_MEMBER(nanos_state::nanos_tc_w) |
| 75 | 76 | { |
| 76 | | |
| 77 | m_fdc->tc_w(BIT(data,1)); | |
| 77 | 78 | } |
| 78 | 79 | |
| 79 | 80 | |
| r18419 | r18420 | |
| 167 | 168 | |
| 168 | 169 | /* FDC card */ |
| 169 | 170 | AM_RANGE(0x92, 0x92) AM_WRITE(nanos_tc_w) |
| 170 | AM_RANGE(0x94, 0x94) AM_DEVREAD_LEGACY("upd765", upd765_status_r) | |
| 171 | AM_RANGE(0x95, 0x95) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w) | |
| 171 | AM_RANGE(0x94, 0x95) AM_DEVICE("upd765", upd765a_device, map) | |
| 172 | 172 | /* V24+IFSS card */ |
| 173 | 173 | AM_RANGE(0xA0, 0xA3) AM_DEVREADWRITE("z80sio_0", z80sio_device, read_alt, write_alt) |
| 174 | 174 | AM_RANGE(0xA4, 0xA7) AM_DEVREADWRITE("z80ctc_1", z80ctc_device, read, write) |
| r18419 | r18420 | |
| 465 | 465 | DEVCB_NULL |
| 466 | 466 | }; |
| 467 | 467 | |
| 468 | ||
| 469 | static const upd765_interface nanos_upd765_interface = | |
| 470 | { | |
| 471 | DEVCB_NULL, | |
| 472 | DEVCB_NULL, | |
| 473 | NULL, | |
| 474 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 475 | {FLOPPY_0,FLOPPY_1, FLOPPY_2, FLOPPY_3} | |
| 476 | }; | |
| 477 | ||
| 478 | static LEGACY_FLOPPY_OPTIONS_START(nanos) | |
| 479 | LEGACY_FLOPPY_OPTION(nanos, "img", "NANOS disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 480 | HEADS([2]) | |
| 481 | TRACKS([80]) | |
| 482 | SECTORS([5]) | |
| 483 | SECTOR_LENGTH([1024]) | |
| 484 | FIRST_SECTOR_ID([1])) | |
| 485 | LEGACY_FLOPPY_OPTIONS_END | |
| 486 | ||
| 487 | static const floppy_interface nanos_floppy_interface = | |
| 488 | { | |
| 489 | DEVCB_NULL, | |
| 490 | DEVCB_NULL, | |
| 491 | DEVCB_NULL, | |
| 492 | DEVCB_NULL, | |
| 493 | DEVCB_NULL, | |
| 494 | FLOPPY_STANDARD_5_25_DSHD, | |
| 495 | LEGACY_FLOPPY_OPTIONS_NAME(nanos), | |
| 496 | NULL, | |
| 468 | static const floppy_format_type nanos_floppy_formats[] = { | |
| 469 | FLOPPY_NANOS_FORMAT, | |
| 470 | FLOPPY_MFI_FORMAT, | |
| 497 | 471 | NULL |
| 498 | 472 | }; |
| 499 | 473 | |
| 474 | static SLOT_INTERFACE_START( nanos_floppies ) | |
| 475 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 476 | SLOT_INTERFACE_END | |
| 477 | ||
| 500 | 478 | /* F4 Character Displayer */ |
| 501 | 479 | static const gfx_layout nanos_charlayout = |
| 502 | 480 | { |
| r18419 | r18420 | |
| 542 | 520 | MCFG_Z80SIO_ADD( "z80sio_1", XTAL_4MHz, sio_intf) |
| 543 | 521 | MCFG_Z80PIO_ADD( "z80pio", XTAL_4MHz, nanos_z80pio_intf ) |
| 544 | 522 | /* UPD765 */ |
| 545 | MCFG_UPD765A_ADD("upd765", nanos_upd765_interface) | |
| 523 | MCFG_UPD765A_ADD("upd765", false, true) | |
| 524 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", nanos_floppies, "525hd", 0, nanos_floppy_formats) | |
| 546 | 525 | |
| 547 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(nanos_floppy_interface) | |
| 548 | ||
| 549 | 526 | /* internal ram */ |
| 550 | 527 | MCFG_RAM_ADD(RAM_TAG) |
| 551 | 528 | MCFG_RAM_DEFAULT_SIZE("64K") |
| r18419 | r18420 | |
|---|---|---|
| 11 | 11 | #include "machine/upd765.h" |
| 12 | 12 | #include "imagedev/flopdrv.h" |
| 13 | 13 | #include "machine/terminal.h" |
| 14 | #include "formats/mfi_dsk.h" | |
| 14 | 15 | |
| 15 | 16 | |
| 16 | 17 | class microdec_state : public driver_device |
| r18419 | r18420 | |
| 23 | 24 | DECLARE_READ8_MEMBER(terminal_status_r); |
| 24 | 25 | DECLARE_READ8_MEMBER(terminal_r); |
| 25 | 26 | DECLARE_WRITE8_MEMBER(kbd_put); |
| 26 | DECLARE_WRITE_LINE_MEMBER(microdec_irq_w); | |
| 27 | 27 | UINT8 m_term_data; |
| 28 | 28 | |
| 29 | 29 | required_device<generic_terminal_device> m_terminal; |
| 30 | 30 | virtual void machine_reset(); |
| 31 | ||
| 32 | virtual void machine_start(); | |
| 33 | void fdc_irq(bool state); | |
| 31 | 34 | }; |
| 32 | 35 | |
| 33 | 36 | |
| r18419 | r18420 | |
| 52 | 55 | static ADDRESS_MAP_START(microdec_io, AS_IO, 8, microdec_state) |
| 53 | 56 | ADDRESS_MAP_UNMAP_HIGH |
| 54 | 57 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 55 | AM_RANGE(0xfa, 0xfa) AM_DEVREAD_LEGACY("upd765", upd765_status_r) | |
| 56 | AM_RANGE(0xfb, 0xfb) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w) | |
| 58 | AM_RANGE(0xfa, 0xfb) AM_DEVICE("upd765", upd765a_device, map) | |
| 57 | 59 | AM_RANGE(0xfc, 0xfc) AM_READ(terminal_r) AM_DEVWRITE(TERMINAL_TAG, generic_terminal_device, write) |
| 58 | 60 | AM_RANGE(0xfd, 0xfd) AM_READ(terminal_status_r) |
| 59 | 61 | ADDRESS_MAP_END |
| r18419 | r18420 | |
| 62 | 64 | static INPUT_PORTS_START( microdec ) |
| 63 | 65 | INPUT_PORTS_END |
| 64 | 66 | |
| 67 | void microdec_state::machine_start() | |
| 68 | { | |
| 69 | machine().device<upd765a_device>("upd765")->setup_intrq_cb(upd765a_device::line_cb(FUNC(microdec_state::fdc_irq), this)); | |
| 70 | } | |
| 65 | 71 | |
| 66 | 72 | void microdec_state::machine_reset() |
| 67 | 73 | { |
| r18419 | r18420 | |
| 78 | 84 | DEVCB_DRIVER_MEMBER(microdec_state, kbd_put) |
| 79 | 85 | }; |
| 80 | 86 | |
| 81 | ||
| 87 | void microdec_state::fdc_irq(bool state) | |
| 82 | 88 | { |
| 83 | 89 | } |
| 84 | 90 | |
| 85 | static const struct upd765_interface microdec_upd765_interface = | |
| 86 | { | |
| 87 | DEVCB_DRIVER_LINE_MEMBER(microdec_state, microdec_irq_w), /* interrupt */ | |
| 88 | DEVCB_NULL, /* DMA request */ | |
| 89 | NULL, /* image lookup */ | |
| 90 | UPD765_RDY_PIN_CONNECTED, /* ready pin */ | |
| 91 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 92 | }; | |
| 93 | ||
| 94 | static const floppy_interface microdec_floppy_interface = | |
| 95 | { | |
| 96 | DEVCB_NULL, | |
| 97 | DEVCB_NULL, | |
| 98 | DEVCB_NULL, | |
| 99 | DEVCB_NULL, | |
| 100 | DEVCB_NULL, | |
| 101 | FLOPPY_STANDARD_5_25_DSHD, | |
| 102 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 103 | NULL, | |
| 91 | static const floppy_format_type microdec_floppy_formats[] = { | |
| 92 | FLOPPY_MFI_FORMAT, | |
| 104 | 93 | NULL |
| 105 | 94 | }; |
| 106 | 95 | |
| 96 | static SLOT_INTERFACE_START( microdec_floppies ) | |
| 97 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 98 | SLOT_INTERFACE_END | |
| 99 | ||
| 107 | 100 | static MACHINE_CONFIG_START( microdec, microdec_state ) |
| 108 | 101 | /* basic machine hardware */ |
| 109 | 102 | MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz) |
| r18419 | r18420 | |
| 114 | 107 | /* video hardware */ |
| 115 | 108 | MCFG_GENERIC_TERMINAL_ADD(TERMINAL_TAG, terminal_intf) |
| 116 | 109 | |
| 117 | MCFG_UPD765A_ADD("upd765", microdec_upd765_interface) | |
| 118 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(microdec_floppy_interface) | |
| 110 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 111 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", microdec_floppies, "525hd", 0, microdec_floppy_formats) | |
| 112 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", microdec_floppies, "525hd", 0, microdec_floppy_formats) | |
| 119 | 113 | MACHINE_CONFIG_END |
| 120 | 114 | |
| 121 | 115 | /* ROM definition */ |
| r18419 | r18420 | |
|---|---|---|
| 26 | 26 | #include "machine/ram.h" |
| 27 | 27 | #include "machine/ctronics.h" |
| 28 | 28 | #include "machine/upd765.h" |
| 29 | #include "formats/mfi_dsk.h" | |
| 29 | 30 | #include "includes/prof180x.h" |
| 30 | 31 | |
| 31 | 32 | UINT32 prof180x_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| r18419 | r18420 | |
| 170 | 171 | static ADDRESS_MAP_START( prof180x_io , AS_IO, 8, prof180x_state ) |
| 171 | 172 | AM_RANGE(0x08, 0x08) AM_MIRROR(0xff00) AM_WRITE(flr_w) |
| 172 | 173 | AM_RANGE(0x09, 0x09) AM_MASK(0xff00) AM_READ(status_r) |
| 173 | AM_RANGE(0x0a, 0x0a) AM_MIRROR(0xff00) AM_DEVREADWRITE_LEGACY(FDC9268_TAG, upd765_dack_r, upd765_dack_w) | |
| 174 | ||
| 175 | // Seriously? | |
| 176 | // AM_RANGE(0x0a, 0x0a) AM_MIRROR(0xff00) AM_DEVREADWRITE_LEGACY(FDC9268_TAG, upd765_dack_r, upd765_dack_w) | |
| 174 | 177 | AM_RANGE(0x0b, 0x0b) AM_MIRROR(0xff00) AM_DEVWRITE(CENTRONICS_TAG, centronics_device, write) |
| 175 | AM_RANGE(0x0c, 0x0c) AM_MIRROR(0xff00) AM_DEVREAD_LEGACY(FDC9268_TAG, upd765_status_r) | |
| 176 | AM_RANGE(0x0d, 0x0d) AM_MIRROR(0xff00) AM_DEVREADWRITE_LEGACY(FDC9268_TAG, upd765_data_r, upd765_data_w) | |
| 178 | AM_RANGE(0x0c, 0x0d) AM_MIRROR(0xff00) AM_DEVICE(FDC9268_TAG, upd765a_device, map) | |
| 177 | 179 | ADDRESS_MAP_END |
| 178 | 180 | |
| 179 | 181 | /* Input ports */ |
| r18419 | r18420 | |
| 183 | 185 | |
| 184 | 186 | /* Video */ |
| 185 | 187 | |
| 186 | static const struct upd765_interface fdc_intf = | |
| 187 | { | |
| 188 | DEVCB_NULL, | |
| 189 | DEVCB_NULL, // DEVCB_CPU_INPUT_LINE(HD64180_TAG, INPUT_LINE_DREQ1) | |
| 190 | NULL, | |
| 191 | UPD765_RDY_PIN_CONNECTED, | |
| 192 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 193 | }; | |
| 194 | ||
| 195 | static const floppy_interface prof180x_floppy_interface = | |
| 196 | { | |
| 197 | DEVCB_NULL, | |
| 198 | DEVCB_NULL, | |
| 199 | DEVCB_NULL, | |
| 200 | DEVCB_NULL, | |
| 201 | DEVCB_NULL, | |
| 202 | FLOPPY_STANDARD_5_25_DSHD, | |
| 203 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 204 | NULL, | |
| 188 | static const floppy_format_type prof180x_floppy_formats[] = { | |
| 189 | FLOPPY_MFI_FORMAT, | |
| 205 | 190 | NULL |
| 206 | 191 | }; |
| 207 | 192 | |
| 193 | static SLOT_INTERFACE_START( prof180x_floppies ) | |
| 194 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 195 | SLOT_INTERFACE_END | |
| 196 | ||
| 208 | 197 | /* |
| 209 | 198 | static RTC8583_INTERFCE( rtc_intf ) |
| 210 | 199 | { |
| r18419 | r18420 | |
| 247 | 236 | MCFG_PALETTE_INIT(black_and_white) |
| 248 | 237 | |
| 249 | 238 | /* devices */ |
| 250 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(prof180x_floppy_interface) | |
| 251 | MCFG_UPD765A_ADD(FDC9268_TAG, fdc_intf) | |
| 239 | MCFG_UPD765A_ADD(FDC9268_TAG, false, true) | |
| 240 | MCFG_FLOPPY_DRIVE_ADD(FDC9268_TAG ":0", prof180x_floppies, "525hd", 0, prof180x_floppy_formats) | |
| 241 | MCFG_FLOPPY_DRIVE_ADD(FDC9268_TAG ":1", prof180x_floppies, "525hd", 0, prof180x_floppy_formats) | |
| 242 | MCFG_FLOPPY_DRIVE_ADD(FDC9268_TAG ":2", prof180x_floppies, "525hd", 0, prof180x_floppy_formats) | |
| 243 | MCFG_FLOPPY_DRIVE_ADD(FDC9268_TAG ":3", prof180x_floppies, "525hd", 0, prof180x_floppy_formats) | |
| 244 | ||
| 252 | 245 | //MCFG_RTC8583_ADD(MK3835_TAG, rtc_intf) |
| 253 | 246 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics) |
| 254 | 247 |
| r18419 | r18420 | |
|---|---|---|
| 96 | 96 | causes Spectrum to reset. Fixing this problem |
| 97 | 97 | made much more software runing (i.e. Paperboy). |
| 98 | 98 | Corrected frames per second value for 48k and 128k |
| 99 | Sinc | |
| 99 | Sinclair machines. | |
| 100 | 100 | There are 50.08 frames per second for Spectrum |
| 101 | 101 | 48k what gives 69888 cycles for each frame and |
| 102 | 102 | 50.021 for Spectrum 128/+2/+2A/+3 what gives |
| r18419 | r18420 | |
| 152 | 152 | #include "sound/ay8910.h" |
| 153 | 153 | #include "sound/speaker.h" |
| 154 | 154 | #include "formats/tzx_cas.h" |
| 155 | #include "formats/mfi_dsk.h" | |
| 155 | 156 | |
| 156 | 157 | /* +3 hardware */ |
| 157 | 158 | #include "machine/upd765.h" |
| r18419 | r18420 | |
| 163 | 164 | /* This driver uses some of the spectrum_128 functions. The +3 is similar to a spectrum 128 |
| 164 | 165 | but with a disc drive */ |
| 165 | 166 | |
| 166 | static const upd765_interface spectrum_plus3_upd765_interface = | |
| 167 | { | |
| 168 | DEVCB_NULL, | |
| 169 | DEVCB_NULL, | |
| 170 | NULL, | |
| 171 | UPD765_RDY_PIN_CONNECTED, | |
| 172 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 173 | }; | |
| 174 | 167 | |
| 175 | ||
| 176 | 168 | static const int spectrum_plus3_memory_selections[]= |
| 177 | 169 | { |
| 178 | 170 | 0,1,2,3, |
| r18419 | r18420 | |
| 185 | 177 | { |
| 186 | 178 | spectrum_state *state = space.machine().driver_data<spectrum_state>(); |
| 187 | 179 | if (state->m_floppy==1) |
| 188 | | |
| 180 | space.machine().device<upd765a_device>("upd765")->fifo_w(space, 0, data, 0xff); | |
| 189 | 181 | } |
| 190 | 182 | |
| 191 | 183 | static READ8_HANDLER(spectrum_plus3_port_3ffd_r) |
| r18419 | r18420 | |
| 194 | 186 | if (state->m_floppy==0) |
| 195 | 187 | return 0xff; |
| 196 | 188 | else |
| 197 | return | |
| 189 | return space.machine().device<upd765a_device>("upd765")->fifo_r(space, 0, 0xff); | |
| 198 | 190 | } |
| 199 | 191 | |
| 200 | 192 | |
| r18419 | r18420 | |
| 202 | 194 | { |
| 203 | 195 | spectrum_state *state = space.machine().driver_data<spectrum_state>(); |
| 204 | 196 | if (state->m_floppy==0) |
| 205 | | |
| 197 | return 0xff; | |
| 206 | 198 | else |
| 207 | | |
| 199 | return space.machine().device<upd765a_device>("upd765")->msr_r(space, 0, 0xff); | |
| 208 | 200 | } |
| 209 | 201 | |
| 210 | 202 | |
| r18419 | r18420 | |
| 375 | 367 | m_floppy = 0; |
| 376 | 368 | } |
| 377 | 369 | |
| 378 | static const floppy_interface specpls3_floppy_interface = | |
| 379 | { | |
| 380 | DEVCB_NULL, | |
| 381 | DEVCB_NULL, | |
| 382 | DEVCB_NULL, | |
| 383 | DEVCB_NULL, | |
| 384 | DEVCB_NULL, | |
| 385 | FLOPPY_STANDARD_3_SSDD, | |
| 386 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 387 | NULL, | |
| 370 | static const floppy_format_type specpls3_floppy_formats[] = { | |
| 371 | FLOPPY_MFI_FORMAT, | |
| 388 | 372 | NULL |
| 389 | 373 | }; |
| 390 | 374 | |
| 375 | static SLOT_INTERFACE_START( specpls3_floppies ) | |
| 376 | SLOT_INTERFACE( "3ssdd", FLOPPY_3_SSDD ) | |
| 377 | SLOT_INTERFACE_END | |
| 378 | ||
| 391 | 379 | /* F4 Character Displayer */ |
| 392 | 380 | static const gfx_layout spectrum_charlayout = |
| 393 | 381 | { |
| r18419 | r18420 | |
| 415 | 403 | |
| 416 | 404 | MCFG_MACHINE_RESET_OVERRIDE(spectrum_state, spectrum_plus3 ) |
| 417 | 405 | |
| 418 | MCFG_UPD765A_ADD("upd765", spectrum_plus3_upd765_interface) | |
| 419 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(specpls3_floppy_interface) | |
| 406 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 407 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", specpls3_floppies, "3ssdd", 0, specpls3_floppy_formats) | |
| 408 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", specpls3_floppies, "3ssdd", 0, specpls3_floppy_formats) | |
| 420 | 409 | MACHINE_CONFIG_END |
| 421 | 410 | |
| 422 | 411 | /*************************************************************************** |
| r18419 | r18420 | |
|---|---|---|
| 10 | 10 | #include "cpu/i86/i86.h" |
| 11 | 11 | #include "machine/upd765.h" |
| 12 | 12 | #include "video/upd7220.h" |
| 13 | #include "formats/mfi_dsk.h" | |
| 13 | 14 | |
| 14 | 15 | class mz6500_state : public driver_device |
| 15 | 16 | { |
| r18419 | r18420 | |
| 22 | 23 | m_video_ram(*this, "video_ram"){ } |
| 23 | 24 | |
| 24 | 25 | required_device<upd7220_device> m_hgdc; |
| 25 | required_device<device_t> m_fdc; | |
| 26 | DECLARE_READ8_MEMBER(fdc_r); | |
| 27 | DECLARE_WRITE8_MEMBER(fdc_w); | |
| 26 | required_device<upd765a_device> m_fdc; | |
| 28 | 27 | DECLARE_READ8_MEMBER(mz6500_vram_r); |
| 29 | 28 | DECLARE_WRITE8_MEMBER(mz6500_vram_w); |
| 30 | DECLARE_WRITE_LINE_MEMBER(fdc_irq); | |
| 31 | DECLARE_WRITE_LINE_MEMBER(fdc_drq); | |
| 29 | void fdc_irq(bool state); | |
| 30 | void fdc_drq(bool state); | |
| 32 | 31 | required_shared_ptr<UINT8> m_video_ram; |
| 33 | 32 | virtual void machine_reset(); |
| 34 | 33 | virtual void video_start(); |
| r18419 | r18420 | |
| 58 | 57 | } |
| 59 | 58 | |
| 60 | 59 | |
| 61 | READ8_MEMBER( mz6500_state::fdc_r ) | |
| 62 | { | |
| 63 | return (offset) ? upd765_data_r(m_fdc, space, 0) : upd765_status_r(m_fdc, space, 0); | |
| 64 | } | |
| 65 | ||
| 66 | WRITE8_MEMBER( mz6500_state::fdc_w ) | |
| 67 | { | |
| 68 | if(offset) | |
| 69 | upd765_data_w(m_fdc, space, 0, data); | |
| 70 | } | |
| 71 | ||
| 72 | 60 | READ8_MEMBER( mz6500_state::mz6500_vram_r ) |
| 73 | 61 | { |
| 74 | 62 | return m_video_ram[offset]; |
| r18419 | r18420 | |
| 91 | 79 | ADDRESS_MAP_UNMAP_HIGH |
| 92 | 80 | // AM_RANGE(0x0000, 0x000f) i8237 dma |
| 93 | 81 | // AM_RANGE(0x0010, 0x001f) i8255 |
| 94 | AM_RANGE(0x0020, 0x0021) AM_MIRROR(0xe) AM_ | |
| 82 | AM_RANGE(0x0020, 0x0021) AM_MIRROR(0xe) AM_DEVICE8("upd765", upd765a_device, map, 0xffff) | |
| 95 | 83 | // AM_RANGE(0x0030, 0x003f) i8259 master |
| 96 | 84 | // AM_RANGE(0x0040, 0x004f) i8259 slave |
| 97 | 85 | // AM_RANGE(0x0050, 0x0050) segment byte for DMA |
| r18419 | r18420 | |
| 121 | 109 | { |
| 122 | 110 | } |
| 123 | 111 | |
| 124 | ||
| 112 | void mz6500_state::fdc_irq(bool state) | |
| 125 | 113 | { |
| 126 | 114 | //printf("%02x IRQ\n",state); |
| 127 | 115 | } |
| 128 | 116 | |
| 129 | ||
| 117 | void mz6500_state::fdc_drq(bool state) | |
| 130 | 118 | { |
| 131 | 119 | //printf("%02x DRQ\n",state); |
| 132 | 120 | } |
| 133 | 121 | |
| 134 | static const struct upd765_interface upd765_intf = | |
| 135 | { | |
| 136 | DEVCB_DRIVER_LINE_MEMBER(mz6500_state, fdc_irq), | |
| 137 | DEVCB_DRIVER_LINE_MEMBER(mz6500_state, fdc_drq), | |
| 138 | NULL, | |
| 139 | UPD765_RDY_PIN_CONNECTED, | |
| 140 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 141 | }; | |
| 142 | ||
| 143 | static const floppy_interface mz6500_floppy_interface = | |
| 144 | { | |
| 145 | DEVCB_NULL, | |
| 146 | DEVCB_NULL, | |
| 147 | DEVCB_NULL, | |
| 148 | DEVCB_NULL, | |
| 149 | DEVCB_NULL, | |
| 150 | FLOPPY_STANDARD_5_25_DSHD, | |
| 151 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 152 | NULL, | |
| 122 | static const floppy_format_type mz6500_floppy_formats[] = { | |
| 123 | FLOPPY_MFI_FORMAT, | |
| 153 | 124 | NULL |
| 154 | 125 | }; |
| 155 | 126 | |
| 127 | static SLOT_INTERFACE_START( mz6500_floppies ) | |
| 128 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 129 | SLOT_INTERFACE_END | |
| 156 | 130 | |
| 157 | 131 | static UPD7220_INTERFACE( hgdc_intf ) |
| 158 | 132 | { |
| r18419 | r18420 | |
| 187 | 161 | |
| 188 | 162 | /* Devices */ |
| 189 | 163 | MCFG_UPD7220_ADD("upd7220", 4000000, hgdc_intf, upd7220_map) |
| 190 | MCFG_UPD765A_ADD("upd765", upd765_intf) | |
| 191 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(mz6500_floppy_interface) | |
| 164 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 165 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", mz6500_floppies, "525hd", 0, mz6500_floppy_formats) | |
| 166 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", mz6500_floppies, "525hd", 0, mz6500_floppy_formats) | |
| 192 | 167 | MACHINE_CONFIG_END |
| 193 | 168 | |
| 194 | 169 | /* ROM definition */ |
| r18419 | r18420 | |
|---|---|---|
| 21 | 21 | #include "video/upd7220.h" |
| 22 | 22 | #include "machine/ram.h" |
| 23 | 23 | #include "machine/upd765.h" |
| 24 | #include "formats/mfi_dsk.h" | |
| 25 | #include "formats/a5105_dsk.h" | |
| 24 | 26 | #include "machine/z80ctc.h" |
| 25 | 27 | #include "machine/z80pio.h" |
| 26 | 28 | #include "imagedev/cassette.h" |
| 27 | 29 | #include "imagedev/flopdrv.h" |
| 28 | 30 | #include "sound/wave.h" |
| 29 | 31 | #include "sound/beep.h" |
| 30 | #include "formats/basicdsk.h" | |
| 31 | 32 | |
| 32 | 33 | |
| 33 | 34 | |
| r18419 | r18420 | |
| 310 | 311 | |
| 311 | 312 | WRITE8_MEMBER( a5105_state::a5105_upd765_w ) |
| 312 | 313 | { |
| 313 | | |
| 314 | machine().device<upd765a_device>("upd765")->tc_w(BIT(data, 4)); | |
| 314 | 315 | } |
| 315 | 316 | |
| 316 | 317 | static ADDRESS_MAP_START(a5105_io, AS_IO, 8, a5105_state) |
| 317 | 318 | ADDRESS_MAP_UNMAP_HIGH |
| 318 | 319 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 319 | AM_RANGE(0x40, 0x40) AM_DEVREAD_LEGACY("upd765", upd765_status_r) | |
| 320 | AM_RANGE(0x41, 0x41) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w) | |
| 320 | AM_RANGE(0x40, 0x41) AM_DEVICE("upd765a", upd765a_device, map) | |
| 321 | 321 | AM_RANGE(0x48, 0x4f) AM_WRITE(a5105_upd765_w) |
| 322 | 322 | |
| 323 | 323 | AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("z80ctc", z80ctc_device, read, write) |
| r18419 | r18420 | |
| 520 | 520 | AM_RANGE(0x00000, 0x1ffff) AM_RAM AM_SHARE("video_ram") |
| 521 | 521 | ADDRESS_MAP_END |
| 522 | 522 | |
| 523 | static LEGACY_FLOPPY_OPTIONS_START(a5105) | |
| 524 | LEGACY_FLOPPY_OPTION(a5105, "img", "A5105 disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 525 | HEADS([2]) | |
| 526 | TRACKS([80]) | |
| 527 | SECTORS([5]) | |
| 528 | SECTOR_LENGTH([1024]) | |
| 529 | FIRST_SECTOR_ID([1])) | |
| 530 | LEGACY_FLOPPY_OPTIONS_END | |
| 531 | ||
| 532 | static const floppy_interface a5105_floppy_interface = | |
| 533 | { | |
| 534 | DEVCB_NULL, | |
| 535 | DEVCB_NULL, | |
| 536 | DEVCB_NULL, | |
| 537 | DEVCB_NULL, | |
| 538 | DEVCB_NULL, | |
| 539 | FLOPPY_STANDARD_5_25_DSDD, | |
| 540 | LEGACY_FLOPPY_OPTIONS_NAME(a5105), | |
| 541 | "floppy_5_25", | |
| 523 | static const floppy_format_type a5105_floppy_formats[] = { | |
| 524 | FLOPPY_MFI_FORMAT, | |
| 525 | FLOPPY_A5105_FORMAT, | |
| 542 | 526 | NULL |
| 543 | 527 | }; |
| 544 | 528 | |
| 529 | static SLOT_INTERFACE_START( a5105_floppies ) | |
| 530 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 531 | SLOT_INTERFACE_END | |
| 545 | 532 | |
| 546 | static const upd765_interface a5105_interface = | |
| 547 | { | |
| 548 | DEVCB_NULL, | |
| 549 | DEVCB_NULL, | |
| 550 | NULL, | |
| 551 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 552 | {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} | |
| 553 | }; | |
| 554 | ||
| 555 | 533 | static Z80CTC_INTERFACE( a5105_ctc_intf ) |
| 556 | 534 | { |
| 557 | 535 | DEVCB_CPU_INPUT_LINE("maincpu", 0), /* interrupt callback */ |
| r18419 | r18420 | |
| 609 | 587 | |
| 610 | 588 | MCFG_CASSETTE_ADD( CASSETTE_TAG, default_cassette_interface ) |
| 611 | 589 | |
| 612 | MCFG_UPD765A_ADD("upd765", a5105_interface) | |
| 613 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(a5105_floppy_interface) | |
| 590 | MCFG_UPD765A_ADD("upd765a", false, true) | |
| 591 | MCFG_FLOPPY_DRIVE_ADD("upd765a:0", a5105_floppies, "525dd", 0, a5105_floppy_formats) | |
| 592 | MCFG_FLOPPY_DRIVE_ADD("upd765a:1", a5105_floppies, "525dd", 0, a5105_floppy_formats) | |
| 593 | MCFG_FLOPPY_DRIVE_ADD("upd765a:2", a5105_floppies, "525dd", 0, a5105_floppy_formats) | |
| 594 | MCFG_FLOPPY_DRIVE_ADD("upd765a:3", a5105_floppies, "525dd", 0, a5105_floppy_formats) | |
| 614 | 595 | |
| 615 | 596 | /* internal ram */ |
| 616 | 597 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | 25 | #include "includes/prof80.h" |
| 26 | #include "formats/mfi_dsk.h" | |
| 26 | 27 | |
| 27 | 28 | |
| 28 | ||
| 29 | 29 | //************************************************************************** |
| 30 | 30 | // MACROS / CONSTANTS |
| 31 | 31 | //************************************************************************** |
| r18419 | r18420 | |
| 101 | 101 | |
| 102 | 102 | void prof80_state::floppy_motor_off() |
| 103 | 103 | { |
| 104 | floppy_mon_w(m_floppy0, 1); | |
| 105 | floppy_mon_w(m_floppy1, 1); | |
| 106 | floppy_drive_set_ready_state(m_floppy0, 0, 1); | |
| 107 | floppy_drive_set_ready_state(m_floppy1, 0, 1); | |
| 104 | if(m_floppy0) | |
| 105 | m_floppy0->mon_w(true); | |
| 106 | if(m_floppy1) | |
| 107 | m_floppy1->mon_w(true); | |
| 108 | 108 | |
| 109 | 109 | m_motor = 0; |
| 110 | 110 | } |
| r18419 | r18420 | |
| 135 | 135 | break; |
| 136 | 136 | |
| 137 | 137 | case 3: // READY |
| 138 | | |
| 138 | m_fdc->ready_w(fa); | |
| 139 | 139 | break; |
| 140 | 140 | |
| 141 | 141 | case 4: // TCK |
| r18419 | r18420 | |
| 157 | 157 | else |
| 158 | 158 | { |
| 159 | 159 | // turn on floppy motor |
| 160 | floppy_mon_w(m_floppy0, 0); | |
| 161 | floppy_mon_w(m_floppy1, 0); | |
| 162 | floppy_drive_set_ready_state(m_floppy0, 1, 1); | |
| 163 | floppy_drive_set_ready_state(m_floppy1, 1, 1); | |
| 160 | if(m_floppy0) | |
| 161 | m_floppy0->mon_w(false); | |
| 162 | if(m_floppy1) | |
| 163 | m_floppy1->mon_w(false); | |
| 164 | 164 | |
| 165 | 165 | m_motor = 1; |
| 166 | 166 | |
| r18419 | r18420 | |
| 176 | 176 | switch (sb) |
| 177 | 177 | { |
| 178 | 178 | case 0: // RESF |
| 179 | if (fb) | |
| 179 | if (fb) m_fdc->reset(); | |
| 180 | 180 | break; |
| 181 | 181 | |
| 182 | 182 | case 1: // MINI |
| r18419 | r18420 | |
| 272 | 272 | data |= 0x10; |
| 273 | 273 | |
| 274 | 274 | // floppy index |
| 275 | data |= (m_fdc_index << 5); | |
| 275 | if(m_floppy0) | |
| 276 | data |= m_floppy0->idx_r() << 5; | |
| 276 | 277 | |
| 278 | if(m_floppy1) | |
| 279 | data |= m_floppy1->idx_r() << 5; | |
| 280 | ||
| 277 | 281 | return data; |
| 278 | 282 | } |
| 279 | 283 | |
| r18419 | r18420 | |
| 404 | 408 | AM_RANGE(0xd8, 0xd8) AM_MIRROR(0xff00) AM_WRITE(flr_w) |
| 405 | 409 | AM_RANGE(0xda, 0xda) AM_MIRROR(0xff00) AM_READ(status_r) |
| 406 | 410 | AM_RANGE(0xdb, 0xdb) AM_MIRROR(0xff00) AM_READ(status2_r) |
| 407 | AM_RANGE(0xdc, 0xdc) AM_MIRROR(0xff00) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) | |
| 408 | AM_RANGE(0xdd, 0xdd) AM_MIRROR(0xff00) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) | |
| 411 | AM_RANGE(0xdc, 0xdd) AM_MIRROR(0xff00) AM_DEVICE(UPD765_TAG, upd765a_device, map) | |
| 409 | 412 | AM_RANGE(0xde, 0xde) AM_MIRROR(0xff01) AM_MASK(0xff00) AM_WRITE(par_w) |
| 410 | 413 | ADDRESS_MAP_END |
| 411 | 414 | |
| r18419 | r18420 | |
| 504 | 507 | // upd765_interface fdc_intf |
| 505 | 508 | //------------------------------------------------- |
| 506 | 509 | |
| 507 | WRITE_LINE_MEMBER( prof80_state::floppy_index_w ) | |
| 508 | { | |
| 509 | m_fdc_index = state; | |
| 510 | } | |
| 511 | ||
| 512 | static const floppy_interface floppy_intf = | |
| 513 | { | |
| 514 | DEVCB_DRIVER_LINE_MEMBER(prof80_state, floppy_index_w), | |
| 515 | DEVCB_NULL, | |
| 516 | DEVCB_NULL, | |
| 517 | DEVCB_NULL, | |
| 518 | DEVCB_NULL, | |
| 519 | FLOPPY_STANDARD_5_25_DSHD, | |
| 520 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 521 | NULL, | |
| 510 | static const floppy_format_type prof80_floppy_formats[] = { | |
| 511 | FLOPPY_MFI_FORMAT, | |
| 522 | 512 | NULL |
| 523 | 513 | }; |
| 524 | 514 | |
| 525 | static const struct upd765_interface fdc_intf = | |
| 526 | { | |
| 527 | DEVCB_NULL, | |
| 528 | DEVCB_NULL, | |
| 529 | NULL, | |
| 530 | UPD765_RDY_PIN_NOT_CONNECTED, | |
| 531 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 532 | }; | |
| 515 | static SLOT_INTERFACE_START( prof80_floppies ) | |
| 516 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 517 | SLOT_INTERFACE_END | |
| 533 | 518 | |
| 534 | 519 | |
| 535 | 520 | //------------------------------------------------- |
| r18419 | r18420 | |
| 637 | 622 | |
| 638 | 623 | // devices |
| 639 | 624 | MCFG_UPD1990A_ADD(UPD1990A_TAG, XTAL_32_768kHz, rtc_intf) |
| 640 | MCFG_UPD765A_ADD(UPD765_TAG, fdc_intf) | |
| 641 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf) | |
| 625 | MCFG_UPD765A_ADD(UPD765_TAG, false, true) | |
| 626 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", prof80_floppies, "525hd", 0, prof80_floppy_formats) | |
| 627 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", prof80_floppies, "525hd", 0, prof80_floppy_formats) | |
| 642 | 628 | |
| 643 | 629 | // ECB bus |
| 644 | 630 | MCFG_ECBBUS_ADD(Z80_TAG, ecb_intf) |
| r18419 | r18420 | |
|---|---|---|
| 29 | 29 | |
| 30 | 30 | #include "includes/apollo.h" |
| 31 | 31 | #include "machine/apollo_kbd.h" |
| 32 | #include "machine/pc_fdc.h" | |
| 32 | 33 | |
| 33 | 34 | #include "debugger.h" |
| 34 | 35 | |
| r18419 | r18420 | |
| 751 | 752 | AM_RANGE(0x04D000, 0x04D007) AM_DEVREADWRITE16_LEGACY(APOLLO_WDC_TAG, omti8621_r, omti8621_w, 0xffffffff) |
| 752 | 753 | AM_RANGE(0x050000, 0x050007) AM_DEVREADWRITE8_LEGACY(APOLLO_CTAPE_TAG, sc499_r, sc499_w, 0xffffffff) |
| 753 | 754 | AM_RANGE(0x058000, 0x058007) AM_DEVREADWRITE8_LEGACY(APOLLO_ETH_TAG, threecom3c505_r, threecom3c505_w, 0xffffffff) |
| 754 | AM_RANGE(0x05f800, 0x05f807) AM_ | |
| 755 | AM_RANGE(0x05f800, 0x05f807) AM_DEVICE8(APOLLO_WDC_TAG, pc_fdc_at_device, map, 0xffffffff) | |
| 755 | 756 | |
| 756 | 757 | AM_RANGE(0x05d800, 0x05dc07) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mcr_r, apollo_mcr_w, 0xffffffff) |
| 757 | 758 | AM_RANGE(0xfa0000, 0xfdffff) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mgm_r, apollo_mgm_w, 0xffffffff) |
| r18419 | r18420 | |
| 799 | 800 | AM_RANGE(0x04D000, 0x04D007) AM_DEVREADWRITE16_LEGACY(APOLLO_WDC_TAG, omti8621_r, omti8621_w, 0xffffffff) |
| 800 | 801 | AM_RANGE(0x050000, 0x050007) AM_DEVREADWRITE8_LEGACY(APOLLO_CTAPE_TAG, sc499_r, sc499_w, 0xffffffff) |
| 801 | 802 | AM_RANGE(0x058000, 0x058007) AM_DEVREADWRITE8_LEGACY(APOLLO_ETH_TAG, threecom3c505_r, threecom3c505_w, 0xffffffff) |
| 802 | AM_RANGE(0x05f800, 0x05f807) AM_ | |
| 803 | AM_RANGE(0x05f800, 0x05f807) AM_DEVICE8(APOLLO_WDC_TAG, pc_fdc_at_device, map, 0xffffffff) | |
| 803 | 804 | |
| 804 | 805 | // AM_RANGE(0x05d800, 0x05dc07) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mcr_r, apollo_mcr_w, 0xffffffff) |
| 805 | 806 | // AM_RANGE(0xfa0000, 0xfdffff) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mgm_r, apollo_mgm_w, 0xffffffff) |
| r18419 | r18420 | |
| 838 | 839 | AM_RANGE(0x04D000, 0x04D007) AM_DEVREADWRITE16_LEGACY(APOLLO_WDC_TAG, omti8621_r, omti8621_w, 0xffffffff) |
| 839 | 840 | AM_RANGE(0x050000, 0x050007) AM_DEVREADWRITE8_LEGACY(APOLLO_CTAPE_TAG, sc499_r, sc499_w, 0xffffffff) |
| 840 | 841 | AM_RANGE(0x058000, 0x058007) AM_DEVREADWRITE8_LEGACY(APOLLO_ETH_TAG, threecom3c505_r, threecom3c505_w, 0xffffffff) |
| 841 | AM_RANGE(0x05f800, 0x05f807) AM_ | |
| 842 | AM_RANGE(0x05f800, 0x05f807) AM_DEVICE8(APOLLO_WDC_TAG, pc_fdc_at_device, map, 0xffffffff) | |
| 842 | 843 | |
| 843 | 844 | AM_RANGE(0x05d800, 0x05dc07) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mcr_r, apollo_mcr_w, 0xffffffff) |
| 844 | 845 | AM_RANGE(0xfa0000, 0xfdffff) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mgm_r, apollo_mgm_w, 0xffffffff) |
| r18419 | r18420 | |
| 876 | 877 | AM_RANGE(0x04D000, 0x04D007) AM_DEVREADWRITE16_LEGACY(APOLLO_WDC_TAG, omti8621_r, omti8621_w, 0xffffffff) |
| 877 | 878 | AM_RANGE(0x050000, 0x050007) AM_DEVREADWRITE8_LEGACY(APOLLO_CTAPE_TAG, sc499_r, sc499_w, 0xffffffff) |
| 878 | 879 | AM_RANGE(0x058000, 0x058007) AM_DEVREADWRITE8_LEGACY(APOLLO_ETH_TAG, threecom3c505_r, threecom3c505_w, 0xffffffff) |
| 879 | AM_RANGE(0x05f800, 0x05f807) AM_ | |
| 880 | AM_RANGE(0x05f800, 0x05f807) AM_DEVICE8(APOLLO_WDC_TAG, pc_fdc_at_device, map, 0xffffffff) | |
| 880 | 881 | |
| 881 | 882 | // AM_RANGE(0x05d800, 0x05dc07) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mcr_r, apollo_mcr_w, 0xffffffff) |
| 882 | 883 | // AM_RANGE(0xfa0000, 0xfdffff) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mgm_r, apollo_mgm_w, 0xffffffff) |
| r18419 | r18420 | |
| 922 | 923 | AM_RANGE(0x04D000, 0x04D007) AM_DEVREADWRITE16_LEGACY(APOLLO_WDC_TAG, omti8621_r, omti8621_w, 0xffffffff) |
| 923 | 924 | AM_RANGE(0x050000, 0x050007) AM_DEVREADWRITE8_LEGACY(APOLLO_CTAPE_TAG, sc499_r, sc499_w, 0xffffffff) |
| 924 | 925 | AM_RANGE(0x058000, 0x058007) AM_DEVREADWRITE8_LEGACY(APOLLO_ETH_TAG, threecom3c505_r, threecom3c505_w, 0xffffffff) |
| 925 | AM_RANGE(0x05f800, 0x05f807) AM_ | |
| 926 | AM_RANGE(0x05f800, 0x05f807) AM_DEVICE8(APOLLO_WDC_TAG, pc_fdc_at_device, map, 0xffffffff) | |
| 926 | 927 | |
| 927 | 928 | AM_RANGE(0x05d800, 0x05dc07) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mcr_r, apollo_mcr_w, 0xffffffff) |
| 928 | 929 | AM_RANGE(0xfa0000, 0xfdffff) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mgm_r, apollo_mgm_w, 0xffffffff) |
| r18419 | r18420 | |
| 974 | 975 | AM_RANGE(0x04D000, 0x04D007) AM_DEVREADWRITE16_LEGACY(APOLLO_WDC_TAG, omti8621_r, omti8621_w, 0xffffffff) |
| 975 | 976 | AM_RANGE(0x050000, 0x050007) AM_DEVREADWRITE8_LEGACY(APOLLO_CTAPE_TAG, sc499_r, sc499_w, 0xffffffff) |
| 976 | 977 | AM_RANGE(0x058000, 0x058007) AM_DEVREADWRITE8_LEGACY(APOLLO_ETH_TAG, threecom3c505_r, threecom3c505_w, 0xffffffff) |
| 977 | AM_RANGE(0x05f800, 0x05f807) AM_ | |
| 978 | AM_RANGE(0x05f800, 0x05f807) AM_DEVICE8(APOLLO_WDC_TAG, pc_fdc_at_device, map, 0xffffffff) | |
| 978 | 979 | |
| 979 | 980 | // AM_RANGE(0x05d800, 0x05dc07) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mcr_r, apollo_mcr_w, 0xffffffff) |
| 980 | 981 | // AM_RANGE(0xfa0000, 0xfdffff) AM_DEVREADWRITE16_LEGACY(APOLLO_SCREEN_TAG, apollo_mgm_r, apollo_mgm_w, 0xffffffff) |
| r18419 | r18420 | |
|---|---|---|
| 95 | 95 | /* Components */ |
| 96 | 96 | #include "machine/pc_lpt.h" /* PC-Parallel Port */ |
| 97 | 97 | #include "machine/pckeybrd.h" /* PC-AT keyboard */ |
| 98 | #include "machine/p | |
| 98 | #include "machine/upd765.h" /* FDC superio */ | |
| 99 | 99 | #include "machine/ins8250.h" /* pc com port */ |
| 100 | 100 | #include "sound/beep.h" /* pcw/pcw16 beeper */ |
| 101 | 101 | #include "machine/intelfsh.h" |
| 102 | 102 | |
| 103 | 103 | /* Devices */ |
| 104 | #include "formats/pc_dsk.h" /* pc disk images */ | |
| 104 | #include "formats/pc_dsk.h" | |
| 105 | #include "formats/mfi_dsk.h" | |
| 105 | 106 | #include "imagedev/flopdrv.h" |
| 106 | 107 | #include "machine/ram.h" |
| 107 | 108 | |
| r18419 | r18420 | |
| 742 | 743 | } |
| 743 | 744 | |
| 744 | 745 | |
| 745 | ||
| 746 | void pcw16_state::trigger_fdc_int() | |
| 746 | 747 | { |
| 747 | pcw16_state *drvstate = machine.driver_data<pcw16_state>(); | |
| 748 | 748 | int state; |
| 749 | 749 | |
| 750 | state = | |
| 750 | state = m_system_status & (1<<6); | |
| 751 | 751 | |
| 752 | switch ( | |
| 752 | switch (m_fdc_int_code) | |
| 753 | 753 | { |
| 754 | 754 | /* nmi */ |
| 755 | 755 | case 0: |
| r18419 | r18420 | |
| 760 | 760 | is cleared this will not cause another nmi */ |
| 761 | 761 | /* I'll emulate it like this to be sure */ |
| 762 | 762 | |
| 763 | if (state!= | |
| 763 | if (state!=m_previous_fdc_int_state) | |
| 764 | 764 | { |
| 765 | 765 | if (state) |
| 766 | 766 | { |
| 767 | 767 | /* I'll pulse it because if I used hold-line I'm not sure |
| 768 | 768 | it would clear - to be checked */ |
| 769 | machine.device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
| 769 | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); | |
| 770 | 770 | } |
| 771 | 771 | } |
| 772 | 772 | } |
| r18419 | r18420 | |
| 775 | 775 | /* attach fdc to int */ |
| 776 | 776 | case 1: |
| 777 | 777 | { |
| 778 | | |
| 778 | pcw16_refresh_ints(); | |
| 779 | 779 | } |
| 780 | 780 | break; |
| 781 | 781 | |
| r18419 | r18420 | |
| 784 | 784 | break; |
| 785 | 785 | } |
| 786 | 786 | |
| 787 | | |
| 787 | m_previous_fdc_int_state = state; | |
| 788 | 788 | } |
| 789 | 789 | |
| 790 | 790 | READ8_MEMBER(pcw16_state::pcw16_system_status_r) |
| r18419 | r18420 | |
| 854 | 854 | /* set terminal count */ |
| 855 | 855 | case 0x05: |
| 856 | 856 | { |
| 857 | pc_fdc_se | |
| 857 | machine().device<pc_fdc_superio_device>("fdc")->tc_w(true); | |
| 858 | 858 | } |
| 859 | 859 | break; |
| 860 | 860 | |
| 861 | 861 | /* clear terminal count */ |
| 862 | 862 | case 0x06: |
| 863 | 863 | { |
| 864 | pc_fdc_se | |
| 864 | machine().device<pc_fdc_superio_device>("fdc")->tc_w(false); | |
| 865 | 865 | } |
| 866 | 866 | break; |
| 867 | 867 | |
| r18419 | r18420 | |
| 907 | 907 | } |
| 908 | 908 | } |
| 909 | 909 | |
| 910 | /**** SUPER I/O connections */ | |
| 911 | ||
| 912 | /* write to Super I/O chip. FDC Data Rate. */ | |
| 913 | WRITE8_MEMBER(pcw16_state::pcw16_superio_fdc_datarate_w) | |
| 910 | void pcw16_state::fdc_interrupt(bool state) | |
| 914 | 911 | { |
| 915 | pc_fdc_w(space, PC_FDC_DATA_RATE_REGISTER,data); | |
| 916 | } | |
| 917 | ||
| 918 | /* write to Super I/O chip. FDC Digital output register */ | |
| 919 | WRITE8_MEMBER(pcw16_state::pcw16_superio_fdc_digital_output_register_w) | |
| 920 | { | |
| 921 | pc_fdc_w(space, PC_FDC_DIGITAL_OUTPUT_REGISTER, data); | |
| 922 | } | |
| 923 | ||
| 924 | /* write to Super I/O chip. FDC Data Register */ | |
| 925 | WRITE8_MEMBER(pcw16_state::pcw16_superio_fdc_data_w) | |
| 926 | { | |
| 927 | pc_fdc_w(space, PC_FDC_DATA_REGISTER, data); | |
| 928 | } | |
| 929 | ||
| 930 | /* write to Super I/O chip. FDC Data Register */ | |
| 931 | READ8_MEMBER(pcw16_state::pcw16_superio_fdc_data_r) | |
| 932 | { | |
| 933 | return pc_fdc_r(space, PC_FDC_DATA_REGISTER); | |
| 934 | } | |
| 935 | ||
| 936 | /* write to Super I/O chip. FDC Main Status Register */ | |
| 937 | READ8_MEMBER(pcw16_state::pcw16_superio_fdc_main_status_register_r) | |
| 938 | { | |
| 939 | return pc_fdc_r(space, PC_FDC_MAIN_STATUS_REGISTER); | |
| 940 | } | |
| 941 | ||
| 942 | READ8_MEMBER(pcw16_state::pcw16_superio_fdc_digital_input_register_r) | |
| 943 | { | |
| 944 | return pc_fdc_r(space, PC_FDC_DIGITIAL_INPUT_REGISTER); | |
| 945 | } | |
| 946 | ||
| 947 | static void pcw16_fdc_interrupt(running_machine &machine, int state) | |
| 948 | { | |
| 949 | pcw16_state *drvstate = machine.driver_data<pcw16_state>(); | |
| 950 | 912 | /* IRQ6 */ |
| 951 | 913 | /* bit 6 of PCW16 system status indicates floppy ints */ |
| 952 | drvstate->m_system_status &= ~(1<<6); | |
| 953 | ||
| 954 | 914 | if (state) |
| 955 | { | |
| 956 | drvstate->m_system_status |= (1<<6); | |
| 957 | } | |
| 915 | m_system_status |= (1<<6); | |
| 916 | else | |
| 917 | m_system_status &= ~(1<<6); | |
| 958 | 918 | |
| 959 | | |
| 919 | trigger_fdc_int(); | |
| 960 | 920 | } |
| 961 | 921 | |
| 962 | static device_t * pcw16_get_device(running_machine &machine) | |
| 963 | { | |
| 964 | return machine.device("upd765"); | |
| 965 | } | |
| 966 | 922 | |
| 967 | static const struct pc_fdc_interface pcw16_fdc_interface= | |
| 968 | { | |
| 969 | pcw16_fdc_interrupt, | |
| 970 | NULL, | |
| 971 | NULL, | |
| 972 | pcw16_get_device | |
| 973 | }; | |
| 974 | ||
| 975 | ||
| 976 | 923 | WRITE_LINE_MEMBER(pcw16_state::pcw16_com_interrupt_1) |
| 977 | 924 | { |
| 978 | 925 | m_system_status &= ~(1 << 4); |
| r18419 | r18420 | |
| 1024 | 971 | } |
| 1025 | 972 | }; |
| 1026 | 973 | |
| 974 | static const floppy_format_type pcw16_floppy_formats[] = { | |
| 975 | FLOPPY_PC_FORMAT, | |
| 976 | FLOPPY_MFI_FORMAT, | |
| 977 | NULL | |
| 978 | }; | |
| 1027 | 979 | |
| 980 | static SLOT_INTERFACE_START( pcw16_floppies ) | |
| 981 | SLOT_INTERFACE( "35hd", FLOPPY_35_HD ) | |
| 982 | SLOT_INTERFACE_END | |
| 1028 | 983 | |
| 984 | ||
| 1029 | 985 | static ADDRESS_MAP_START(pcw16_io, AS_IO, 8, pcw16_state ) |
| 1030 | 986 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 1031 | 987 | /* super i/o chip */ |
| 1032 | AM_RANGE(0x01a, 0x01a) AM_WRITE(pcw16_superio_fdc_digital_output_register_w) | |
| 1033 | AM_RANGE(0x01c, 0x01c) AM_READ(pcw16_superio_fdc_main_status_register_r) | |
| 1034 | AM_RANGE(0x01d, 0x01d) AM_READWRITE(pcw16_superio_fdc_data_r, pcw16_superio_fdc_data_w) | |
| 1035 | AM_RANGE(0x01f, 0x01f) AM_READWRITE(pcw16_superio_fdc_digital_input_register_r, pcw16_superio_fdc_datarate_w) | |
| 988 | AM_RANGE(0x018, 0x01f) AM_DEVICE("fdc", pc_fdc_superio_device, map) | |
| 1036 | 989 | AM_RANGE(0x020, 0x027) AM_DEVREADWRITE("ns16550_1", ns16550_device, ins8250_r, ins8250_w) |
| 1037 | 990 | AM_RANGE(0x028, 0x02f) AM_DEVREADWRITE("ns16550_2", ns16550_device, ins8250_r, ins8250_w) |
| 1038 | 991 | AM_RANGE(0x038, 0x03a) AM_DEVREADWRITE_LEGACY("lpt", pc_lpt_r, pc_lpt_w) |
| r18419 | r18420 | |
| 1058 | 1011 | /* initialise defaults */ |
| 1059 | 1012 | m_fdc_int_code = 2; |
| 1060 | 1013 | /* clear terminal count */ |
| 1061 | pc_fdc_se | |
| 1014 | machine().device<pc_fdc_superio_device>("fdc")->tc_w(false); | |
| 1062 | 1015 | /* select first rom page */ |
| 1063 | 1016 | m_banks[0] = 0; |
| 1064 | 1017 | // pcw16_update_memory(machine); |
| r18419 | r18420 | |
| 1084 | 1037 | m_system_status = 0; |
| 1085 | 1038 | m_interrupt_counter = 0; |
| 1086 | 1039 | |
| 1087 | pc_fdc_init(machine(), &pcw16_fdc_interface); | |
| 1040 | machine().device<pc_fdc_superio_device>("fdc") | |
| 1041 | ->setup_intrq_cb(pc_fdc_superio_device::line_cb(FUNC(pcw16_state::fdc_interrupt), this)); | |
| 1088 | 1042 | |
| 1089 | 1043 | /* initialise keyboard */ |
| 1090 | 1044 | at_keyboard_init(machine(), AT_KEYBOARD_TYPE_AT); |
| r18419 | r18420 | |
| 1112 | 1066 | DEVCB_CPU_INPUT_LINE("maincpu", 0) |
| 1113 | 1067 | }; |
| 1114 | 1068 | |
| 1115 | static const floppy_interface pcw16_floppy_interface = | |
| 1116 | { | |
| 1117 | DEVCB_NULL, | |
| 1118 | DEVCB_NULL, | |
| 1119 | DEVCB_NULL, | |
| 1120 | DEVCB_NULL, | |
| 1121 | DEVCB_NULL, | |
| 1122 | FLOPPY_STANDARD_5_25_DSHD, | |
| 1123 | LEGACY_FLOPPY_OPTIONS_NAME(pc), | |
| 1124 | NULL, | |
| 1125 | NULL | |
| 1126 | }; | |
| 1127 | ||
| 1128 | 1069 | static MACHINE_CONFIG_START( pcw16, pcw16_state ) |
| 1129 | 1070 | /* basic machine hardware */ |
| 1130 | 1071 | MCFG_CPU_ADD("maincpu", Z80, 16000000) |
| r18419 | r18420 | |
| 1155 | 1096 | |
| 1156 | 1097 | /* printer */ |
| 1157 | 1098 | MCFG_PC_LPT_ADD("lpt", pcw16_lpt_config) |
| 1158 | MCFG_UPD765A_ADD("upd765", pc_fdc_upd765_connected_interface) | |
| 1159 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(pcw16_floppy_interface) | |
| 1099 | MCFG_PC_FDC_SUPERIO_ADD("fdc") | |
| 1100 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", pcw16_floppies, "35hd", 0, pcw16_floppy_formats) | |
| 1101 | MCFG_FLOPPY_DRIVE_ADD("fdc:1", pcw16_floppies, "35hd", 0, pcw16_floppy_formats) | |
| 1160 | 1102 | |
| 1161 | 1103 | /* internal ram */ |
| 1162 | 1104 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 28 | 28 | #include "cpu/z80/z80.h" |
| 29 | 29 | #include "imagedev/flopdrv.h" |
| 30 | 30 | #include "machine/ram.h" |
| 31 | #include "formats/ | |
| 31 | #include "formats/mfi_dsk.h" | |
| 32 | 32 | #include "machine/6821pia.h" |
| 33 | 33 | #include "machine/ctronics.h" |
| 34 | 34 | #include "machine/upd765.h" |
| r18419 | r18420 | |
| 146 | 146 | |
| 147 | 147 | if (data) |
| 148 | 148 | { |
| 149 | floppy_mon_w(m_floppy0, CLEAR_LINE); | |
| 150 | floppy_drive_set_ready_state(m_floppy0, 1, 0); | |
| 149 | m_floppy0->mon_w(false); | |
| 151 | 150 | } |
| 152 | 151 | |
| 153 | 152 | set_floppy_motor_off_timer(); |
| r18419 | r18420 | |
| 158 | 157 | |
| 159 | 158 | if (data) |
| 160 | 159 | { |
| 161 | floppy_mon_w(m_floppy1, CLEAR_LINE); | |
| 162 | floppy_drive_set_ready_state(m_floppy1, 1, 0); | |
| 160 | m_floppy1->mon_w(false); | |
| 163 | 161 | } |
| 164 | 162 | |
| 165 | 163 | set_floppy_motor_off_timer(); |
| 166 | 164 | break; |
| 167 | 165 | |
| 168 | 166 | case 7: /* FDC TC */ |
| 169 | | |
| 167 | m_fdc->tc_w(data); | |
| 170 | 168 | break; |
| 171 | 169 | } |
| 172 | 170 | } |
| r18419 | r18420 | |
| 199 | 197 | AM_RANGE(0x00, 0x0f) AM_READWRITE(ls259_r, ls259_w) |
| 200 | 198 | AM_RANGE(0x10, 0x10) AM_MIRROR(0x0e) AM_DEVWRITE(MC6845_TAG, mc6845_device, address_w) |
| 201 | 199 | AM_RANGE(0x11, 0x11) AM_MIRROR(0x0e) AM_DEVREADWRITE(MC6845_TAG, mc6845_device, register_r, register_w) |
| 202 | AM_RANGE(0x20, 0x20) AM_MIRROR(0x0e) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) | |
| 203 | AM_RANGE(0x21, 0x21) AM_MIRROR(0x0e) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) | |
| 200 | AM_RANGE(0x20, 0x21) AM_MIRROR(0x0e) AM_DEVICE(UPD765_TAG, upd765a_device, map) | |
| 204 | 201 | AM_RANGE(0x30, 0x33) AM_MIRROR(0x0c) AM_DEVREADWRITE(PIA6821_TAG, pia6821_device, read, write) |
| 205 | 202 | AM_RANGE(0x40, 0x40) AM_MIRROR(0x0c) AM_DEVREADWRITE_LEGACY(Z80SIO_TAG, z80dart_d_r, z80dart_d_w) |
| 206 | 203 | AM_RANGE(0x41, 0x41) AM_MIRROR(0x0c) AM_DEVREADWRITE_LEGACY(Z80SIO_TAG, z80dart_c_r, z80dart_c_w) |
| r18419 | r18420 | |
| 408 | 405 | |
| 409 | 406 | /* UPD765 Interface */ |
| 410 | 407 | |
| 411 | ||
| 408 | void bw12_state::fdc_intrq_w(bool state) | |
| 412 | 409 | { |
| 413 | 410 | m_fdc_int = state; |
| 414 | 411 | } |
| 415 | 412 | |
| 416 | static UPD765_GET_IMAGE( bw12_upd765_get_image ) | |
| 417 | { | |
| 418 | bw12_state *state = device->machine().driver_data<bw12_state>(); | |
| 419 | ||
| 420 | switch (floppy_index) | |
| 421 | { | |
| 422 | case 1: /* drive A */ | |
| 423 | return state->m_floppy0; | |
| 424 | ||
| 425 | case 2: /* drive B */ | |
| 426 | return state->m_floppy1; | |
| 427 | ||
| 428 | default: | |
| 429 | return NULL; | |
| 430 | } | |
| 431 | } | |
| 432 | ||
| 433 | static const struct upd765_interface fdc_intf = | |
| 434 | { | |
| 435 | DEVCB_DRIVER_LINE_MEMBER(bw12_state, fdc_intrq_w), /* interrupt */ | |
| 436 | DEVCB_NULL, /* DMA request */ | |
| 437 | bw12_upd765_get_image, /* image lookup */ | |
| 438 | UPD765_RDY_PIN_CONNECTED, /* ready pin */ | |
| 439 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 440 | }; | |
| 441 | ||
| 442 | 413 | /* PIA6821 Interface */ |
| 443 | 414 | |
| 444 | 415 | READ8_MEMBER( bw12_state::pia_pa_r ) |
| r18419 | r18420 | |
| 659 | 630 | } |
| 660 | 631 | } |
| 661 | 632 | |
| 662 | static LEGACY_FLOPPY_OPTIONS_START( bw12 ) | |
| 663 | LEGACY_FLOPPY_OPTION(bw12, "dsk", "180KB BW 12 SSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 664 | HEADS([1]) | |
| 665 | TRACKS([40]) | |
| 666 | SECTORS([18]) | |
| 667 | SECTOR_LENGTH([256]) | |
| 668 | FIRST_SECTOR_ID([0])) | |
| 669 | LEGACY_FLOPPY_OPTION(bw12, "dsk", "SVI-328 SSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 670 | HEADS([1]) | |
| 671 | TRACKS([40]) | |
| 672 | SECTORS([17]) | |
| 673 | SECTOR_LENGTH([256]) | |
| 674 | FIRST_SECTOR_ID([0])) | |
| 675 | LEGACY_FLOPPY_OPTION(bw12, "dsk", "Kaypro II SSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 676 | HEADS([1]) | |
| 677 | TRACKS([40]) | |
| 678 | SECTORS([10]) | |
| 679 | SECTOR_LENGTH([512]) | |
| 680 | FIRST_SECTOR_ID([0])) | |
| 681 | LEGACY_FLOPPY_OPTIONS_END | |
| 633 | static SLOT_INTERFACE_START( bw12_floppies ) | |
| 634 | SLOT_INTERFACE( "525ssdd", FLOPPY_525_SSDD ) | |
| 635 | SLOT_INTERFACE_END | |
| 682 | 636 | |
| 683 | static const floppy_interface bw12_floppy_interface = | |
| 684 | { | |
| 685 | DEVCB_NULL, | |
| 686 | DEVCB_NULL, | |
| 687 | DEVCB_NULL, | |
| 688 | DEVCB_NULL, | |
| 689 | DEVCB_NULL, | |
| 690 | FLOPPY_STANDARD_5_25_SSDD, | |
| 691 | LEGACY_FLOPPY_OPTIONS_NAME(bw12), | |
| 692 | NULL, | |
| 637 | static const floppy_format_type bw12_floppy_formats[] = { | |
| 638 | FLOPPY_MFI_FORMAT, | |
| 693 | 639 | NULL |
| 694 | 640 | }; |
| 695 | 641 | |
| 696 | static LEGACY_FLOPPY_OPTIONS_START( bw14 ) | |
| 697 | LEGACY_FLOPPY_OPTION(bw14, "dsk", "180KB BW 12 SSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 698 | HEADS([1]) | |
| 699 | TRACKS([40]) | |
| 700 | SECTORS([18]) | |
| 701 | SECTOR_LENGTH([256]) | |
| 702 | FIRST_SECTOR_ID([0])) | |
| 703 | LEGACY_FLOPPY_OPTION(bw14, "dsk", "360KB BW 14 DSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 704 | HEADS([2]) | |
| 705 | TRACKS([40]) | |
| 706 | SECTORS([18]) | |
| 707 | SECTOR_LENGTH([256]) | |
| 708 | FIRST_SECTOR_ID([0])) | |
| 709 | LEGACY_FLOPPY_OPTION(bw14, "dsk", "SVI-328 SSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 710 | HEADS([1]) | |
| 711 | TRACKS([40]) | |
| 712 | SECTORS([17]) | |
| 713 | SECTOR_LENGTH([256]) | |
| 714 | FIRST_SECTOR_ID([0])) | |
| 715 | LEGACY_FLOPPY_OPTION(bw14, "dsk", "SVI-328 DSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 716 | HEADS([2]) | |
| 717 | TRACKS([40]) | |
| 718 | SECTORS([17]) | |
| 719 | SECTOR_LENGTH([256]) | |
| 720 | FIRST_SECTOR_ID([0])) | |
| 721 | LEGACY_FLOPPY_OPTION(bw14, "dsk", "Kaypro II SSDD", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 722 | HEADS([1]) | |
| 723 | TRACKS([40]) | |
| 724 | SECTORS([10]) | |
| 725 | SECTOR_LENGTH([512]) | |
| 726 | FIRST_SECTOR_ID([0])) | |
| 727 | LEGACY_FLOPPY_OPTIONS_END | |
| 642 | static SLOT_INTERFACE_START( bw14_floppies ) | |
| 643 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 644 | SLOT_INTERFACE_END | |
| 728 | 645 | |
| 729 | ||
| 730 | static const floppy_interface bw14_floppy_interface = | |
| 731 | { | |
| 732 | DEVCB_NULL, | |
| 733 | DEVCB_NULL, | |
| 734 | DEVCB_NULL, | |
| 735 | DEVCB_NULL, | |
| 736 | DEVCB_NULL, | |
| 737 | FLOPPY_STANDARD_5_25_DSHD, | |
| 738 | LEGACY_FLOPPY_OPTIONS_NAME(bw14), | |
| 739 | NULL, | |
| 646 | static const floppy_format_type bw14_floppy_formats[] = { | |
| 647 | FLOPPY_MFI_FORMAT, | |
| 740 | 648 | NULL |
| 741 | 649 | }; |
| 742 | 650 | |
| r18419 | r18420 | |
| 788 | 696 | |
| 789 | 697 | /* devices */ |
| 790 | 698 | MCFG_TIMER_DRIVER_ADD(FLOPPY_TIMER_TAG, bw12_state, floppy_motor_off_tick) |
| 791 | MCFG_UPD765A_ADD(UPD765_TAG, | |
| 699 | MCFG_UPD765A_ADD(UPD765_TAG, true, true) | |
| 792 | 700 | MCFG_PIA6821_ADD(PIA6821_TAG, pia_intf) |
| 793 | 701 | MCFG_Z80SIO0_ADD(Z80SIO_TAG, XTAL_16MHz/4, sio_intf) |
| 794 | 702 | MCFG_PIT8253_ADD(PIT8253_TAG, pit_intf) |
| r18419 | r18420 | |
| 800 | 708 | |
| 801 | 709 | static MACHINE_CONFIG_DERIVED( bw12, common ) |
| 802 | 710 | /* floppy drives */ |
| 803 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(bw12_floppy_interface) | |
| 711 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", bw12_floppies, "525ssdd", 0, bw12_floppy_formats) | |
| 712 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", bw12_floppies, "525ssdd", 0, bw12_floppy_formats) | |
| 804 | 713 | |
| 805 | 714 | // software lists |
| 806 | 715 | MCFG_SOFTWARE_LIST_ADD("flop_list", "bw12") |
| r18419 | r18420 | |
| 812 | 721 | |
| 813 | 722 | static MACHINE_CONFIG_DERIVED( bw14, common ) |
| 814 | 723 | /* floppy drives */ |
| 815 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(bw14_floppy_interface) | |
| 724 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", bw14_floppies, "525hd", 0, bw14_floppy_formats) | |
| 725 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":1", bw14_floppies, "525hd", 0, bw14_floppy_formats) | |
| 816 | 726 | |
| 817 | 727 | /* internal ram */ |
| 818 | 728 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 28 | 28 | #include "imagedev/flopdrv.h" |
| 29 | 29 | #include "imagedev/cassette.h" |
| 30 | 30 | #include "formats/tzx_cas.h" |
| 31 | #include "formats/mfi_dsk.h" | |
| 31 | 32 | #include "machine/ram.h" |
| 32 | 33 | |
| 33 | 34 | |
| r18419 | r18420 | |
| 79 | 80 | * |
| 80 | 81 | *************************************/ |
| 81 | 82 | |
| 82 | static const struct upd765_interface elwro800jr_upd765_interface = | |
| 83 | { | |
| 84 | DEVCB_NULL, | |
| 85 | DEVCB_NULL, | |
| 86 | NULL, | |
| 87 | UPD765_RDY_PIN_CONNECTED, | |
| 88 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 89 | }; | |
| 90 | ||
| 91 | 83 | WRITE8_MEMBER(elwro800_state::elwro800jr_fdc_control_w) |
| 92 | 84 | { |
| 93 | device | |
| 85 | upd765a_device *fdc = machine().device<upd765a_device>("upd765"); | |
| 94 | 86 | |
| 95 | floppy_mon_w(floppy_get_device(machine(), 0), !BIT(data, 0)); | |
| 96 | floppy_mon_w(floppy_get_device(machine(), 1), !BIT(data, 1)); | |
| 97 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), 1,1); | |
| 98 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1), 1,1); | |
| 87 | machine().device<floppy_connector>("upd765:0")->get_device()->mon_w(!BIT(data, 0)); | |
| 88 | machine().device<floppy_connector>("upd765:1")->get_device()->mon_w(!BIT(data, 1)); | |
| 99 | 89 | |
| 100 | | |
| 90 | fdc->tc_w(data & 0x04); | |
| 101 | 91 | |
| 102 | upd765_reset_w(fdc, !(data & 0x08)); | |
| 92 | if(!(data & 8)) | |
| 93 | fdc->reset(); | |
| 103 | 94 | } |
| 104 | 95 | |
| 105 | 96 | /************************************* |
| r18419 | r18420 | |
| 289 | 280 | else if (!BIT(cs,3)) |
| 290 | 281 | { |
| 291 | 282 | // CSFDC |
| 292 | device | |
| 283 | upd765a_device *fdc = machine().device<upd765a_device>("upd765"); | |
| 293 | 284 | if (offset & 1) |
| 294 | 285 | { |
| 295 | return | |
| 286 | return fdc->fifo_r(space, 0, 0xff); | |
| 296 | 287 | } |
| 297 | 288 | else |
| 298 | 289 | { |
| 299 | return | |
| 290 | return fdc->msr_r(space, 0, 0xff); | |
| 300 | 291 | } |
| 301 | 292 | } |
| 302 | 293 | else if (!BIT(cs,4)) |
| r18419 | r18420 | |
| 347 | 338 | else if (!BIT(cs,3)) |
| 348 | 339 | { |
| 349 | 340 | // CSFDC |
| 350 | device | |
| 341 | upd765a_device *fdc = machine().device<upd765a_device>("upd765"); | |
| 351 | 342 | if (offset & 1) |
| 352 | 343 | { |
| 353 | | |
| 344 | fdc->fifo_w(space, 0, data, 0xff); | |
| 354 | 345 | } |
| 355 | 346 | } |
| 356 | 347 | else if (!BIT(cs,4)) |
| r18419 | r18420 | |
| 543 | 534 | device.execute().set_input_line(0, HOLD_LINE); |
| 544 | 535 | } |
| 545 | 536 | |
| 546 | static const floppy_interface elwro800jr_floppy_interface = | |
| 547 | { | |
| 548 | DEVCB_NULL, | |
| 549 | DEVCB_NULL, | |
| 550 | DEVCB_NULL, | |
| 551 | DEVCB_NULL, | |
| 552 | DEVCB_NULL, | |
| 553 | FLOPPY_STANDARD_5_25_DSHD, | |
| 554 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 555 | NULL, | |
| 537 | static const floppy_format_type elwro800jr_floppy_formats[] = { | |
| 538 | FLOPPY_MFI_FORMAT, | |
| 556 | 539 | NULL |
| 557 | 540 | }; |
| 558 | 541 | |
| 542 | static SLOT_INTERFACE_START( elwro800jr_floppies ) | |
| 543 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 544 | SLOT_INTERFACE_END | |
| 545 | ||
| 559 | 546 | /* F4 Character Displayer */ |
| 560 | 547 | static const gfx_layout elwro800_charlayout = |
| 561 | 548 | { |
| r18419 | r18420 | |
| 600 | 587 | |
| 601 | 588 | MCFG_VIDEO_START_OVERRIDE(elwro800_state, spectrum ) |
| 602 | 589 | |
| 603 | MCFG_UPD765A_ADD("upd765", | |
| 590 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 604 | 591 | MCFG_I8255A_ADD( "ppi8255", elwro800jr_ppi8255_interface) |
| 605 | 592 | |
| 606 | 593 | /* printer */ |
| r18419 | r18420 | |
| 617 | 604 | |
| 618 | 605 | MCFG_CASSETTE_ADD( CASSETTE_TAG, elwro800jr_cassette_interface ) |
| 619 | 606 | |
| 620 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(elwro800jr_floppy_interface) | |
| 607 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", elwro800jr_floppies, "525hd", 0, elwro800jr_floppy_formats) | |
| 608 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", elwro800jr_floppies, "525hd", 0, elwro800jr_floppy_formats) | |
| 621 | 609 | |
| 622 | 610 | /* internal ram */ |
| 623 | 611 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 244 | 244 | #include "cpu/z80/z80.h" |
| 245 | 245 | #include "imagedev/cassette.h" |
| 246 | 246 | #include "imagedev/flopdrv.h" |
| 247 | #include "imagedev/cassette.h" | |
| 247 | #include "formats/mfi_dsk.h" | |
| 248 | #include "formats/d88_dsk.h" | |
| 248 | 249 | #include "machine/ctronics.h" |
| 249 | 250 | #include "machine/i8255.h" |
| 250 | 251 | #include "machine/upd1990a.h" |
| r18419 | r18420 | |
| 438 | 439 | void pc8801_draw_char(bitmap_ind16 &bitmap,int x,int y,int pal,UINT8 gfx_mode,UINT8 reverse,UINT8 secret, |
| 439 | 440 | UINT8 blink,UINT8 upper,UINT8 lower,int y_size,int width, UINT8 non_special); |
| 440 | 441 | void draw_text(bitmap_ind16 &bitmap,int y_size, UINT8 width); |
| 442 | void fdc_irq_w(bool state); | |
| 441 | 443 | |
| 442 | 444 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 443 | 445 | |
| r18419 | r18420 | |
| 1887 | 1889 | { |
| 1888 | 1890 | |
| 1889 | 1891 | //printf("0\n"); |
| 1890 | | |
| 1892 | machine().device<upd765a_device>("upd765")->tc_w(false); | |
| 1891 | 1893 | } |
| 1892 | 1894 | |
| 1893 | 1895 | WRITE8_MEMBER(pc8801_state::upd765_mc_w) |
| 1894 | 1896 | { |
| 1895 | floppy_mon_w(floppy_get_device(machine(), 0), (data & 1) ? CLEAR_LINE : ASSERT_LINE); | |
| 1896 | floppy_mon_w(floppy_get_device(machine(), 1), (data & 2) ? CLEAR_LINE : ASSERT_LINE); | |
| 1897 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0), (data & 1), 0); | |
| 1898 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1), (data & 2), 0); | |
| 1897 | machine().device<floppy_connector>("upd765:0")->get_device()->mon_w(!(data & 1)); | |
| 1898 | machine().device<floppy_connector>("upd765:1")->get_device()->mon_w(!(data & 2)); | |
| 1899 | 1899 | } |
| 1900 | 1900 | |
| 1901 | 1901 | READ8_MEMBER(pc8801_state::upd765_tc_r) |
| 1902 | 1902 | { |
| 1903 | 1903 | //printf("%04x 1\n",m_fdccpu->pc()); |
| 1904 | 1904 | |
| 1905 | upd765_tc_w(machine().device("upd765"), 1); | |
| 1906 | //TODO: I'm not convinced that this works correctly with current hook-up ... 1000 usec is needed by Aploon, a bigger value breaks Alpha. | |
| 1907 | machine().scheduler().timer_set(attotime::from_usec(750), timer_expired_delegate(FUNC(pc8801_state::pc8801fd_upd765_tc_to_zero),this)); | |
| 1905 | machine().device<upd765a_device>("upd765")->tc_w(true); | |
| 1906 | //TODO: I'm not convinced that this works correctly with current hook-up ... 1000 usec is needed by Aploon, a bigger value breaks Alpha. | |
| 1907 | //OTOH, 50 seems more than enough for the new upd... | |
| 1908 | machine().scheduler().timer_set(attotime::from_usec(50), timer_expired_delegate(FUNC(pc8801_state::pc8801fd_upd765_tc_to_zero),this)); | |
| 1908 | 1909 | return 0xff; // value is meaningless |
| 1909 | 1910 | } |
| 1910 | 1911 | |
| r18419 | r18420 | |
| 1916 | 1917 | |
| 1917 | 1918 | WRITE8_MEMBER(pc8801_state::fdc_drive_mode_w) |
| 1918 | 1919 | { |
| 1919 | if(data & 5) | |
| 1920 | printf("drive 0 sets up %s floppy format\n",data & 1 ? "2hd" : "2dd"); | |
| 1921 | if(data & 0xa) | |
| 1922 | printf("drive 1 sets up %s floppy format\n",data & 2 ? "2hd" : "2dd"); | |
| 1920 | logerror("FDC drive mode %02x\n", data); | |
| 1921 | machine().device<floppy_connector>("upd765:0")->get_device()->set_rpm(data & 0x01 ? 360 : 300); | |
| 1922 | machine().device<floppy_connector>("upd765:1")->get_device()->set_rpm(data & 0x02 ? 360 : 300); | |
| 1923 | ||
| 1924 | machine().device<upd765a_device>("upd765")->set_rate(data & 0x20 ? 500000 : 250000); | |
| 1923 | 1925 | } |
| 1924 | 1926 | |
| 1925 | 1927 | static ADDRESS_MAP_START( pc8801fdc_io, AS_IO, 8, pc8801_state ) |
| r18419 | r18420 | |
| 1928 | 1930 | AM_RANGE(0xf4, 0xf4) AM_WRITE(fdc_drive_mode_w) // Drive mode, 2d, 2dd, 2hd |
| 1929 | 1931 | AM_RANGE(0xf7, 0xf7) AM_WRITENOP // printer port output |
| 1930 | 1932 | AM_RANGE(0xf8, 0xf8) AM_READWRITE(upd765_tc_r,upd765_mc_w) // (R) Terminal Count Port (W) Motor Control Port |
| 1931 | AM_RANGE(0xfa, 0xfa) AM_DEVREAD_LEGACY("upd765", upd765_status_r ) | |
| 1932 | AM_RANGE(0xfb, 0xfb) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w ) | |
| 1933 | AM_RANGE(0xfa, 0xfb) AM_DEVICE("upd765", upd765a_device, map ) | |
| 1933 | 1934 | AM_RANGE(0xfc, 0xff) AM_DEVREADWRITE("d8255_slave", i8255_device, read, write) |
| 1934 | 1935 | ADDRESS_MAP_END |
| 1935 | 1936 | |
| r18419 | r18420 | |
| 2261 | 2262 | |
| 2262 | 2263 | /* Floppy Configuration */ |
| 2263 | 2264 | |
| 2264 | static const floppy_interface pc88_floppy_interface = | |
| 2265 | { | |
| 2266 | DEVCB_NULL, | |
| 2267 | DEVCB_NULL, | |
| 2268 | DEVCB_NULL, | |
| 2269 | DEVCB_NULL, | |
| 2270 | DEVCB_NULL, | |
| 2271 | FLOPPY_STANDARD_5_25_DSHD, | |
| 2272 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 2273 | "floppy_5_25", | |
| 2265 | ||
| 2266 | static const floppy_format_type pc88_floppy_formats[] = { | |
| 2267 | FLOPPY_D88_FORMAT, | |
| 2268 | FLOPPY_MFI_FORMAT, | |
| 2274 | 2269 | NULL |
| 2275 | 2270 | }; |
| 2276 | 2271 | |
| 2272 | static SLOT_INTERFACE_START( pc88_floppies ) | |
| 2273 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 2274 | SLOT_INTERFACE_END | |
| 2275 | ||
| 2277 | 2276 | /* Cassette Configuration */ |
| 2278 | 2277 | |
| 2279 | 2278 | static const cassette_interface pc88_cassette_interface = |
| r18419 | r18420 | |
| 2433 | 2432 | { |
| 2434 | 2433 | |
| 2435 | 2434 | machine().device("maincpu")->execute().set_irq_acknowledge_callback(pc8801_irq_callback); |
| 2435 | machine().device<upd765a_device>("upd765")->setup_intrq_cb(upd765a_device::line_cb(FUNC(pc8801_state::fdc_irq_w), this)); | |
| 2436 | 2436 | |
| 2437 | machine().device<floppy_connector>("upd765:0")->get_device()->set_rpm(300); | |
| 2438 | machine().device<floppy_connector>("upd765:1")->get_device()->set_rpm(300); | |
| 2439 | machine().device<upd765a_device>("upd765")->set_rate(250000); | |
| 2440 | ||
| 2437 | 2441 | m_rtc->cs_w(1); |
| 2438 | 2442 | m_rtc->oe_w(1); |
| 2439 | 2443 | } |
| r18419 | r18420 | |
| 2563 | 2567 | palette_set_color_rgb(machine(), i, pal1bit(i >> 1), pal1bit(i >> 2), pal1bit(i >> 0)); |
| 2564 | 2568 | } |
| 2565 | 2569 | |
| 2566 | ||
| 2570 | void pc8801_state::fdc_irq_w(bool state) | |
| 2567 | 2571 | { |
| 2568 | DEVCB_CPU_INPUT_LINE("fdccpu", INPUT_LINE_IRQ0), | |
| 2569 | DEVCB_NULL, //DRQ, TODO | |
| 2570 | NULL, | |
| 2571 | UPD765_RDY_PIN_CONNECTED, | |
| 2572 | {FLOPPY_0, FLOPPY_1, NULL, NULL} | |
| 2573 | }; | |
| 2572 | m_fdccpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); | |
| 2573 | } | |
| 2574 | 2574 | |
| 2575 | 2575 | /* YM2203 Interface */ |
| 2576 | 2576 | |
| r18419 | r18420 | |
| 2682 | 2682 | MCFG_I8255_ADD( "d8255_master", master_fdd_intf ) |
| 2683 | 2683 | MCFG_I8255_ADD( "d8255_slave", slave_fdd_intf ) |
| 2684 | 2684 | |
| 2685 | MCFG_UPD765A_ADD("upd765", | |
| 2685 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 2686 | 2686 | #ifdef USE_PROPER_I8214 |
| 2687 | 2687 | MCFG_I8214_ADD(I8214_TAG, MASTER_CLOCK, pic_intf) |
| 2688 | 2688 | #endif |
| r18419 | r18420 | |
| 2693 | 2693 | |
| 2694 | 2694 | MCFG_I8251_ADD(I8251_TAG, uart_intf) |
| 2695 | 2695 | |
| 2696 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(pc88_floppy_interface) | |
| 2696 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", pc88_floppies, "525hd", 0, pc88_floppy_formats) | |
| 2697 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", pc88_floppies, "525hd", 0, pc88_floppy_formats) | |
| 2697 | 2698 | MCFG_SOFTWARE_LIST_ADD("disk_list","pc8801_flop") |
| 2698 | 2699 | |
| 2699 | 2700 | /* video hardware */ |
| r18419 | r18420 | |
|---|---|---|
| 79 | 79 | #include "sound/discrete.h" /* for 1 Bit sound*/ |
| 80 | 80 | #include "machine/upd765.h" /* for floppy disc controller */ |
| 81 | 81 | #include "imagedev/flopdrv.h" |
| 82 | #include "formats/ | |
| 82 | #include "formats/mfi_dsk.h" | |
| 83 | 83 | #include "cpu/z80/z80.h" |
| 84 | 84 | #include "formats/hect_dsk.h" |
| 85 | 85 | #include "includes/hec2hrp.h" |
| r18419 | r18420 | |
| 108 | 108 | AM_RANGE(0x040,0x04f) AM_READWRITE_LEGACY(hector_disc2_io40_port_r, hector_disc2_io40_port_w ) |
| 109 | 109 | AM_RANGE(0x050,0x05f) AM_READWRITE_LEGACY(hector_disc2_io50_port_r, hector_disc2_io50_port_w ) |
| 110 | 110 | // uPD765 link: |
| 111 | AM_RANGE(0x060,0x060) AM_DEVREAD_LEGACY("upd765",upd765_status_r ) | |
| 112 | // AM_RANGE(0x061,0x061) AM_DEVREADWRITE_LEGACY("upd765",upd765_data_r,upd765_data_w) | |
| 113 | // AM_RANGE(0x070,0x07f) AM_DEVREADWRITE_LEGACY("upd765",upd765_dack_r,upd765_dack_w) | |
| 114 | AM_RANGE(0x061,0x061) AM_READWRITE_LEGACY(hector_disc2_io61_port_r, hector_disc2_io61_port_w )//patched version | |
| 115 | AM_RANGE(0x070,0x07F) AM_READWRITE_LEGACY(hector_disc2_io70_port_r, hector_disc2_io70_port_w )//patched version | |
| 111 | AM_RANGE(0x060,0x061) AM_DEVICE("upd765", upd765a_device, map) | |
| 112 | AM_RANGE(0x070,0x07f) AM_DEVREADWRITE("upd765", upd765a_device, mdma_r, mdma_w) | |
| 116 | 113 | ADDRESS_MAP_END |
| 117 | 114 | |
| 118 | 115 | /*****************************************************************************/ |
| r18419 | r18420 | |
| 519 | 516 | |
| 520 | 517 | MACHINE_CONFIG_END |
| 521 | 518 | |
| 519 | static const floppy_format_type hector_floppy_formats[] = { | |
| 520 | FLOPPY_MFI_FORMAT, | |
| 521 | NULL | |
| 522 | }; | |
| 523 | ||
| 524 | static SLOT_INTERFACE_START( hector_floppies ) | |
| 525 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 526 | SLOT_INTERFACE_END | |
| 527 | ||
| 522 | 528 | /*****************************************************************************/ |
| 523 | 529 | static MACHINE_CONFIG_START( hec2mx40, hec2hrp_state ) |
| 524 | 530 | /*****************************************************************************/ |
| r18419 | r18420 | |
| 532 | 538 | MCFG_CPU_ADD("disc2cpu",Z80, XTAL_4MHz) |
| 533 | 539 | MCFG_CPU_PROGRAM_MAP(hecdisc2_mem) |
| 534 | 540 | MCFG_CPU_IO_MAP(hecdisc2_io) |
| 535 | MCFG_UPD765A_ADD("upd765", hector_disc2_upd765_interface) | |
| 536 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(hector_disc2_floppy_interface) | |
| 541 | MCFG_UPD765A_ADD("upd765", false, true) | |
| 542 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", hector_floppies, "525hd", 0, hector_floppy_formats) | |
| 543 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", hector_floppies, "525hd", 0, hector_floppy_formats) | |
| 537 | 544 | MCFG_MACHINE_RESET_OVERRIDE(hec2hrp_state,hec2hrx) |
| 538 | 545 | MCFG_MACHINE_START_OVERRIDE(hec2hrp_state,hec2hrx) |
| 539 | 546 | |
| r18419 | r18420 | |
| 583 | 590 | MCFG_CPU_ADD("disc2cpu",Z80, XTAL_4MHz) |
| 584 | 591 | MCFG_CPU_PROGRAM_MAP(hecdisc2_mem) |
| 585 | 592 | MCFG_CPU_IO_MAP(hecdisc2_io) |
| 586 | MCFG_UPD765A_ADD("upd765", hector_disc2_upd765_interface) | |
| 587 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(hector_disc2_floppy_interface) | |
| 593 | MCFG_UPD765A_ADD("upd765", false, true) | |
| 594 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", hector_floppies, "525hd", 0, hector_floppy_formats) | |
| 595 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", hector_floppies, "525hd", 0, hector_floppy_formats) | |
| 588 | 596 | |
| 589 | 597 | /* video hardware */ |
| 590 | 598 | MCFG_SCREEN_ADD("screen", RASTER) |
| r18419 | r18420 | |
| 681 | 689 | MCFG_CPU_ADD("disc2cpu",Z80, XTAL_4MHz) |
| 682 | 690 | MCFG_CPU_PROGRAM_MAP(hecdisc2_mem) |
| 683 | 691 | MCFG_CPU_IO_MAP(hecdisc2_io) |
| 684 | MCFG_UPD765A_ADD("upd765", hector_disc2_upd765_interface) | |
| 685 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(hector_disc2_floppy_interface) | |
| 692 | MCFG_UPD765A_ADD("upd765", false, true) | |
| 693 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", hector_floppies, "525hd", 0, hector_floppy_formats) | |
| 694 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", hector_floppies, "525hd", 0, hector_floppy_formats) | |
| 686 | 695 | |
| 687 | 696 | /* video hardware */ |
| 688 | 697 | MCFG_SCREEN_ADD("screen", RASTER) |
| r18419 | r18420 | |
|---|---|---|
| 49 | 49 | #include "cpu/z80/z80.h" |
| 50 | 50 | #include "cpu/z8000/z8000.h" |
| 51 | 51 | #include "cpu/z80/z80daisy.h" |
| 52 | #include "formats/ | |
| 52 | #include "formats/mfi_dsk.h" | |
| 53 | 53 | #include "imagedev/flopdrv.h" |
| 54 | 54 | #include "machine/upd765.h" |
| 55 | 55 | #include "machine/z80ctc.h" |
| r18419 | r18420 | |
| 82 | 82 | DECLARE_DRIVER_INIT(p8k); |
| 83 | 83 | DECLARE_MACHINE_RESET(p8k); |
| 84 | 84 | DECLARE_MACHINE_RESET(p8k_16); |
| 85 | ||
| 86 | void fdc_irq(bool state); | |
| 87 | void fdc_drq(bool state); | |
| 88 | ||
| 89 | virtual void machine_start(); | |
| 85 | 90 | }; |
| 86 | 91 | |
| 87 | 92 | /*************************************************************************** |
| r18419 | r18420 | |
| 116 | 121 | AM_RANGE(0x0c, 0x0f) AM_DEVREADWRITE("z80pio_0", z80pio_device, read_alt, write_alt) |
| 117 | 122 | AM_RANGE(0x18, 0x1b) AM_DEVREADWRITE("z80pio_1", z80pio_device, read_alt, write_alt) |
| 118 | 123 | AM_RANGE(0x1c, 0x1f) AM_DEVREADWRITE("z80pio_2", z80pio_device, read_alt, write_alt) |
| 119 | AM_RANGE(0x20, 0x20) AM_DEVREADWRITE_LEGACY("i8272", upd765_data_r, upd765_data_w) | |
| 120 | AM_RANGE(0x21, 0x21) AM_DEVREAD_LEGACY("i8272", upd765_status_r) | |
| 124 | AM_RANGE(0x20, 0x21) AM_DEVICE("i8272", i8272a_device, map) | |
| 121 | 125 | //AM_RANGE(0x24, 0x27) AM_DEVREADWRITE("z80sio_0", z80sio_device, read_alt, write_alt) |
| 122 | 126 | AM_RANGE(0x24, 0x27) AM_READWRITE(p8k_port24_r,p8k_port24_w) |
| 123 | 127 | AM_RANGE(0x28, 0x2b) AM_DEVREADWRITE("z80sio_1", z80sio_device, read_alt, write_alt) |
| r18419 | r18420 | |
| 211 | 215 | |
| 212 | 216 | static WRITE_LINE_DEVICE_HANDLER( p8k_dma_irq_w ) |
| 213 | 217 | { |
| 214 | if (state) | |
| 215 | { | |
| 216 | device_t *i8272 = device->machine().device("i8272"); | |
| 217 | upd765_tc_w(i8272, state); | |
| 218 | } | |
| 218 | i8272a_device *i8272 = device->machine().device<i8272a_device>("i8272"); | |
| 219 | i8272->tc_w(state); | |
| 219 | 220 | |
| 220 | 221 | p8k_daisy_interrupt(device, state); |
| 221 | 222 | } |
| r18419 | r18420 | |
| 350 | 351 | |
| 351 | 352 | /* Intel 8272 Interface */ |
| 352 | 353 | |
| 353 | ||
| 354 | void p8k_state::fdc_irq(bool state) | |
| 354 | 355 | { |
| 355 | z80pio_device *z80pio = | |
| 356 | z80pio_device *z80pio = machine().device<z80pio_device>("z80pio_2"); | |
| 356 | 357 | |
| 357 | z80pio->port_b_write( | |
| 358 | z80pio->port_b_write(state ? 0x10 : 0x00); | |
| 358 | 359 | } |
| 359 | 360 | |
| 360 | stat | |
| 361 | void p8k_state::fdc_drq(bool state) | |
| 361 | 362 | { |
| 362 | DEVCB_LINE(p8k_i8272_irq_w), | |
| 363 | DEVCB_DEVICE_LINE("z80dma", z80dma_rdy_w), | |
| 364 | NULL, | |
| 365 | UPD765_RDY_PIN_CONNECTED, | |
| 366 | { FLOPPY_0, FLOPPY_1, NULL, NULL } | |
| 367 | }; | |
| 363 | z80dma_device *z80dma = machine().device<z80dma_device>("z80dma"); | |
| 364 | z80dma->rdy_w(state); | |
| 365 | } | |
| 368 | 366 | |
| 369 | ||
| 367 | void p8k_state::machine_start() | |
| 370 | 368 | { |
| 371 | DEVCB_NULL, | |
| 372 | DEVCB_NULL, | |
| 373 | DEVCB_NULL, | |
| 374 | DEVCB_NULL, | |
| 375 | DEVCB_NULL, | |
| 376 | FLOPPY_STANDARD_5_25_DSHD, | |
| 377 | LEGACY_FLOPPY_OPTIONS_NAME(default), | |
| 378 | NULL, | |
| 369 | i8272a_device *fdc = machine().device<i8272a_device>("i8272"); | |
| 370 | fdc->setup_intrq_cb(i8272a_device::line_cb(FUNC(p8k_state::fdc_irq), this)); | |
| 371 | fdc->setup_drq_cb(i8272a_device::line_cb(FUNC(p8k_state::fdc_drq), this)); | |
| 372 | } | |
| 373 | ||
| 374 | static const floppy_format_type p8k_floppy_formats[] = { | |
| 375 | FLOPPY_MFI_FORMAT, | |
| 379 | 376 | NULL |
| 380 | 377 | }; |
| 381 | 378 | |
| 379 | static SLOT_INTERFACE_START( p8k_floppies ) | |
| 380 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 381 | SLOT_INTERFACE_END | |
| 382 | ||
| 382 | 383 | /* Input ports */ |
| 383 | 384 | static INPUT_PORTS_START( p8k ) |
| 384 | 385 | PORT_START("DSW") |
| r18419 | r18420 | |
| 726 | 727 | MCFG_Z80PIO_ADD("z80pio_0", 1229000, p8k_pio_0_intf) |
| 727 | 728 | MCFG_Z80PIO_ADD("z80pio_1", 1229000, p8k_pio_1_intf) |
| 728 | 729 | MCFG_Z80PIO_ADD("z80pio_2", 1229000, p8k_pio_2_intf) |
| 729 | MCFG_UPD765A_ADD("i8272", p8k_i8272_intf) | |
| 730 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(p8k_floppy_interface) | |
| 730 | MCFG_I8272A_ADD("i8272", true) | |
| 731 | MCFG_FLOPPY_DRIVE_ADD("i8272:0", p8k_floppies, "525hd", 0, p8k_floppy_formats) | |
| 732 | MCFG_FLOPPY_DRIVE_ADD("i8272:1", p8k_floppies, "525hd", 0, p8k_floppy_formats) | |
| 731 | 733 | |
| 732 | 734 | /* sound hardware */ |
| 733 | 735 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| r18419 | r18420 | |
|---|---|---|
| 624 | 624 | // reason. The kernel otoh behaves as expected. |
| 625 | 625 | |
| 626 | 626 | if(fdc) { |
| 627 | floppy_image_device *fdev = machine().device<floppy_connector>(":fd0")->get_device(); | |
| 627 | floppy_image_device *fdev = machine().device<floppy_connector>(":fdc:0")->get_device(); | |
| 628 | 628 | if(fdev->exists()) { |
| 629 | 629 | UINT32 variant = fdev->get_variant(); |
| 630 | 630 | switch(variant) { |
| r18419 | r18420 | |
| 889 | 889 | ADDRESS_MAP_END |
| 890 | 890 | |
| 891 | 891 | static ADDRESS_MAP_START( next_fdc_mem, AS_PROGRAM, 32, next_state ) |
| 892 | AM_RANGE(0x02014100, 0x02014107) AM_MIRROR(0x300000) AM_DEVICE8("fdc", n82077aa_device, | |
| 892 | AM_RANGE(0x02014100, 0x02014107) AM_MIRROR(0x300000) AM_DEVICE8("fdc", n82077aa_device, map, 0xffffffff) | |
| 893 | 893 | AM_RANGE(0x02014108, 0x0201410b) AM_MIRROR(0x300000) AM_READWRITE(fdc_control_r, fdc_control_w) |
| 894 | 894 | |
| 895 | 895 | AM_IMPORT_FROM(next_mem) |
| r18419 | r18420 | |
| 987 | 987 | |
| 988 | 988 | static MACHINE_CONFIG_DERIVED( next_fdc_base, next_base ) |
| 989 | 989 | MCFG_N82077AA_ADD("fdc", n82077aa_device::MODE_PS2) |
| 990 | MCFG_FLOPPY_DRIVE_ADD("fd0", next_floppies, "35ed", 0, next_state::floppy_formats) | |
| 990 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", next_floppies, "35ed", 0, next_state::floppy_formats) | |
| 991 | 991 | MACHINE_CONFIG_END |
| 992 | 992 | |
| 993 | 993 | static MACHINE_CONFIG_DERIVED( nexts, next_fdc_base ) |
| r18419 | r18420 | |
| 1145 | 1145 | COMP( 1990, nextstc, nextst, 0, nextstc, next, next_state, nextstc, "Next Software Inc", "NeXTstation turbo color", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 1146 | 1146 | COMP( ????, nextct, nextst, 0, nextct, next, next_state, nextct, "Next Software Inc", "NeXT Cube turbo", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 1147 | 1147 | COMP( ????, nextctc, nextst, 0, nextctc, next, next_state, nextctc, "Next Software Inc", "NeXT Cube turbo color", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 1148 | ||
| 1149 | /* | |
| 1150 | ||
| 1151 | UINT32 *rom = (UINT32 *)(machine.root_device().memregion("user1")->base()); | |
| 1152 | rom[0x3f48/4] = 0x2f017000; // memory test funcall | |
| 1153 | rom[0x3f4c/4] = 0x4e712400; | |
| 1154 | rom[0x00b8/4] = 0x001a4e71; // rom checksum | |
| 1155 | rom[0x00bc/4] = 0x4e714e71; | |
| 1156 | ||
| 1157 | v74 | |
| 1158 | UINT32 *rom = (UINT32 *)(machine.root_device().memregion("user1")->base()); | |
| 1159 | rom[0x329c/4] = 0x70004e71; // memory test funcall | |
| 1160 | rom[0x32a0/4] = 0x4e712400; | |
| 1161 | rom[0x03f8/4] = 0x001a4e71; // rom checksum | |
| 1162 | rom[0x03fc/4] = 0x4e714e71; | |
| 1163 | */ |
| r18419 | r18420 | |
|---|---|---|
| 23 | 23 | #include "emu.h" |
| 24 | 24 | #include "cpu/z80/z80.h" |
| 25 | 25 | #include "cpu/z80/z80daisy.h" |
| 26 | #include "formats/basicdsk.h" | |
| 26 | #include "formats/mfi_dsk.h" | |
| 27 | #include "formats/m5_dsk.h" | |
| 27 | 28 | #include "formats/sord_cas.h" |
| 28 | 29 | #include "imagedev/cartslot.h" |
| 29 | 30 | #include "imagedev/cassette.h" |
| r18419 | r18420 | |
| 211 | 212 | |
| 212 | 213 | */ |
| 213 | 214 | |
| 214 | floppy_mon_w(m_floppy0, !BIT(data, 0)); | |
| 215 | floppy_drive_set_ready_state(m_floppy0, 1, 1); | |
| 215 | m_floppy0->mon_w(!BIT(data, 0)); | |
| 216 | 216 | } |
| 217 | 217 | |
| 218 | 218 | |
| r18419 | r18420 | |
| 222 | 222 | |
| 223 | 223 | WRITE8_MEMBER( m5_state::fd5_tc_w ) |
| 224 | 224 | { |
| 225 | upd765_tc_w(m_fdc, 1); | |
| 226 | upd765_tc_w(m_fdc, 0); | |
| 225 | m_fdc->tc_w(true); | |
| 226 | m_fdc->tc_w(false); | |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | 229 | |
| r18419 | r18420 | |
| 289 | 289 | |
| 290 | 290 | static ADDRESS_MAP_START( fd5_io, AS_IO, 8, m5_state ) |
| 291 | 291 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 292 | AM_RANGE(0x00, 0x00) AM_DEVREAD_LEGACY(UPD765_TAG, upd765_status_r) | |
| 293 | AM_RANGE(0x01, 0x01) AM_DEVREADWRITE_LEGACY(UPD765_TAG, upd765_data_r, upd765_data_w) | |
| 292 | AM_RANGE(0x00, 0x01) AM_DEVICE(UPD765_TAG, upd765a_device, map) | |
| 294 | 293 | AM_RANGE(0x10, 0x10) AM_READWRITE(fd5_data_r, fd5_data_w) |
| 295 | 294 | AM_RANGE(0x20, 0x20) AM_WRITE(fd5_com_w) |
| 296 | 295 | AM_RANGE(0x30, 0x30) AM_READ(fd5_com_r) |
| r18419 | r18420 | |
| 561 | 560 | // upd765_interface fdc_intf |
| 562 | 561 | //------------------------------------------------- |
| 563 | 562 | |
| 564 | static LEGACY_FLOPPY_OPTIONS_START( m5 ) | |
| 565 | LEGACY_FLOPPY_OPTION( m5, "dsk", "Sord M5 disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 566 | HEADS([2]) | |
| 567 | TRACKS([40]) | |
| 568 | SECTORS([18]) | |
| 569 | SECTOR_LENGTH([256]) | |
| 570 | FIRST_SECTOR_ID([1])) | |
| 571 | LEGACY_FLOPPY_OPTIONS_END | |
| 572 | ||
| 573 | static const floppy_interface m5_floppy_interface = | |
| 574 | { | |
| 575 | DEVCB_NULL, | |
| 576 | DEVCB_NULL, | |
| 577 | DEVCB_NULL, | |
| 578 | DEVCB_NULL, | |
| 579 | DEVCB_NULL, | |
| 580 | FLOPPY_STANDARD_5_25_DSDD_40, | |
| 581 | LEGACY_FLOPPY_OPTIONS_NAME(m5), | |
| 582 | NULL, | |
| 563 | static const floppy_format_type m5_floppy_formats[] = { | |
| 564 | FLOPPY_M5_FORMAT, | |
| 565 | FLOPPY_MFI_FORMAT, | |
| 583 | 566 | NULL |
| 584 | 567 | }; |
| 585 | 568 | |
| 586 | static const struct upd765_interface fdc_intf = | |
| 569 | static SLOT_INTERFACE_START( m5_floppies ) | |
| 570 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 571 | SLOT_INTERFACE_END | |
| 572 | ||
| 573 | void m5_state::fdc_irq(bool state) | |
| 587 | 574 | { |
| 588 | DEVCB_CPU_INPUT_LINE(Z80_FD5_TAG, INPUT_LINE_IRQ0), | |
| 589 | DEVCB_NULL, | |
| 590 | NULL, | |
| 591 | UPD765_RDY_PIN_CONNECTED, | |
| 592 | { FLOPPY_0, NULL, NULL, NULL } | |
| 593 | }; | |
| 575 | m_fd5cpu->set_input_line(INPUT_LINE_IRQ0, state ? ASSERT_LINE : CLEAR_LINE); | |
| 576 | } | |
| 594 | 577 | |
| 595 | ||
| 596 | 578 | //------------------------------------------------- |
| 597 | 579 | // z80_daisy_config m5_daisy_chain |
| 598 | 580 | //------------------------------------------------- |
| r18419 | r18420 | |
| 631 | 613 | break; |
| 632 | 614 | } |
| 633 | 615 | |
| 616 | m_fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(m5_state::fdc_irq), this)); | |
| 617 | ||
| 634 | 618 | // register for state saving |
| 635 | 619 | save_item(NAME(m_fd5_data)); |
| 636 | 620 | save_item(NAME(m_fd5_com)); |
| r18419 | r18420 | |
| 680 | 664 | MCFG_CENTRONICS_PRINTER_ADD(CENTRONICS_TAG, standard_centronics) |
| 681 | 665 | MCFG_CASSETTE_ADD(CASSETTE_TAG, cassette_intf) |
| 682 | 666 | MCFG_I8255_ADD(I8255A_TAG, ppi_intf) |
| 683 | MCFG_UPD765A_ADD(UPD765_TAG, fdc_intf) | |
| 684 | MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, m5_floppy_interface) | |
| 667 | MCFG_UPD765A_ADD(UPD765_TAG, true, true) | |
| 668 | MCFG_FLOPPY_DRIVE_ADD(UPD765_TAG ":0", m5_floppies, "525dd", 0, m5_floppy_formats) | |
| 685 | 669 | |
| 686 | 670 | // cartridge |
| 687 | 671 | MCFG_CARTSLOT_ADD("cart") |
| r18419 | r18420 | |
|---|---|---|
| 55 | 55 | RAM : between 1MB and 4MB stock, expandable to 12MB |
| 56 | 56 | |
| 57 | 57 | FDD : 2x 5.25", Compact models use 2x 3.5" drives. |
| 58 | FDC : NEC uPD72065 | |
| 58 | FDC : NEC uPD72065 | |
| 59 | 59 | |
| 60 | 60 | HDD : HD models have up to an 81MB HDD. |
| 61 | 61 | HDC : Fujitsu MB89352A (SCSI) |
| r18419 | r18420 | |
| 76 | 76 | |
| 77 | 77 | |
| 78 | 78 | *** Current status (28/12/08) |
| 79 | FDC/FDD : Uses the uPD765A code with a small patch to handle Sense Interrupt Status being invalid if not in seek mode | |
| 80 | Extra uPD72065 commands not yet implemented, although I have yet to see them used. | |
| 81 | ||
| 82 | 79 | MFP : Largely works, as far as the X68000 goes. |
| 83 | 80 | |
| 84 | 81 | PPI : Joystick controls work okay. |
| r18419 | r18420 | |
| 129 | 126 | #include "machine/rp5c15.h" |
| 130 | 127 | #include "machine/mb89352.h" |
| 131 | 128 | #include "imagedev/flopdrv.h" |
| 132 | #include "formats/basicdsk.h" | |
| 129 | #include "formats/mfi_dsk.h" | |
| 130 | #include "formats/xdf_dsk.h" | |
| 133 | 131 | #include "formats/dim_dsk.h" |
| 134 | 132 | #include "machine/x68k_hdc.h" |
| 135 | 133 | #include "includes/x68k.h" |
| r18419 | r18420 | |
| 944 | 942 | // NEC uPD72065 at 0xe94000 |
| 945 | 943 | WRITE16_MEMBER(x68k_state::x68k_fdc_w) |
| 946 | 944 | { |
| 947 | device_t *fdc = machine().device("upd72065"); | |
| 948 | 945 | unsigned int drive, x; |
| 949 | 946 | switch(offset) |
| 950 | 947 | { |
| 951 | case 0x00: | |
| 952 | case 0x01: | |
| 953 | upd765_data_w(fdc, space, 0,data); | |
| 954 | break; | |
| 955 | case 0x02: // drive option signal control | |
| 948 | case 0x00: // drive option signal control | |
| 956 | 949 | x = data & 0x0f; |
| 957 | 950 | for(drive=0;drive<4;drive++) |
| 958 | 951 | { |
| r18419 | r18420 | |
| 965 | 958 | output_set_indexed_value("eject_drv",drive,(data & 0x40) ? 1 : 0); |
| 966 | 959 | if(data & 0x20) // ejects disk |
| 967 | 960 | { |
| 968 | (dynamic_cast<device_image_interface *>(floppy_get_device(machine(), drive)))->unload(); | |
| 969 | floppy_mon_w(floppy_get_device(machine(), drive), ASSERT_LINE); | |
| 961 | m_fdc.floppy[drive]->mon_w(false); | |
| 962 | m_fdc.floppy[drive]->unload(); | |
| 970 | 963 | } |
| 971 | 964 | } |
| 972 | 965 | } |
| r18419 | r18420 | |
| 974 | 967 | m_fdc.selected_drive = data & 0x0f; |
| 975 | 968 | logerror("FDC: signal control set to %02x\n",data); |
| 976 | 969 | break; |
| 977 | case 0x03: | |
| 978 | m_fdc.media_density[data & 0x03] = data & 0x10; | |
| 970 | case 0x01: { | |
| 971 | static const int rates[4] = { 500000, 300000, 250000, 125000 }; | |
| 972 | m_fdc.fdc->set_rate(rates[(data >> 4) & 3]); | |
| 979 | 973 | m_fdc.motor[data & 0x03] = data & 0x80; |
| 980 | | |
| 974 | m_fdc.floppy[data & 0x03]->mon_w(!BIT(data, 7)); | |
| 981 | 975 | if(data & 0x80) |
| 982 | 976 | { |
| 983 | 977 | for(drive=0;drive<4;drive++) // enable motor for this drive |
| 984 | 978 | { |
| 985 | 979 | if(drive == (data & 0x03)) |
| 986 | 980 | { |
| 987 | floppy | |
| 981 | m_fdc.floppy[drive]->mon_w(false); | |
| 988 | 982 | output_set_indexed_value("access_drv",drive,0); |
| 989 | 983 | } |
| 990 | 984 | else |
| r18419 | r18420 | |
| 995 | 989 | { |
| 996 | 990 | for(drive=0;drive<4;drive++) |
| 997 | 991 | { |
| 998 | | |
| 992 | m_fdc.floppy[drive]->mon_w(true); | |
| 999 | 993 | output_set_indexed_value("access_drv",drive,1); |
| 1000 | 994 | } |
| 1001 | 995 | } |
| 1002 | floppy_drive_set_ready_state(floppy_get_device(machine(), 0),1,1); | |
| 1003 | floppy_drive_set_ready_state(floppy_get_device(machine(), 1),1,1); | |
| 1004 | floppy_drive_set_ready_state(floppy_get_device(machine(), 2),1,1); | |
| 1005 | floppy_drive_set_ready_state(floppy_get_device(machine(), 3),1,1); | |
| 1006 | #if 0 | |
| 1007 | for(drive=0;drive<4;drive++) | |
| 1008 | { | |
| 1009 | if(floppy_drive_get_flag_state(floppy_get_device(machine, drive),FLOPPY_DRIVE_MOTOR_ON)) | |
| 1010 | output_set_indexed_value("access_drv",drive,0); | |
| 1011 | else | |
| 1012 | output_set_indexed_value("access_drv",drive,1); | |
| 1013 | } | |
| 1014 | #endif | |
| 1015 | 996 | logerror("FDC: Drive #%i: Drive selection set to %02x\n",data & 0x03,data); |
| 1016 | 997 | break; |
| 1017 | default: | |
| 1018 | // logerror("FDC: [%08x] Wrote %04x to invalid FDC port %04x\n",space.device().safe_pc(),data,offset); | |
| 1019 | break; | |
| 1020 | 998 | } |
| 999 | } | |
| 1021 | 1000 | } |
| 1022 | 1001 | |
| 1023 | 1002 | READ16_MEMBER(x68k_state::x68k_fdc_r) |
| 1024 | 1003 | { |
| 1025 | 1004 | unsigned int ret; |
| 1026 | 1005 | int x; |
| 1027 | device_t *fdc = machine().device("upd72065"); | |
| 1028 | 1006 | |
| 1029 | 1007 | switch(offset) |
| 1030 | 1008 | { |
| 1031 | 1009 | case 0x00: |
| 1032 | return upd765_status_r(fdc, space, 0); | |
| 1033 | case 0x01: | |
| 1034 | return upd765_data_r(fdc, space, 0); | |
| 1035 | case 0x02: | |
| 1036 | 1010 | ret = 0x00; |
| 1037 | 1011 | for(x=0;x<4;x++) |
| 1038 | 1012 | { |
| 1039 | 1013 | if(m_fdc.selected_drive & (1 << x)) |
| 1040 | 1014 | { |
| 1041 | 1015 | ret = 0x00; |
| 1042 | if(m_fdc. | |
| 1016 | if(m_fdc.floppy[x]->exists()) | |
| 1043 | 1017 | { |
| 1044 | 1018 | ret |= 0x80; |
| 1045 | 1019 | } |
| r18419 | r18420 | |
| 1049 | 1023 | } |
| 1050 | 1024 | } |
| 1051 | 1025 | return ret; |
| 1052 | case 0x0 | |
| 1026 | case 0x01: | |
| 1053 | 1027 | logerror("FDC: IOC selection is write-only\n"); |
| 1054 | 1028 | return 0xff; |
| 1055 | default: | |
| 1056 | logerror("FDC: Read from invalid FDC port %04x\n",offset); | |
| 1057 | return 0xff; | |
| 1058 | 1029 | } |
| 1030 | return 0xff; | |
| 1059 | 1031 | } |
| 1060 | 1032 | |
| 1061 | ||
| 1033 | void x68k_state::fdc_irq(bool state) | |
| 1062 | 1034 | { |
| 1063 | if((m_ioc.irqstatus & 0x04) && state | |
| 1035 | if((m_ioc.irqstatus & 0x04) && state) | |
| 1064 | 1036 | { |
| 1065 | 1037 | m_current_vector[1] = m_ioc.fdcvector; |
| 1066 | 1038 | m_ioc.irqstatus |= 0x80; |
| r18419 | r18420 | |
| 1073 | 1045 | static int x68k_fdc_read_byte(running_machine &machine,int addr) |
| 1074 | 1046 | { |
| 1075 | 1047 | x68k_state *state = machine.driver_data<x68k_state>(); |
| 1076 | int data = -1; | |
| 1077 | device_t *fdc = machine.device("upd72065"); | |
| 1078 | ||
| 1079 | if(state->m_fdc.drq_state != 0) | |
| 1080 | data = upd765_dack_r(fdc, state->generic_space(), 0); | |
| 1081 | // logerror("FDC: DACK reading\n"); | |
| 1082 | return data; | |
| 1048 | return state->m_fdc.fdc->dma_r(); | |
| 1083 | 1049 | } |
| 1084 | 1050 | |
| 1085 | 1051 | static void x68k_fdc_write_byte(running_machine &machine,int addr, int data) |
| 1086 | 1052 | { |
| 1087 | device_t *fdc = machine.device("upd72065"); | |
| 1088 | upd765_dack_w(fdc, machine.driver_data()->generic_space(), 0, data); | |
| 1053 | x68k_state *state = machine.driver_data<x68k_state>(); | |
| 1054 | return state->m_fdc.fdc->dma_w(data); | |
| 1089 | 1055 | } |
| 1090 | 1056 | |
| 1091 | ||
| 1057 | void x68k_state::fdc_drq(bool state) | |
| 1092 | 1058 | { |
| 1093 | 1059 | m_fdc.drq_state = state; |
| 1094 | 1060 | } |
| r18419 | r18420 | |
| 1114 | 1080 | |
| 1115 | 1081 | WRITE8_MEMBER(x68k_state::x68k_ct_w) |
| 1116 | 1082 | { |
| 1117 | device_t *fdc = machine().device("upd72065"); | |
| 1118 | device_t *okim = machine().device("okim6258"); | |
| 1083 | device_t *okim = space.machine().device("okim6258"); | |
| 1119 | 1084 | |
| 1120 | 1085 | // CT1 and CT2 bits from YM2151 port 0x1b |
| 1121 | 1086 | // CT1 - ADPCM clock - 0 = 8MHz, 1 = 4MHz |
| 1122 | 1087 | // CT2 - 1 = Set ready state of FDC |
| 1123 | | |
| 1088 | m_fdc.fdc->ready_w(data & 0x01); | |
| 1124 | 1089 | m_adpcm.clock = data & 0x02; |
| 1125 | 1090 | x68k_set_adpcm(); |
| 1126 | 1091 | okim6258_set_clock(okim, data & 0x02 ? 4000000 : 8000000); |
| r18419 | r18420 | |
| 1923 | 1888 | AM_RANGE(0xe90000, 0xe91fff) AM_READWRITE(x68k_fm_r, x68k_fm_w) |
| 1924 | 1889 | AM_RANGE(0xe92000, 0xe92001) AM_DEVREADWRITE8_LEGACY("okim6258", okim6258_status_r, okim6258_ctrl_w, 0x00ff) |
| 1925 | 1890 | AM_RANGE(0xe92002, 0xe92003) AM_DEVREADWRITE8_LEGACY("okim6258", okim6258_status_r, okim6258_data_w, 0x00ff) |
| 1926 | AM_RANGE(0xe94000, 0xe95fff) AM_READWRITE(x68k_fdc_r, x68k_fdc_w) | |
| 1891 | AM_RANGE(0xe94000, 0xe94003) AM_DEVICE8("upd72065", upd72065_device, map, 0x00ff) | |
| 1892 | AM_RANGE(0xe94004, 0xe94007) AM_READWRITE(x68k_fdc_r, x68k_fdc_w) | |
| 1927 | 1893 | AM_RANGE(0xe96000, 0xe9601f) AM_DEVREADWRITE("x68k_hdc", x68k_hdc_image_device, hdc_r, hdc_w) |
| 1928 | 1894 | AM_RANGE(0xe98000, 0xe99fff) AM_READWRITE(x68k_scc_r, x68k_scc_w) |
| 1929 | 1895 | AM_RANGE(0xe9a000, 0xe9bfff) AM_READWRITE(x68k_ppi_r, x68k_ppi_w) |
| r18419 | r18420 | |
| 1960 | 1926 | AM_RANGE(0xe90000, 0xe91fff) AM_READWRITE(x68k_fm_r, x68k_fm_w) |
| 1961 | 1927 | AM_RANGE(0xe92000, 0xe92001) AM_DEVREADWRITE8_LEGACY("okim6258", okim6258_status_r, okim6258_ctrl_w, 0x00ff) |
| 1962 | 1928 | AM_RANGE(0xe92002, 0xe92003) AM_DEVREADWRITE8_LEGACY("okim6258", okim6258_status_r, okim6258_data_w, 0x00ff) |
| 1963 | AM_RANGE(0xe94000, 0xe95fff) AM_READWRITE(x68k_fdc_r, x68k_fdc_w) | |
| 1929 | AM_RANGE(0xe94000, 0xe94003) AM_DEVICE8("upd72065", upd72065_device, map, 0x00ff) | |
| 1930 | AM_RANGE(0xe94004, 0xe94007) AM_READWRITE(x68k_fdc_r, x68k_fdc_w) | |
| 1964 | 1931 | // AM_RANGE(0xe96000, 0xe9601f) AM_DEVREADWRITE_LEGACY("x68k_hdc",x68k_hdc_r, x68k_hdc_w) |
| 1965 | 1932 | AM_RANGE(0xe96020, 0xe9603f) AM_DEVREADWRITE8("scsi:mb89352",mb89352_device,mb89352_r,mb89352_w,0x00ff) |
| 1966 | 1933 | AM_RANGE(0xe98000, 0xe99fff) AM_READWRITE(x68k_scc_r, x68k_scc_w) |
| r18419 | r18420 | |
| 1998 | 1965 | AM_RANGE(0xe8e000, 0xe8ffff) AM_READWRITE16(x68k_sysport_r, x68k_sysport_w,0xffffffff) |
| 1999 | 1966 | AM_RANGE(0xe90000, 0xe91fff) AM_READWRITE16(x68k_fm_r, x68k_fm_w,0xffffffff) |
| 2000 | 1967 | AM_RANGE(0xe92000, 0xe92003) AM_DEVREAD8_LEGACY("okim6258", okim6258_status_r, 0x00ff00ff) AM_WRITE8(x68030_adpcm_w, 0x00ff00ff) |
| 2001 | AM_RANGE(0xe94000, 0xe95fff) AM_READWRITE16(x68k_fdc_r, x68k_fdc_w,0xffffffff) | |
| 1968 | AM_RANGE(0xe94000, 0xe94003) AM_DEVICE8("upd72065", upd72065_device, map, 0x00ff00ff) | |
| 1969 | AM_RANGE(0xe94004, 0xe94007) AM_READWRITE16(x68k_fdc_r, x68k_fdc_w,0xffffffff) | |
| 2002 | 1970 | // AM_RANGE(0xe96000, 0xe9601f) AM_DEVREADWRITE16_LEGACY("x68k_hdc",x68k_hdc_r, x68k_hdc_w,0xffffffff) |
| 2003 | 1971 | AM_RANGE(0xe96020, 0xe9603f) AM_DEVREADWRITE8("scsi:mb89352",mb89352_device,mb89352_r,mb89352_w,0x00ff00ff) |
| 2004 | 1972 | AM_RANGE(0xe98000, 0xe99fff) AM_READWRITE16(x68k_scc_r, x68k_scc_w,0xffffffff) |
| r18419 | r18420 | |
| 2065 | 2033 | // { 0, 0, 0, 0 } |
| 2066 | 2034 | }; |
| 2067 | 2035 | |
| 2068 | static const upd765_interface fdc_interface = | |
| 2069 | { | |
| 2070 | DEVCB_DRIVER_LINE_MEMBER(x68k_state,fdc_irq), | |
| 2071 | DEVCB_DRIVER_LINE_MEMBER(x68k_state,fdc_drq), | |
| 2072 | NULL, | |
| 2073 | UPD765_RDY_PIN_CONNECTED, | |
| 2074 | {FLOPPY_0,FLOPPY_1,FLOPPY_2,FLOPPY_3} | |
| 2075 | }; | |
| 2076 | ||
| 2077 | 2036 | static const ym2151_interface x68k_ym2151_interface = |
| 2078 | 2037 | { |
| 2079 | 2038 | DEVCB_DRIVER_LINE_MEMBER(x68k_state,x68k_fm_irq), |
| r18419 | r18420 | |
| 2400 | 2359 | |
| 2401 | 2360 | INPUT_PORTS_END |
| 2402 | 2361 | |
| 2403 | ||
| 2362 | void x68k_state::floppy_load_unload() | |
| 2404 | 2363 | { |
| 2405 | x68k_state *state = image.device().machine().driver_data<x68k_state>(); | |
| 2406 | if(state->m_ioc.irqstatus & 0x02) | |
| 2364 | if(m_ioc.irqstatus & 0x02) | |
| 2407 | 2365 | { |
| 2408 | state->m_current_vector[1] = 0x61; | |
| 2409 | state->m_ioc.irqstatus |= 0x40; | |
| 2410 | state->m_current_irq_line = 1; | |
| 2411 | image.device().machine().device("maincpu")->execute().set_input_line_and_vector(1,ASSERT_LINE,state->m_current_vector[1]); // Disk insert/eject interrupt | |
| 2366 | m_current_vector[1] = 0x61; | |
| 2367 | m_ioc.irqstatus |= 0x40; | |
| 2368 | m_current_irq_line = 1; | |
| 2369 | machine().device("maincpu")->execute().set_input_line_and_vector(1,ASSERT_LINE,m_current_vector[1]); // Disk insert/eject interrupt | |
| 2412 | 2370 | logerror("IOC: Disk image inserted\n"); |
| 2413 | 2371 | } |
| 2414 | state->m_fdc.disk_inserted[floppy_get_drive(&image.device())] = 1; | |
| 2415 | 2372 | } |
| 2416 | 2373 | |
| 2417 | ||
| 2374 | int x68k_state::floppy_load(floppy_image_device *dev) | |
| 2418 | 2375 | { |
| 2419 | x68k_state *state = image.device().machine().driver_data<x68k_state>(); | |
| 2420 | if(state->m_ioc.irqstatus & 0x02) | |
| 2421 | { | |
| 2422 | state->m_current_vector[1] = 0x61; | |
| 2423 | state->m_ioc.irqstatus |= 0x40; | |
| 2424 | state->m_current_irq_line = 1; | |
| 2425 | image.device().machine().device("maincpu")->execute().set_input_line_and_vector(1,ASSERT_LINE,state->m_current_vector[1]); // Disk insert/eject interrupt | |
| 2426 | } | |
| 2427 | state->m_fdc.disk_inserted[floppy_get_drive(&image.device())] = 0; | |
| 2376 | floppy_load_unload(); | |
| 2377 | return IMAGE_INIT_PASS; | |
| 2428 | 2378 | } |
| 2429 | 2379 | |
| 2380 | void x68k_state::floppy_unload(floppy_image_device *dev) | |
| 2381 | { | |
| 2382 | floppy_load_unload(); | |
| 2383 | } | |
| 2384 | ||
| 2430 | 2385 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_net_irq) |
| 2431 | 2386 | { |
| 2432 | 2387 | |
| r18419 | r18420 | |
| 2447 | 2402 | |
| 2448 | 2403 | } |
| 2449 | 2404 | |
| 2450 | static LEGACY_FLOPPY_OPTIONS_START( x68k ) | |
| 2451 | LEGACY_FLOPPY_OPTION( img2d, "xdf,hdm,2hd", "XDF disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 2452 | HEADS([2]) | |
| 2453 | TRACKS([77]) | |
| 2454 | SECTORS([8]) | |
| 2455 | SECTOR_LENGTH([1024]) | |
| 2456 | FIRST_SECTOR_ID([1])) | |
| 2457 | LEGACY_FLOPPY_OPTION( dim, "dim", "DIM floppy disk image", dim_dsk_identify, dim_dsk_construct, NULL, NULL) | |
| 2458 | LEGACY_FLOPPY_OPTIONS_END | |
| 2459 | ||
| 2460 | ||
| 2461 | static const floppy_interface x68k_floppy_interface = | |
| 2462 | { | |
| 2463 | DEVCB_NULL, | |
| 2464 | DEVCB_NULL, | |
| 2465 | DEVCB_NULL, | |
| 2466 | DEVCB_NULL, | |
| 2467 | DEVCB_NULL, | |
| 2468 | FLOPPY_STANDARD_5_25_DSHD, | |
| 2469 | LEGACY_FLOPPY_OPTIONS_NAME(x68k), | |
| 2470 | "floppy_5_25", | |
| 2471 | NULL | |
| 2472 | }; | |
| 2473 | ||
| 2474 | 2405 | static const mb89352_interface x68k_scsi_intf = |
| 2475 | 2406 | { |
| 2476 | 2407 | DEVCB_DRIVER_LINE_MEMBER(x68k_state,x68k_scsi_irq), |
| r18419 | r18420 | |
| 2507 | 2438 | m_keyboard.delay = 500; // 3*100+200 |
| 2508 | 2439 | m_keyboard.repeat = 110; // 4^2*5+30 |
| 2509 | 2440 | |
| 2510 | // check for disks | |
| 2511 | for(drive=0;drive<4;drive++) | |
| 2512 | { | |
| 2513 | device_image_interface *image = dynamic_cast<device_image_interface *>(floppy_get_device(machine(), drive)); | |
| 2514 | if(image->exists()) | |
| 2515 | m_fdc.disk_inserted[drive] = 1; | |
| 2516 | else | |
| 2517 | m_fdc.disk_inserted[drive] = 0; | |
| 2518 | } | |
| 2519 | ||
| 2520 | 2441 | // initialise CRTC, set registers to defaults for the standard text mode (768x512) |
| 2521 | 2442 | m_crtc.reg[0] = 137; // Horizontal total (in characters) |
| 2522 | 2443 | m_crtc.reg[1] = 14; // Horizontal sync end |
| r18419 | r18420 | |
| 2555 | 2476 | output_set_indexed_value("eject_drv",drive,1); |
| 2556 | 2477 | output_set_indexed_value("ctrl_drv",drive,1); |
| 2557 | 2478 | output_set_indexed_value("access_drv",drive,1); |
| 2558 | floppy_install_unload_proc(floppy_get_device(machine(), drive), x68k_unload_proc); | |
| 2559 | floppy_install_load_proc(floppy_get_device(machine(), drive), x68k_load_proc); | |
| 2560 | 2479 | } |
| 2561 | 2480 | |
| 2562 | 2481 | // reset CPU |
| r18419 | r18420 | |
| 2591 | 2510 | |
| 2592 | 2511 | // start LED timer |
| 2593 | 2512 | m_led_timer->adjust(attotime::zero, 0, attotime::from_msec(400)); |
| 2513 | ||
| 2514 | // check for disks | |
| 2515 | m_fdc.fdc = machine().device<upd72065_device>("upd72065"); | |
| 2516 | m_fdc.fdc->setup_intrq_cb(upd72065_device::line_cb(FUNC(x68k_state::fdc_irq), this)); | |
| 2517 | m_fdc.fdc->setup_drq_cb(upd72065_device::line_cb(FUNC(x68k_state::fdc_drq), this)); | |
| 2518 | ||
| 2519 | for(int drive=0;drive<4;drive++) | |
| 2520 | { | |
| 2521 | char devname[16]; | |
| 2522 | sprintf(devname, "upd72065:%d", drive); | |
| 2523 | floppy_image_device *floppy = machine().device<floppy_connector>(devname)->get_device(); | |
| 2524 | m_fdc.floppy[drive] = floppy; | |
| 2525 | if(floppy) { | |
| 2526 | floppy->setup_load_cb(floppy_image_device::load_cb(FUNC(x68k_state::floppy_load), this)); | |
| 2527 | floppy->setup_unload_cb(floppy_image_device::unload_cb(FUNC(x68k_state::floppy_unload), this)); | |
| 2528 | } | |
| 2529 | } | |
| 2594 | 2530 | } |
| 2595 | 2531 | |
| 2596 | 2532 | MACHINE_START_MEMBER(x68k_state,x68030) |
| r18419 | r18420 | |
| 2621 | 2557 | |
| 2622 | 2558 | // start LED timer |
| 2623 | 2559 | m_led_timer->adjust(attotime::zero, 0, attotime::from_msec(400)); |
| 2560 | ||
| 2561 | // check for disks | |
| 2562 | m_fdc.fdc = machine().device<upd72065_device>("upd72065"); | |
| 2563 | m_fdc.fdc->setup_intrq_cb(upd72065_device::line_cb(FUNC(x68k_state::fdc_irq), this)); | |
| 2564 | m_fdc.fdc->setup_drq_cb(upd72065_device::line_cb(FUNC(x68k_state::fdc_drq), this)); | |
| 2565 | ||
| 2566 | for(int drive=0;drive<4;drive++) | |
| 2567 | { | |
| 2568 | char devname[16]; | |
| 2569 | sprintf(devname, "upd72065:%d", drive); | |
| 2570 | floppy_image_device *floppy = machine().device<floppy_connector>(devname)->get_device(); | |
| 2571 | m_fdc.floppy[drive] = floppy; | |
| 2572 | if(floppy) { | |
| 2573 | floppy->setup_load_cb(floppy_image_device::load_cb(FUNC(x68k_state::floppy_load), this)); | |
| 2574 | floppy->setup_unload_cb(floppy_image_device::unload_cb(FUNC(x68k_state::floppy_unload), this)); | |
| 2575 | } | |
| 2576 | } | |
| 2624 | 2577 | } |
| 2625 | 2578 | |
| 2626 | 2579 | DRIVER_INIT_MEMBER(x68k_state,x68000) |
| r18419 | r18420 | |
| 2680 | 2633 | m_is_32bit = true; |
| 2681 | 2634 | } |
| 2682 | 2635 | |
| 2636 | static const floppy_format_type x68k_floppy_formats[] = { | |
| 2637 | FLOPPY_XDF_FORMAT, | |
| 2638 | FLOPPY_MFI_FORMAT, | |
| 2639 | NULL | |
| 2640 | }; | |
| 2641 | ||
| 2642 | static SLOT_INTERFACE_START( x68k_floppies ) | |
| 2643 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 2644 | SLOT_INTERFACE_END | |
| 2645 | ||
| 2683 | 2646 | static MACHINE_CONFIG_FRAGMENT( x68000_base ) |
| 2684 | 2647 | /* basic machine hardware */ |
| 2685 | 2648 | MCFG_CPU_ADD("maincpu", M68000, 10000000) /* 10 MHz */ |
| r18419 | r18420 | |
| 2728 | 2691 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.50) |
| 2729 | 2692 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.50) |
| 2730 | 2693 | |
| 2731 | MCFG_UPD72065_ADD("upd72065", fdc_interface) | |
| 2732 | MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(x68k_floppy_interface) | |
| 2694 | MCFG_UPD72065_ADD("upd72065", true, true) | |
| 2695 | MCFG_FLOPPY_DRIVE_ADD("upd72065:0", x68k_floppies, "525hd", 0, x68k_floppy_formats) | |
| 2696 | MCFG_FLOPPY_DRIVE_ADD("upd72065:1", x68k_floppies, "525hd", 0, x68k_floppy_formats) | |
| 2697 | MCFG_FLOPPY_DRIVE_ADD("upd72065:2", x68k_floppies, "525hd", 0, x68k_floppy_formats) | |
| 2698 | MCFG_FLOPPY_DRIVE_ADD("upd72065:3", x68k_floppies, "525hd", 0, x68k_floppy_formats) | |
| 2699 | ||
| 2733 | 2700 | MCFG_SOFTWARE_LIST_ADD("flop_list","x68k_flop") |
| 2734 | 2701 | |
| 2735 | 2702 | MCFG_X68K_EXPANSION_SLOT_ADD("exp",x68k_exp_intf,x68000_exp_cards,NULL,NULL) |
| r18419 | r18420 | |
|---|---|---|
| 104 | 104 | #include "machine/upd765.h" /* for NC200 disk drive interface */ |
| 105 | 105 | #include "imagedev/flopdrv.h" /* for NC200 disk image */ |
| 106 | 106 | #include "formats/pc_dsk.h" /* for NC200 disk image */ |
| 107 | #include "formats/mfi_dsk.h" | |
| 107 | 108 | #include "imagedev/cartslot.h" |
| 108 | 109 | #include "sound/beep.h" |
| 109 | 110 | #include "machine/ram.h" |
| r18419 | r18420 | |
| 1257 | 1258 | }; |
| 1258 | 1259 | |
| 1259 | 1260 | |
| 1260 | ||
| 1261 | void nc_state::nc200_fdc_interrupt(bool state) | |
| 1261 | 1262 | { |
| 1262 | 1263 | #if 0 |
| 1263 | 1264 | m_irq_latch &=~(1<<5); |
| r18419 | r18420 | |
| 1277 | 1278 | nc_update_interrupts(machine()); |
| 1278 | 1279 | } |
| 1279 | 1280 | |
| 1280 | static const upd765_interface nc200_upd765_interface= | |
| 1281 | { | |
| 1282 | DEVCB_DRIVER_LINE_MEMBER(nc_state,nc200_fdc_interrupt), | |
| 1283 | DEVCB_NULL, | |
| 1284 | NULL, | |
| 1285 | UPD765_RDY_PIN_CONNECTED, | |
| 1286 | {FLOPPY_0, NULL, NULL, NULL } | |
| 1287 | }; | |
| 1288 | ||
| 1289 | 1281 | #ifdef UNUSED_FUNCTION |
| 1290 | 1282 | static void nc200_floppy_drive_index_callback(int drive_id) |
| 1291 | 1283 | { |
| r18419 | r18420 | |
| 1339 | 1331 | |
| 1340 | 1332 | /* serial timer */ |
| 1341 | 1333 | m_serial_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nc_state::nc_serial_timer_callback),this)); |
| 1334 | machine().device<upd765a_device>("upd765")->setup_intrq_cb(upd765a_device::line_cb(FUNC(nc_state::nc200_fdc_interrupt), this)); | |
| 1342 | 1335 | } |
| 1343 | 1336 | |
| 1344 | 1337 | /* |
| r18419 | r18420 | |
| 1432 | 1425 | |
| 1433 | 1426 | WRITE8_MEMBER(nc_state::nc200_memory_card_wait_state_w) |
| 1434 | 1427 | { |
| 1435 | device | |
| 1428 | upd765a_device *fdc = machine().device<upd765a_device>("upd765"); | |
| 1436 | 1429 | LOG_DEBUG(("nc200 memory card wait state: PC: %04x %02x\n", machine().device("maincpu")->safe_pc(), data)); |
| 1437 | 1430 | #if 0 |
| 1438 | 1431 | floppy_drive_set_motor_state(0, 1); |
| 1439 | 1432 | floppy_drive_set_ready_state(0, 1, 1); |
| 1440 | 1433 | #endif |
| 1441 | | |
| 1434 | fdc->tc_w(data & 0x01); | |
| 1442 | 1435 | } |
| 1443 | 1436 | |
| 1444 | 1437 | /* bit 2: backlight: 1=off, 0=on */ |
| r18419 | r18420 | |
| 1468 | 1461 | AM_RANGE(0xc0, 0xc0) AM_DEVREADWRITE("uart",i8251_device, data_r, data_w) |
| 1469 | 1462 | AM_RANGE(0xc1, 0xc1) AM_DEVREADWRITE("uart", i8251_device, status_r, control_w) |
| 1470 | 1463 | AM_RANGE(0xd0, 0xd1) AM_DEVREADWRITE("mc", mc146818_device, read, write) |
| 1471 | AM_RANGE(0xe0, 0xe0) AM_DEVREAD_LEGACY("upd765", upd765_status_r) | |
| 1472 | AM_RANGE(0xe1, 0xe1) AM_DEVREADWRITE_LEGACY("upd765",upd765_data_r, upd765_data_w) | |
| 1464 | AM_RANGE(0xe0, 0xe1) AM_DEVICE("upd765", upd765a_device, map) | |
| 1473 | 1465 | ADDRESS_MAP_END |
| 1474 | 1466 | |
| 1475 | 1467 | static INPUT_PORTS_START(nc200) |
| r18419 | r18420 | |
| 1636 | 1628 | MCFG_TIMER_DRIVER_ADD_PERIODIC("dummy_timer", nc_state, dummy_timer_callback, attotime::from_hz(50)) |
| 1637 | 1629 | MACHINE_CONFIG_END |
| 1638 | 1630 | |
| 1639 | static const floppy_interface nc200_floppy_interface = | |
| 1640 | { | |
| 1641 | DEVCB_NULL, | |
| 1642 | DEVCB_NULL, | |
| 1643 | DEVCB_NULL, | |
| 1644 | DEVCB_NULL, | |
| 1645 | DEVCB_NULL, | |
| 1646 | FLOPPY_STANDARD_5_25_DSHD, | |
| 1647 | LEGACY_FLOPPY_OPTIONS_NAME(pc), | |
| 1648 | NULL, | |
| 1631 | static const floppy_format_type ibmpc_floppy_formats[] = { | |
| 1632 | FLOPPY_PC_FORMAT, | |
| 1633 | FLOPPY_MFI_FORMAT, | |
| 1649 | 1634 | NULL |
| 1650 | 1635 | }; |
| 1651 | 1636 | |
| 1637 | static SLOT_INTERFACE_START( ibmpc_floppies ) | |
| 1638 | SLOT_INTERFACE( "525dd", FLOPPY_525_DD ) | |
| 1639 | SLOT_INTERFACE_END | |
| 1640 | ||
| 1652 | 1641 | static MACHINE_CONFIG_DERIVED( nc200, nc100 ) |
| 1653 | 1642 | |
| 1654 | 1643 | MCFG_CPU_MODIFY( "maincpu" ) |
| r18419 | r18420 | |
| 1674 | 1663 | /* no rtc */ |
| 1675 | 1664 | MCFG_DEVICE_REMOVE("rtc") |
| 1676 | 1665 | |
| 1677 | MCFG_UPD765A_ADD("upd765", nc200_upd765_interface) | |
| 1666 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 1667 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1668 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", ibmpc_floppies, "525dd", 0, ibmpc_floppy_formats) | |
| 1678 | 1669 | |
| 1679 | MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, nc200_floppy_interface) | |
| 1680 | ||
| 1681 | 1670 | MCFG_MC146818_ADD( "mc", MC146818_STANDARD ) |
| 1682 | 1671 | |
| 1683 | 1672 | /* internal ram */ |
| r18419 | r18420 | |
|---|---|---|
| 83 | 83 | IBM Roms thanks to Frode |
| 84 | 84 | ========================= |
| 85 | 85 | |
| 86 | 1504036.bin: IBM 4860 PC/jr BIOS. vissible in memory at F0000-F7FFF. | |
| 87 | 1504037.bin: IBM 4860 PC/jr BIOS. vissible in memory at F8000-FFFFF. | |
| 86 | 1504036.bin: IBM 4860 PC/jr BIOS. visible in memory at F0000-F7FFF. | |
| 87 | 1504037.bin: IBM 4860 PC/jr BIOS. visible in memory at F8000-FFFFF. | |
| 88 | 88 | |
| 89 | 89 | ROM_LOAD( "1504036.bin", 0xf0000, 0x8000, CRC(de8fa668) SHA1(459341e033be1199c107e56d33680170e144b689)) |
| 90 | 90 | ROM_LOAD( "1504037.bin", 0xf8000, 0x8000, CRC(04c05f17) SHA1(319423cb6bb02b399ecf6e0cb82015c16ada68f5)) |
| 91 | 91 | |
| 92 | 5601JDA.bin: IBM 5511 PC/JX BIOS. vis | |
| 92 | 5601JDA.bin: IBM 5511 PC/JX BIOS. visible in memory at F0000-FFFFF. | |
| 93 | 93 | ROM_LOAD( "5601jda.bin", 0xf0000, 0x10000, CRC(b1e12366) SHA1(751feb16b985aa4f1ec1437493ff77e2ebd5e6a6)) |
| 94 | 94 | |
| 95 | 7396917.bin: IBM 5140 PC/Convertible BIOS. vissible in memory at F0000-F7FFF. | |
| 96 | 7396918.bin: IBM 5140 PC/Convertible BIOS. vissible in memory at F8000-FFFFF. | |
| 95 | 7396917.bin: IBM 5140 PC/Convertible BIOS. visible in memory at F0000-F7FFF. | |
| 96 | 7396918.bin: IBM 5140 PC/Convertible BIOS. visible in memory at F8000-FFFFF. | |
| 97 | 97 | ROM_LOAD( "7396917.bin", 0xf0000, 0x8000, CRC(95c35652) SHA1(2bdac30715dba114fbe0895b8b4723f8dc26a90d)) |
| 98 | 98 | ROM_LOAD( "7396918.bin", 0xf8000, 0x8000, CRC(1b4202b0) SHA1(4797ff853ba1675860f293b6368832d05e2f3ea9)) |
| 99 | 99 | |
| 100 | 5700019.bin: IBM 5150 PC BASIC 1.0. vissible in memory at F6000-F7FFF. | |
| 101 | 5700027.bin: IBM 5150 PC BASIC 1.0. vissible in memory at F8000-F9FFF. | |
| 102 | 5700035.bin: IBM 5150 PC BASIC 1.0. vissible in memory at FA000-FBFFF. | |
| 103 | 5700043.bin: IBM 5150 PC BASIC 1.0. vissible in memory at FC000-FDFFF. | |
| 100 | 5700019.bin: IBM 5150 PC BASIC 1.0. visible in memory at F6000-F7FFF. | |
| 101 | 5700027.bin: IBM 5150 PC BASIC 1.0. visible in memory at F8000-F9FFF. | |
| 102 | 5700035.bin: IBM 5150 PC BASIC 1.0. visible in memory at FA000-FBFFF. | |
| 103 | 5700043.bin: IBM 5150 PC BASIC 1.0. visible in memory at FC000-FDFFF. | |
| 104 | 104 | ROM_LOAD( "5700019.bin", 0xf6000, 0x2000, CRC(b59e8f6c) SHA1(7a5db95370194c73b7921f2d69267268c69d2511)) |
| 105 | 105 | ROM_LOAD( "5700027.bin", 0xf8000, 0x2000, CRC(bfff99b8) SHA1(ca2f126ba69c1613b7b5a4137d8d8cf1db36a8e6)) |
| 106 | 106 | ROM_LOAD( "5700035.bin", 0xfa000, 0x2000, CRC(9fe4ec11) SHA1(89af8138185938c3da3386f97d3b0549a51de5ef)) |
| 107 | 107 | ROM_LOAD( "5700043.bin", 0xfc000, 0x2000, CRC(ea2794e6) SHA1(22fe58bc853ffd393d5e2f98defda7456924b04f)) |
| 108 | 108 | |
| 109 | 109 | |
| 110 | 5700051.bin: First early IBM 5150 PC BIOS. vis | |
| 110 | 5700051.bin: First early IBM 5150 PC BIOS. visible in memory at FE000-FFFFF. | |
| 111 | 111 | ROM_LOAD( "5700051.bin", 0xfe000, 0x2000, CRC(12d33fb8) SHA1(f046058faa016ad13aed5a082a45b21dea43d346)) |
| 112 | 5700671.bin: Second early IBM 5150 PC BIOS. vis | |
| 112 | 5700671.bin: Second early IBM 5150 PC BIOS. visible in memory at FE000-FFFFF. | |
| 113 | 113 | ROM_LOAD( "5700671.bin", 0xfe000, 0x2000, CRC(b7d4ec46) SHA1(bdb06f846c4768f39eeff7e16b6dbff8cd2117d2)) |
| 114 | 114 | |
| 115 | 5000019.bin: IBM 5150 PC BASIC 1.1. vissible in memory at F6000-F7FFF. | |
| 116 | 5000021.bin: IBM 5150 PC BASIC 1.1. vissible in memory at F8000-F9FFF. | |
| 117 | 5000022.bin: IBM 5150 PC BASIC 1.1. vissible in memory at FA000-FBFFF. | |
| 118 | 5000023.bin: IBM 5150 PC BASIC 1.1. vissible in memory at FC000-FDFFF. | |
| 115 | 5000019.bin: IBM 5150 PC BASIC 1.1. visible in memory at F6000-F7FFF. | |
| 116 | 5000021.bin: IBM 5150 PC BASIC 1.1. visible in memory at F8000-F9FFF. | |
| 117 | 5000022.bin: IBM 5150 PC BASIC 1.1. visible in memory at FA000-FBFFF. | |
| 118 | 5000023.bin: IBM 5150 PC BASIC 1.1. visible in memory at FC000-FDFFF. | |
| 119 | 119 | ROM_LOAD( "5000019.bin", 0xf6000, 0x2000, CRC(80d3cf5d) SHA1(64769b7a8b60ffeefa04e4afbec778069a2840c9)) |
| 120 | 120 | ROM_LOAD( "5000021.bin", 0xf8000, 0x2000, CRC(673a4acc) SHA1(082ae803994048e225150f771794ca305f73d731)) |
| 121 | 121 | ROM_LOAD( "5000022.bin", 0xfa000, 0x2000, CRC(aac3fc37) SHA1(c9e0529470edf04da093bb8c8ae2536c688c1a74)) |
| 122 | 122 | ROM_LOAD( "5000023.bin", 0xfc000, 0x2000, CRC(3062b3fc) SHA1(5134dd64721cbf093d059ee5d3fd09c7f86604c7)) |
| 123 | 123 | |
| 124 | 124 | |
| 125 | 5700476.0.bin: Late IBM 5150 PC BIOS. vis | |
| 125 | 5700476.0.bin: Late IBM 5150 PC BIOS. visible in memory at FE000-FFFFF. (1981 copyright) | |
| 126 | 126 | ROM_LOAD( "1501476.0.bin", 0xfe000, 0x2000, CRC(9b791d3e) SHA1(0c93f07e62cd27688f7f473e9787ef5308535fa0)) |
| 127 | 5700476.1.bin: Late IBM 5150 PC BIOS. vis | |
| 127 | 5700476.1.bin: Late IBM 5150 PC BIOS. visible in memory at FE000-FFFFF. (1982 copyright) | |
| 128 | 128 | ROM_LOAD( "1501476.1.bin", 0xfe000, 0x2000, CRC(e88792b3) SHA1(40fce6a94dda4328a8b608c7ae2f39d1dc688af4)) |
| 129 | 129 | |
| 130 | 5000027.bin: Early IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F6000-F7FFF. | |
| 131 | 5000026.bin: Prototype IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F8000-FFFFF. | |
| 130 | 5000027.bin: Early IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F6000-F7FFF. | |
| 131 | 5000026.bin: Prototype IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F8000-FFFFF. | |
| 132 | 132 | ROM_LOAD( "5000027.bin", 0xf6000, 0x2000, CRC(80d3cf5d) SHA1(64769b7a8b60ffeefa04e4afbec778069a2840c9)) |
| 133 | 133 | ROM_LOAD( "5000026.bin", 0xf8000, 0x8000, CRC(3c9b0ac3) SHA1(271c9f4cef5029a1560075550b67c3395db09fef)) |
| 134 | 134 | |
| 135 | 6359116.bin: Early IBM 5160 PC/XT BIOS/BASIC 1.1. vis | |
| 135 | 6359116.bin: Early IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F6000-F7FFF. | |
| 136 | 136 | ROM_LOAD( "6359116.bin", 0xf6000, 0x2000, CRC(80d3cf5d) SHA1(64769b7a8b60ffeefa04e4afbec778069a2840c9)) |
| 137 | 137 | |
| 138 | 1501512.bin: Early IBM 5160 PC/XT BIOS/BASIC 1.1. vis | |
| 138 | 1501512.bin: Early IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F8000-FFFFF. | |
| 139 | 139 | ROM_LOAD( "1501512.bin", 0xf8000, 0x8000, CRC(79522c3d) SHA1(6bac726d8d033491d52507278aa388ec04cf8b7e)) |
| 140 | 140 | |
| 141 | 62x0854.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F0000-F7FFF. (PROM) | |
| 142 | 62x0851.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F8000-FFFFF. (PROM) | |
| 141 | 62x0854.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F0000-F7FFF. (PROM) | |
| 142 | 62x0851.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F8000-FFFFF. (PROM) | |
| 143 | 143 | ROM_LOAD( "62x0854.bin", 0xf0000, 0x8000, CRC(b5fb0e83) SHA1(937b43759ffd472da4fb0fe775b3842f5fb4c3b3)) |
| 144 | 144 | ROM_LOAD( "62x0851.bin", 0xf8000, 0x8000, CRC(1054f7bd) SHA1(e7d0155813e4c650085144327581f05486ed1484)) |
| 145 | 145 | |
| 146 | 62x0853.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F0000-F7FFF. (EPROM) | |
| 147 | 62x0852.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F8000-FFFFF. (EPROM) | |
| 146 | 62x0853.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F0000-F7FFF. (EPROM) | |
| 147 | 62x0852.bin: First late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F8000-FFFFF. (EPROM) | |
| 148 | 148 | ROM_LOAD( "62x0853.bin", 0xf0000, 0x8000, CRC(b5fb0e83) SHA1(937b43759ffd472da4fb0fe775b3842f5fb4c3b3)) |
| 149 | 149 | ROM_LOAD( "62x0852.bin", 0xf8000, 0x8000, CRC(1054f7bd) SHA1(e7d0155813e4c650085144327581f05486ed1484)) |
| 150 | 150 | |
| 151 | 68x4370.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F0000-F7FFF. (PROM) | |
| 152 | 62x0890.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F8000-FFFFF. (PROM) | |
| 151 | 68x4370.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F0000-F7FFF. (PROM) | |
| 152 | 62x0890.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F8000-FFFFF. (PROM) | |
| 153 | 153 | ROM_LOAD( "68x4370.bin", 0xf0000, 0x8000, CRC(758ff036) SHA1(045e27a70407d89b7956ecae4d275bd2f6b0f8e2)) |
| 154 | 154 | ROM_LOAD( "62x0890.bin", 0xf8000, 0x8000, CRC(4f417635) SHA1(daa61762d3afdd7262e34edf1a3d2df9a05bcebb)) |
| 155 | 155 | |
| 156 | 62x0819.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F0000-F7FFF. (EPROM) | |
| 157 | 59x7268.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. vissible in memory at F8000-FFFFF. (EPROM) | |
| 156 | 62x0819.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F0000-F7FFF. (EPROM) | |
| 157 | 59x7268.bin: Second late IBM 5160 PC/XT BIOS/BASIC 1.1. visible in memory at F8000-FFFFF. (EPROM) | |
| 158 | 158 | ROM_LOAD( "62x0819.bin", 0xf0000, 0x8000, CRC(758ff036) SHA1(045e27a70407d89b7956ecae4d275bd2f6b0f8e2)) |
| 159 | 159 | ROM_LOAD( "59x7268.bin", 0xf8000, 0x8000, CRC(4f417635) SHA1(daa61762d3afdd7262e34edf1a3d2df9a05bcebb)) |
| 160 | 160 | |
| 161 | 78x7460.bin: IBM 5162 PC/XT 286 BIOS. vissible in even memory at F0000-FFFFF (mirror at E0000-EFFFF). | |
| 162 | 78x7461.bin: IBM 5162 PC/XT 286 BIOS. vissible in odd memory at F0000-FFFFF (mirror at E0000-EFFFF). | |
| 161 | 78x7460.bin: IBM 5162 PC/XT 286 BIOS. visible in even memory at F0000-FFFFF (mirror at E0000-EFFFF). | |
| 162 | 78x7461.bin: IBM 5162 PC/XT 286 BIOS. visible in odd memory at F0000-FFFFF (mirror at E0000-EFFFF). | |
| 163 | 163 | ROM_LOAD16_BYTE( "78x7460.bin", 0xf0000, 0x8000, CRC(1db4bd8f) SHA1(7be669fbb998d8b4626fefa7cd1208d3b2a88c31)) |
| 164 | 164 | ROM_LOAD16_BYTE( "78x7461.bin", 0xf0001, 0x8000, CRC(be14b453) SHA1(ec7c10087dbd53f9c6d1174e8f14212e2aec1818)) |
| 165 | 165 | |
| 166 | 6181028.bin: First 6MHz IBM 5170 PC/AT BIOS. vissible in even memory at F0000-FFFFF. | |
| 167 | 6181029.bin: First 6MHz IBM 5170 PC/AT BIOS. vissible in odd memory at F0000-FFFFF. | |
| 166 | 6181028.bin: First 6MHz IBM 5170 PC/AT BIOS. visible in even memory at F0000-FFFFF. | |
| 167 | 6181029.bin: First 6MHz IBM 5170 PC/AT BIOS. visible in odd memory at F0000-FFFFF. | |
| 168 | 168 | ROM_LOAD16_BYTE( "6181028.bin", 0xf0000, 0x8000, CRC(f6573f2a) SHA1(3e52cfa6a6a62b4e8576f4fe076c858c220e6c1a)) |
| 169 | 169 | ROM_LOAD16_BYTE( "6181029.bin", 0xf0001, 0x8000, CRC(7075fbb2) SHA1(a7b885cfd38710c9bc509da1e3ba9b543a2760be)) |
| 170 | 170 | |
| 171 | 6480090.bin: Second 6MHz IBM 5170 PC/AT BIOS. vissible in even memory at F0000-FFFFF. | |
| 172 | 6480091.bin: Second 6MHz IBM 5170 PC/AT BIOS. vissible in odd memory at F0000-FFFFF. | |
| 171 | 6480090.bin: Second 6MHz IBM 5170 PC/AT BIOS. visible in even memory at F0000-FFFFF. | |
| 172 | 6480091.bin: Second 6MHz IBM 5170 PC/AT BIOS. visible in odd memory at F0000-FFFFF. | |
| 173 | 173 | ROM_LOAD16_BYTE( "6480090.bin", 0xf0000, 0x8000, CRC(99703aa9) SHA1(18022e93a0412c8477e58f8c61a87718a0b9ab0e)) |
| 174 | 174 | ROM_LOAD16_BYTE( "6480091.bin", 0xf0001, 0x8000, CRC(013ef44b) SHA1(bfa15d2180a1902cb6d38c6eed3740f5617afd16)) |
| 175 | 175 | |
| 176 | 62x0820.bin: 8MHz IBM 5170 PC/AT BIOS. vissible in even memory at F0000-FFFFF. (PROM) | |
| 177 | 62x0821.bin: 8MHz IBM 5170 PC/AT BIOS. vissible in odd memory at F0000-FFFFF. (PROM) | |
| 176 | 62x0820.bin: 8MHz IBM 5170 PC/AT BIOS. visible in even memory at F0000-FFFFF. (PROM) | |
| 177 | 62x0821.bin: 8MHz IBM 5170 PC/AT BIOS. visible in odd memory at F0000-FFFFF. (PROM) | |
| 178 | 178 | ROM_LOAD( "62x0820.bin", 0xf0000, 0x8000, CRC(e9cc3761) SHA1(ff9373c1a1f34a32fb6acdabc189c61b01acf9aa)) |
| 179 | 179 | ROM_LOAD( "62x0821.bin", 0xf0001, 0x8000, CRC(b5978ccb) SHA1(2a1aeb9ae3cd7e60fc4c383ca026208b82156810)) |
| 180 | 180 | |
| 181 | 61x9266.bin: 8MHz IBM 5170 PC/AT BIOS. vissible in even memory at F0000-FFFFF. (EPROM) | |
| 182 | 61x9265.bin: 8MHz IBM 5170 PC/AT BIOS. vissible in odd memory at F0000-FFFFF. (EPROM) | |
| 181 | 61x9266.bin: 8MHz IBM 5170 PC/AT BIOS. visible in even memory at F0000-FFFFF. (EPROM) | |
| 182 | 61x9265.bin: 8MHz IBM 5170 PC/AT BIOS. visible in odd memory at F0000-FFFFF. (EPROM) | |
| 183 | 183 | ROM_LOAD( "61x9265.bin", 0xf0001, 0x8000, CRC(c32713e4) SHA1(22ed4e2be9f948682891e2fd056a97dbea01203c)) |
| 184 | 184 | ROM_LOAD( "61x9266.bin", 0xf0000, 0x8000, CRC(4995be7a) SHA1(8e8e5c863ae3b8c55fd394e345d8cca48b6e575c)) |
| 185 | 185 | |
| 186 | 186 | |
| 187 | 5788005.bin: IBM MDA/CGA font. Not mapped in PC memory. (American manufacture, otherwise similar to the Europe | |
| 187 | 5788005.bin: IBM MDA/CGA font. Not mapped in PC memory. (American manufacture, otherwise similar to the European manufacture) | |
| 188 | 188 | ROM_LOAD( "5788005.bin", 0x0000, 0x2000, CRC(0bf56d70) SHA1(c2a8b10808bf51a3c123ba3eb1e9dd608231916f)) |
| 189 | 189 | |
| 190 | 6359300.bin: IBM MDA/CGA font. Not mapped in PC memory. (Europe | |
| 190 | 6359300.bin: IBM MDA/CGA font. Not mapped in PC memory. (European manufacture, otherwise similar to the American manufacture) | |
| 191 | 191 | ROM_LOAD( "6359300.bin", 0x0000, 0x2000, CRC(0bf56d70) SHA1(c2a8b10808bf51a3c123ba3eb1e9dd608231916f)) |
| 192 | 192 | |
| 193 | 193 | 4733197.bin: IBM MDA/CGA Alternative font. Not mapped in PC memory. |
| r18419 | r18420 | |
| 211 | 211 | 104839e.bin: Hard drive controller Z80 firmware ROM. Not mapped in PC memory. (Mapped in Z80 microcontroller memory at 0000-7FFF) |
| 212 | 212 | ROM_LOAD( "104839e.bin", 0x0000, 0x1000, CRC(3ad32fcc) SHA1(0127fa520aaee91285cb46a640ed835b4554e4b3)) |
| 213 | 213 | |
| 214 | 6323581.bin: 3270 Keyboard adapter ROM. The first 0x800 bytes vis | |
| 214 | 6323581.bin: 3270 Keyboard adapter ROM. The first 0x800 bytes visible in memory at C0000-C07FF. The later 0x1800 bytes visible in memory at CA000-CB7FF. | |
| 215 | 215 | ROM_LOAD( "6323581.bin", 0xc0000, 0x2000, CRC(cf323cbd) SHA1(93c1ef2ede02772a46dab075c32e179faa045f81)) |
| 216 | 216 | |
| 217 | 217 | 1504161.bin: 3270 Character ROM (pixels 0-7). Not mapped in PC memory. |
| r18419 | r18420 | |
| 246 | 246 | ROM_LOAD( "30f9579.bin", 0x0000, 0x10000, CRC(1448d3cb) SHA1(13fa26d895ce084278cd5ab1208fc16c80115ebe)) |
| 247 | 247 | ROM_LOAD( "30f9580.bin", 0x0000, 0x10000, CRC(9965a634) SHA1(c237b1760f8a4561ec47dc70fe2e9df664e56596)) |
| 248 | 248 | |
| 249 | 90X7415.bin: IBM PS/2 model 25/30 external FDD support adapter. vis | |
| 249 | 90X7415.bin: IBM PS/2 model 25/30 external FDD support adapter. visible in memory at C8000-C9FFF. | |
| 250 | 250 | ROM_LOAD( "90x7415.bin", 0x0000, 0x2000, CRC(02d28556) SHA1(5543a8634f90a9141cf95f6a13c71be7778ee2a1)) |
| 251 | 251 | |
| 252 | 252 | |
| r18419 | r18420 | |
| 318 | 318 | SLOT_INTERFACE("hercules", ISA8_HERCULES) |
| 319 | 319 | SLOT_INTERFACE("svga_et4k", ISA8_SVGA_ET4K) |
| 320 | 320 | SLOT_INTERFACE("com", ISA8_COM) |
| 321 | SLOT_INTERFACE("fdc", ISA8_FDC) | |
| 321 | SLOT_INTERFACE("fdc", ISA8_FDC_XT) | |
| 322 | 322 | SLOT_INTERFACE("finalchs", ISA8_FINALCHS) |
| 323 | 323 | SLOT_INTERFACE("hdc", ISA8_HDC) |
| 324 | 324 | SLOT_INTERFACE("adlib", ISA8_ADLIB) |
| r18419 | r18420 | |
|---|---|---|
| 37 | 37 | #include "video/mc6845.h" |
| 38 | 38 | #include "sound/speaker.h" |
| 39 | 39 | #include "imagedev/flopdrv.h" |
| 40 | #include "formats/basicdsk.h" | |
| 40 | #include "formats/mfi_dsk.h" | |
| 41 | #include "formats/pyldin_dsk.h" | |
| 41 | 42 | #include "machine/upd765.h" |
| 42 | 43 | #include "machine/ram.h" |
| 43 | 44 | |
| r18419 | r18420 | |
| 77 | 78 | DECLARE_READ8_MEMBER(floppy_r); |
| 78 | 79 | UINT8 selectedline(UINT16 data); |
| 79 | 80 | required_device<device_t> m_speaker; |
| 80 | required_device<device | |
| 81 | required_device<upd765a_device> m_fdc; | |
| 81 | 82 | required_device<ram_device> m_ram; |
| 82 | 83 | DECLARE_DRIVER_INIT(pyl601); |
| 83 | 84 | virtual void machine_reset(); |
| r18419 | r18420 | |
| 213 | 214 | // UINT8 caps_led = BIT(data,4); |
| 214 | 215 | } |
| 215 | 216 | |
| 216 | INLINE device_t *get_floppy_image(running_machine &machine, int drive) | |
| 217 | { | |
| 218 | return floppy_get_device(machine, drive); | |
| 219 | } | |
| 220 | ||
| 221 | static UPD765_GET_IMAGE( pyldin_upd765_get_image ) | |
| 222 | { | |
| 223 | return get_floppy_image(device->machine(), (floppy_index & 1)^1); | |
| 224 | } | |
| 225 | ||
| 226 | 217 | WRITE8_MEMBER(pyl601_state::floppy_w) |
| 227 | 218 | { |
| 228 | 219 | // bit 0 is reset (if zero) |
| r18419 | r18420 | |
| 232 | 223 | |
| 233 | 224 | if (BIT(data,0)==0) |
| 234 | 225 | //reset |
| 235 | | |
| 226 | m_fdc->reset(); | |
| 236 | 227 | |
| 237 | floppy_mon_w(get_floppy_image(machine(), BIT(data,2)), !BIT(data, 3)); | |
| 228 | floppy_image_device *floppy = machine().device<floppy_connector>(BIT(data,2) ? "upd765:1" : "upd765:0")->get_device(); | |
| 229 | if(floppy) | |
| 230 | floppy->mon_w(!BIT(data, 3)); | |
| 238 | 231 | |
| 239 | | |
| 232 | m_fdc->tc_w(BIT(data, 1)); | |
| 240 | 233 | |
| 241 | upd765_tc_w(m_fdc, BIT(data, 1)); | |
| 242 | ||
| 243 | 234 | m_floppy_ctrl = data; |
| 244 | 235 | } |
| 245 | 236 | |
| r18419 | r18420 | |
| 248 | 239 | return m_floppy_ctrl; |
| 249 | 240 | } |
| 250 | 241 | |
| 251 | static const struct upd765_interface pyldin_upd765_interface = | |
| 252 | { | |
| 253 | DEVCB_NULL, /* interrupt */ | |
| 254 | DEVCB_NULL, /* DMA request */ | |
| 255 | pyldin_upd765_get_image, /* image lookup */ | |
| 256 | UPD765_RDY_PIN_CONNECTED, /* ready pin */ | |
| 257 | {FLOPPY_0,FLOPPY_1, NULL, NULL} | |
| 258 | }; | |
| 259 | ||
| 260 | 242 | static ADDRESS_MAP_START(pyl601_mem, AS_PROGRAM, 8, pyl601_state ) |
| 261 | 243 | ADDRESS_MAP_UNMAP_HIGH |
| 262 | 244 | AM_RANGE( 0x0000, 0xbfff ) AM_RAMBANK("bank1") |
| r18419 | r18420 | |
| 275 | 257 | AM_RANGE( 0xe682, 0xe682 ) AM_WRITE(vdisk_l_w) |
| 276 | 258 | AM_RANGE( 0xe683, 0xe683 ) AM_READWRITE(vdisk_data_r,vdisk_data_w) |
| 277 | 259 | AM_RANGE( 0xe6c0, 0xe6c0 ) AM_READWRITE(floppy_r, floppy_w) |
| 278 | AM_RANGE( 0xe6d0, 0xe6d0 ) AM_DEVREAD_LEGACY("upd765", upd765_status_r) | |
| 279 | AM_RANGE( 0xe6d1, 0xe6d1 ) AM_DEVREADWRITE_LEGACY("upd765", upd765_data_r, upd765_data_w) | |
| 260 | AM_RANGE( 0xe6d0, 0xe6d1 ) AM_DEVICE("upd765", upd765a_device, map) | |
| 280 | 261 | AM_RANGE( 0xe6f0, 0xe6f0 ) AM_READWRITE(rom_page_r, rom_page_w) |
| 281 | 262 | AM_RANGE( 0xe700, 0xefff ) AM_RAMBANK("bank4") |
| 282 | 263 | AM_RANGE( 0xf000, 0xffff ) AM_READ_BANK("bank5") AM_WRITE_BANK("bank6") |
| r18419 | r18420 | |
| 522 | 503 | device.execute().set_input_line(0, HOLD_LINE); |
| 523 | 504 | } |
| 524 | 505 | |
| 525 | static LEGACY_FLOPPY_OPTIONS_START(pyldin) | |
| 526 | LEGACY_FLOPPY_OPTION(pyldin, "img", "Pyldin disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, | |
| 527 | HEADS([2]) | |
| 528 | TRACKS([80]) | |
| 529 | SECTORS([9]) | |
| 530 | SECTOR_LENGTH([512]) | |
| 531 | FIRST_SECTOR_ID([1])) | |
| 532 | LEGACY_FLOPPY_OPTIONS_END | |
| 533 | ||
| 534 | static const floppy_interface pyldin_floppy_interface = | |
| 535 | { | |
| 536 | DEVCB_NULL, | |
| 537 | DEVCB_NULL, | |
| 538 | DEVCB_NULL, | |
| 539 | DEVCB_NULL, | |
| 540 | DEVCB_NULL, | |
| 541 | FLOPPY_STANDARD_5_25_DSHD, | |
| 542 | LEGACY_FLOPPY_OPTIONS_NAME(pyldin), | |
| 543 | NULL, | |
| 506 | static const floppy_format_type pyl601_floppy_formats[] = { | |
| 507 | FLOPPY_PYLDIN_FORMAT, | |
| 508 | FLOPPY_MFI_FORMAT, | |
| 544 | 509 | NULL |
| 545 | 510 | }; |
| 546 | 511 | |
| 512 | static SLOT_INTERFACE_START( pyl601_floppies ) | |
| 513 | SLOT_INTERFACE( "525hd", FLOPPY_525_HD ) | |
| 514 | SLOT_INTERFACE_END | |
| 515 | ||
| 547 | 516 | /* F4 Character Displayer */ |
| 548 | 517 | static const gfx_layout pyl601_charlayout = |
| 549 | 518 | { |
| r18419 | r18420 | |
| 604 | 573 | |
| 605 | 574 | /* Devices */ |
| 606 | 575 | MCFG_MC6845_ADD("crtc", MC6845, XTAL_2MHz, pyl601_crtc6845_interface) |
| 607 | MCFG_UPD765A_ADD("upd765", pyldin_upd765_interface) | |
| 608 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(pyldin_floppy_interface) | |
| 576 | MCFG_UPD765A_ADD("upd765", true, true) | |
| 577 | MCFG_FLOPPY_DRIVE_ADD("upd765:0", pyl601_floppies, "525hd", 0, pyl601_floppy_formats) | |
| 578 | MCFG_FLOPPY_DRIVE_ADD("upd765:1", pyl601_floppies, "525hd", 0, pyl601_floppy_formats) | |
| 609 | 579 | |
| 610 | 580 | /* internal ram */ |
| 611 | 581 | MCFG_RAM_ADD(RAM_TAG) |
| r18419 | r18420 | |
|---|---|---|
| 18 | 18 | #include "machine/ins8250.h" |
| 19 | 19 | #include "machine/pic8259.h" |
| 20 | 20 | #include "machine/mc146818.h" |
| 21 | #include "machine/p | |
| 21 | #include "machine/upd765.h" | |
| 22 | 22 | #include "machine/pci.h" |
| 23 | 23 | #include "machine/8237dma.h" |
| 24 | 24 | #include "machine/pckeybrd.h" |
| r18419 | r18420 | |
| 34 | 34 | #include "machine/scsicd.h" |
| 35 | 35 | #include "machine/scsihd.h" |
| 36 | 36 | #include "imagedev/flopdrv.h" |
| 37 | #include "formats/mfi_dsk.h" | |
| 37 | 38 | #include "formats/pc_dsk.h" |
| 38 | 39 | #include "machine/ram.h" |
| 39 | 40 | |
| r18419 | r18420 | |
| 63 | 64 | AM_RANGE(0x800003c0, 0x800003cf) AM_DEVREADWRITE8("vga", cirrus_vga_device, port_03c0_r, port_03c0_w, U64(0xffffffffffffffff)) |
| 64 | 65 | AM_RANGE(0x800003d0, 0x800003df) AM_DEVREADWRITE8("vga", cirrus_vga_device, port_03d0_r, port_03d0_w, U64(0xffffffffffffffff)) |
| 65 | 66 | AM_RANGE(0x800003F0, 0x800003F7) AM_READWRITE(bebox_800003F0_r, bebox_800003F0_w ) |
| 67 | AM_RANGE(0x800003F0, 0x800003F7) AM_DEVICE8( "smc37c78", smc37c78_device, map, U64(0xffffffffffffffff) ) | |
| 66 | 68 | AM_RANGE(0x800003F8, 0x800003FF) AM_DEVREADWRITE8( "ns16550_0",ns16550_device, ins8250_r, ins8250_w, U64(0xffffffffffffffff) ) |
| 67 | 69 | AM_RANGE(0x80000480, 0x8000048F) AM_READWRITE8(bebox_80000480_r, bebox_80000480_w, U64(0xffffffffffffffff) ) |
| 68 | 70 | AM_RANGE(0x80000CF8, 0x80000CFF) AM_DEVREADWRITE("pcibus", pci_bus_device, read_64be, write_64be ) |
| r18419 | r18420 | |
| 129 | 131 | }; |
| 130 | 132 | |
| 131 | 133 | |
| 132 | static const floppy_interface bebox_floppy_interface = | |
| 133 | { | |
| 134 | DEVCB_NULL, | |
| 135 | DEVCB_NULL, | |
| 136 | DEVCB_NULL, | |
| 137 | DEVCB_NULL, | |
| 138 | DEVCB_NULL, | |
| 139 | FLOPPY_STANDARD_5_25_DSHD, | |
| 140 | LEGACY_FLOPPY_OPTIONS_NAME(pc), | |
| 141 | NULL, | |
| 134 | static const floppy_format_type bebox_floppy_formats[] = { | |
| 135 | FLOPPY_PC_FORMAT, | |
| 136 | FLOPPY_MFI_FORMAT, | |
| 142 | 137 | NULL |
| 143 | 138 | }; |
| 144 | 139 | |
| 140 | static SLOT_INTERFACE_START( bebox_floppies ) | |
| 141 | SLOT_INTERFACE( "35hd", FLOPPY_35_HD ) | |
| 142 | SLOT_INTERFACE_END | |
| 143 | ||
| 145 | 144 | const struct mpc105_interface mpc105_config = |
| 146 | 145 | { |
| 147 | 146 | "ppc1", |
| r18419 | r18420 | |
| 209 | 208 | |
| 210 | 209 | /*MCFG_PCI_BUS_DEVICE(12, NULL, scsi53c810_pci_read, scsi53c810_pci_write)*/ |
| 211 | 210 | |
| 212 | MCFG_SMC37C78_ADD("smc37c78", pc_fdc_upd765_connected_1_drive_interface) | |
| 211 | MCFG_SMC37C78_ADD("smc37c78") | |
| 212 | MCFG_FLOPPY_DRIVE_ADD("smc37c78:0", bebox_floppies, "35hd", 0, bebox_floppy_formats) | |
| 213 | 213 | |
| 214 | MCFG_LEGACY_FLOPPY_DRIVE_ADD(FLOPPY_0, bebox_floppy_interface) | |
| 215 | ||
| 216 | 214 | MCFG_MC146818_ADD( "rtc", MC146818_STANDARD ) |
| 217 | 215 | |
| 218 | 216 | /* internal ram */ |
| r18419 | r18420 | |
|---|---|---|
| 554 | 554 | $(MESS_MACHINE)/wd1772.o \ |
| 555 | 555 | $(MESS_MACHINE)/3c503.o \ |
| 556 | 556 | $(MESS_FORMATS)/z80bin.o \ |
| 557 | $(MESS_MACHINE)/n82077aa.o \ | |
| 558 | 557 | $(MESS_MACHINE)/mb8795.o \ |
| 559 | 558 | $(MESS_MACHINE)/null_modem.o \ |
| 560 | 559 | $(MESS_MACHINE)/vcsctrl.o \ |
| Previous | 199869 Revisions | Next |