src/mess/machine/esqvfd.c
| r0 | r15329 | |
| 1 | /* |
| 2 | Ensoniq Vacuum Flourescent Displays (VFDs) |
| 3 | Emulation by R. Belmont |
| 4 | */ |
| 5 | |
| 6 | #include "esqvfd.h" |
| 7 | #include "esq2by40.lh" |
| 8 | |
| 9 | const device_type ESQ2x40 = &device_creator<esq2x40_t>; |
| 10 | |
| 11 | // adapted from bfm_bd1, rearranged to work with ASCII data used by the Ensoniq h/w |
| 12 | static const UINT16 font[]= |
| 13 | { // FEDC BA98 7654 3210 |
| 14 | 0x0000, // 0000 0000 0000 0000 (space) |
| 15 | 0x0000, // 0000 0000 0000 0000 ! (not defined) |
| 16 | 0x0009, // 0000 0000 0000 1001 ". |
| 17 | 0xC62A, // 1100 0110 0010 1010 #. |
| 18 | 0xC62D, // 1100 0110 0010 1101 $. |
| 19 | 0x0000, // 0000 0000 0000 0000 % (not defined) |
| 20 | 0x0000, // 0000 0000 0000 0000 & (not defined) |
| 21 | 0x0040, // 0000 0000 1000 0000 '. |
| 22 | 0x0880, // 0000 1000 1000 0000 (. |
| 23 | 0x0050, // 0000 0000 0101 0000 ). |
| 24 | 0xCCD8, // 1100 1100 1101 1000 *. |
| 25 | 0xC408, // 1100 0100 0000 1000 +. |
| 26 | 0x0000, // 0000 0000 0000 0000 , (not defined) |
| 27 | 0xC000, // 1100 0000 0000 0000 -. |
| 28 | 0x1000, // 0001 0000 0000 0000 . |
| 29 | 0x0090, // 0000 0000 1001 0000 / |
| 30 | 0x22B7, // 0010 0010 1011 0111 0. |
| 31 | 0x0408, // 0000 0100 0000 1000 1. |
| 32 | 0xE206, // 1110 0010 0000 0110 2. |
| 33 | 0x4226, // 0100 0010 0010 0110 3. |
| 34 | 0xC023, // 1100 0000 0010 0011 4. |
| 35 | 0xC225, // 1100 0010 0010 0101 5. |
| 36 | 0xE225, // 1110 0010 0010 0101 6. |
| 37 | 0x0026, // 0000 0000 0010 0110 7. |
| 38 | 0xE227, // 1110 0010 0010 0111 8. |
| 39 | 0xC227, // 1100 0010 0010 0111 9. |
| 40 | 0x0000, // 0000 0000 0000 0000 : (not defined) |
| 41 | 0x0000, // 0000 0000 0000 0000 ; (not defined) |
| 42 | 0x0290, // 0000 0010 1001 0000 <. |
| 43 | 0xC200, // 1100 0010 0000 0000 =. |
| 44 | 0x0A40, // 0000 1010 0100 0000 >. |
| 45 | 0x0000, // 0000 0000 0000 0000 ? (not defined) |
| 46 | 0xA626, // 1010 0110 0010 0110 @. |
| 47 | 0xE027, // 1110 0000 0010 0111 A. |
| 48 | 0x462E, // 0100 0110 0010 1110 B. |
| 49 | 0x2205, // 0010 0010 0000 0101 C. |
| 50 | 0x062E, // 0000 0110 0010 1110 D. |
| 51 | 0xA205, // 1010 0010 0000 0101 E. |
| 52 | 0xA005, // 1010 0000 0000 0101 F. |
| 53 | 0x6225, // 0110 0010 0010 0101 G. |
| 54 | 0xE023, // 1110 0000 0010 0011 H. |
| 55 | 0x060C, // 0000 0110 0000 1100 I. |
| 56 | 0x2222, // 0010 0010 0010 0010 J. |
| 57 | 0xA881, // 1010 1000 1000 0001 K. |
| 58 | 0x2201, // 0010 0010 0000 0001 L. |
| 59 | 0x20E3, // 0010 0000 1110 0011 M. |
| 60 | 0x2863, // 0010 1000 0110 0011 N. |
| 61 | 0x2227, // 0010 0010 0010 0111 O. |
| 62 | 0xE007, // 1110 0000 0000 0111 P. |
| 63 | 0x2A27, // 0010 1010 0010 0111 Q. |
| 64 | 0xE807, // 1110 1000 0000 0111 R. |
| 65 | 0xC225, // 1100 0010 0010 0101 S. |
| 66 | 0x040C, // 0000 0100 0000 1100 T. |
| 67 | 0x2223, // 0010 0010 0010 0011 U. |
| 68 | 0x2091, // 0010 0000 1001 0001 V. |
| 69 | 0x2833, // 0010 1000 0011 0011 W. |
| 70 | 0x08D0, // 0000 1000 1101 0000 X. |
| 71 | 0x04C0, // 0000 0100 1100 0000 Y. |
| 72 | 0x0294, // 0000 0010 1001 0100 Z. |
| 73 | 0x2205, // 0010 0010 0000 0101 [. |
| 74 | 0x0840, // 0000 1000 0100 0000 \. |
| 75 | 0x0226, // 0000 0010 0010 0110 ]. |
| 76 | 0x0810, // 0000 1000 0001 0000 ^. |
| 77 | 0x0200, // 0000 0010 0000 0000 _ |
| 78 | }; |
| 79 | |
| 80 | esqvfd_t::esqvfd_t(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 81 | device_t(mconfig, type, name, tag, owner, clock) |
| 82 | { |
| 83 | } |
| 84 | |
| 85 | void esqvfd_t::device_start() |
| 86 | { |
| 87 | } |
| 88 | |
| 89 | void esqvfd_t::device_reset() |
| 90 | { |
| 91 | m_cursx = m_cursy = 0; |
| 92 | memset(m_chars, ' ', sizeof(m_chars)); |
| 93 | memset(m_attrs, 0, sizeof(m_attrs)); |
| 94 | } |
| 95 | |
| 96 | void esqvfd_t::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 97 | { |
| 98 | } |
| 99 | |
| 100 | // why isn't the font just stored in this order? |
| 101 | UINT32 esqvfd_t::conv_segments(UINT16 segin) |
| 102 | { |
| 103 | UINT32 segout = 0; |
| 104 | |
| 105 | if ( segin & 0x0004 ) segout |= 0x0001; |
| 106 | if ( segin & 0x0002 ) segout |= 0x0002; |
| 107 | if ( segin & 0x0020 ) segout |= 0x0004; |
| 108 | if ( segin & 0x0200 ) segout |= 0x0008; |
| 109 | if ( segin & 0x2000 ) segout |= 0x0010; |
| 110 | if ( segin & 0x0001 ) segout |= 0x0020; |
| 111 | if ( segin & 0x8000 ) segout |= 0x0040; |
| 112 | if ( segin & 0x4000 ) segout |= 0x0080; |
| 113 | if ( segin & 0x0008 ) segout |= 0x0100; |
| 114 | if ( segin & 0x0400 ) segout |= 0x0200; |
| 115 | if ( segin & 0x0010 ) segout |= 0x0400; |
| 116 | if ( segin & 0x0040 ) segout |= 0x0800; |
| 117 | if ( segin & 0x0080 ) segout |= 0x1000; |
| 118 | if ( segin & 0x0800 ) segout |= 0x2000; |
| 119 | if ( segin & 0x1000 ) segout |= 0x4000; |
| 120 | |
| 121 | return segout; |
| 122 | } |
| 123 | |
| 124 | static MACHINE_CONFIG_FRAGMENT(esq2x40) |
| 125 | MCFG_DEFAULT_LAYOUT(layout_esq2by40) |
| 126 | MACHINE_CONFIG_END |
| 127 | |
| 128 | machine_config_constructor esq2x40_t::device_mconfig_additions() const |
| 129 | { |
| 130 | return MACHINE_CONFIG_NAME( esq2x40 ); |
| 131 | } |
| 132 | |
| 133 | void esq2x40_t::write_char(int data) |
| 134 | { |
| 135 | if ((data >= 0x80) && (data < 0xd0)) |
| 136 | { |
| 137 | m_cursy = ((data & 0x7f) >= 40) ? 1 : 0; |
| 138 | m_cursx = (data & 0x7f) % 40; |
| 139 | } |
| 140 | else if (data >= 0xd0) |
| 141 | { |
| 142 | switch (data) |
| 143 | { |
| 144 | case 0xd6: // clear screen |
| 145 | m_cursx = m_cursy = 0; |
| 146 | memset(m_chars, 0, sizeof(m_chars)); |
| 147 | memset(m_attrs, 0, sizeof(m_attrs)); |
| 148 | memset(m_dirty, 1, sizeof(m_dirty)); |
| 149 | break; |
| 150 | |
| 151 | default: |
| 152 | // printf("Unknown control code %02x\n", data); |
| 153 | break; |
| 154 | } |
| 155 | } |
| 156 | else |
| 157 | { |
| 158 | if (data == 'f') // EPS-16 clear screen (HACK!) |
| 159 | { |
| 160 | m_cursx = m_cursy = 0; |
| 161 | memset(m_chars, 0, sizeof(m_chars)); |
| 162 | memset(m_attrs, 0, sizeof(m_attrs)); |
| 163 | memset(m_dirty, 1, sizeof(m_dirty)); |
| 164 | } |
| 165 | else if ((data >= 0x20) && (data <= 0x5f)) |
| 166 | { |
| 167 | m_chars[m_cursy][m_cursx] = data - ' '; |
| 168 | m_dirty[m_cursy][m_cursx] = 1; |
| 169 | m_cursx++; |
| 170 | |
| 171 | if (m_cursx >= 39) |
| 172 | { |
| 173 | m_cursx = 39; |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | update_display(); |
| 179 | } |
| 180 | |
| 181 | void esq2x40_t::update_display() |
| 182 | { |
| 183 | for (int row = 0; row < 2; row++) |
| 184 | { |
| 185 | for (int col = 0; col < 40; col++) |
| 186 | { |
| 187 | if (m_dirty[row][col]) |
| 188 | { |
| 189 | UINT32 segdata = conv_segments(font[m_chars[row][col]]); |
| 190 | |
| 191 | output_set_indexed_value("vfd", (row*40) + col, segdata); |
| 192 | |
| 193 | m_dirty[row][col] = 0; |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | esq2x40_t::esq2x40_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : esqvfd_t(mconfig, ESQ2x40, "Ensoniq 2x40 VFD", tag, owner, clock) |
| 200 | { |
| 201 | } |
| 202 | |
| 203 | |
src/mess/layout/esq2by40.lay
| r0 | r15329 | |
| 1 | <!-- esq2by40.lay --> |
| 2 | <!-- 2012-05-26: Initial version. [R. Belmont / VFDGen 0.1] --> |
| 3 | |
| 4 | <mamelayout version="2"> |
| 5 | |
| 6 | <element name="vfd0" defstate="0"> |
| 7 | <led14segsc> |
| 8 | <color red="0.45" green="1.0" blue="0.95" /> |
| 9 | </led14segsc> |
| 10 | </element> |
| 11 | |
| 12 | <element name="background"> |
| 13 | <rect> |
| 14 | <bounds left="0" top="0" right="1" bottom="1" /> |
| 15 | <color red="0.0" green="0.0" blue="0.0" /> |
| 16 | </rect> |
| 17 | </element> |
| 18 | |
| 19 | <view name="Default Layout"> |
| 20 | |
| 21 | <!-- Background --> |
| 22 | <backdrop element="background"> |
| 23 | <bounds left="0" top="0" right="759" bottom="47" /> |
| 24 | </backdrop> |
| 25 | |
| 26 | <!-- VFDs --> |
| 27 | <bezel name="vfd0" element="vfd0"> |
| 28 | <bounds left="0" top="0" right="18" bottom="23" /> |
| 29 | </bezel> |
| 30 | <bezel name="vfd1" element="vfd0"> |
| 31 | <bounds left="19" top="0" right="37" bottom="23" /> |
| 32 | </bezel> |
| 33 | <bezel name="vfd2" element="vfd0"> |
| 34 | <bounds left="38" top="0" right="56" bottom="23" /> |
| 35 | </bezel> |
| 36 | <bezel name="vfd3" element="vfd0"> |
| 37 | <bounds left="57" top="0" right="75" bottom="23" /> |
| 38 | </bezel> |
| 39 | <bezel name="vfd4" element="vfd0"> |
| 40 | <bounds left="76" top="0" right="94" bottom="23" /> |
| 41 | </bezel> |
| 42 | <bezel name="vfd5" element="vfd0"> |
| 43 | <bounds left="95" top="0" right="113" bottom="23" /> |
| 44 | </bezel> |
| 45 | <bezel name="vfd6" element="vfd0"> |
| 46 | <bounds left="114" top="0" right="132" bottom="23" /> |
| 47 | </bezel> |
| 48 | <bezel name="vfd7" element="vfd0"> |
| 49 | <bounds left="133" top="0" right="151" bottom="23" /> |
| 50 | </bezel> |
| 51 | <bezel name="vfd8" element="vfd0"> |
| 52 | <bounds left="152" top="0" right="170" bottom="23" /> |
| 53 | </bezel> |
| 54 | <bezel name="vfd9" element="vfd0"> |
| 55 | <bounds left="171" top="0" right="189" bottom="23" /> |
| 56 | </bezel> |
| 57 | <bezel name="vfd10" element="vfd0"> |
| 58 | <bounds left="190" top="0" right="208" bottom="23" /> |
| 59 | </bezel> |
| 60 | <bezel name="vfd11" element="vfd0"> |
| 61 | <bounds left="209" top="0" right="227" bottom="23" /> |
| 62 | </bezel> |
| 63 | <bezel name="vfd12" element="vfd0"> |
| 64 | <bounds left="228" top="0" right="246" bottom="23" /> |
| 65 | </bezel> |
| 66 | <bezel name="vfd13" element="vfd0"> |
| 67 | <bounds left="247" top="0" right="265" bottom="23" /> |
| 68 | </bezel> |
| 69 | <bezel name="vfd14" element="vfd0"> |
| 70 | <bounds left="266" top="0" right="284" bottom="23" /> |
| 71 | </bezel> |
| 72 | <bezel name="vfd15" element="vfd0"> |
| 73 | <bounds left="285" top="0" right="303" bottom="23" /> |
| 74 | </bezel> |
| 75 | <bezel name="vfd16" element="vfd0"> |
| 76 | <bounds left="304" top="0" right="322" bottom="23" /> |
| 77 | </bezel> |
| 78 | <bezel name="vfd17" element="vfd0"> |
| 79 | <bounds left="323" top="0" right="341" bottom="23" /> |
| 80 | </bezel> |
| 81 | <bezel name="vfd18" element="vfd0"> |
| 82 | <bounds left="342" top="0" right="360" bottom="23" /> |
| 83 | </bezel> |
| 84 | <bezel name="vfd19" element="vfd0"> |
| 85 | <bounds left="361" top="0" right="379" bottom="23" /> |
| 86 | </bezel> |
| 87 | <bezel name="vfd20" element="vfd0"> |
| 88 | <bounds left="380" top="0" right="398" bottom="23" /> |
| 89 | </bezel> |
| 90 | <bezel name="vfd21" element="vfd0"> |
| 91 | <bounds left="399" top="0" right="417" bottom="23" /> |
| 92 | </bezel> |
| 93 | <bezel name="vfd22" element="vfd0"> |
| 94 | <bounds left="418" top="0" right="436" bottom="23" /> |
| 95 | </bezel> |
| 96 | <bezel name="vfd23" element="vfd0"> |
| 97 | <bounds left="437" top="0" right="455" bottom="23" /> |
| 98 | </bezel> |
| 99 | <bezel name="vfd24" element="vfd0"> |
| 100 | <bounds left="456" top="0" right="474" bottom="23" /> |
| 101 | </bezel> |
| 102 | <bezel name="vfd25" element="vfd0"> |
| 103 | <bounds left="475" top="0" right="493" bottom="23" /> |
| 104 | </bezel> |
| 105 | <bezel name="vfd26" element="vfd0"> |
| 106 | <bounds left="494" top="0" right="512" bottom="23" /> |
| 107 | </bezel> |
| 108 | <bezel name="vfd27" element="vfd0"> |
| 109 | <bounds left="513" top="0" right="531" bottom="23" /> |
| 110 | </bezel> |
| 111 | <bezel name="vfd28" element="vfd0"> |
| 112 | <bounds left="532" top="0" right="550" bottom="23" /> |
| 113 | </bezel> |
| 114 | <bezel name="vfd29" element="vfd0"> |
| 115 | <bounds left="551" top="0" right="569" bottom="23" /> |
| 116 | </bezel> |
| 117 | <bezel name="vfd30" element="vfd0"> |
| 118 | <bounds left="570" top="0" right="588" bottom="23" /> |
| 119 | </bezel> |
| 120 | <bezel name="vfd31" element="vfd0"> |
| 121 | <bounds left="589" top="0" right="607" bottom="23" /> |
| 122 | </bezel> |
| 123 | <bezel name="vfd32" element="vfd0"> |
| 124 | <bounds left="608" top="0" right="626" bottom="23" /> |
| 125 | </bezel> |
| 126 | <bezel name="vfd33" element="vfd0"> |
| 127 | <bounds left="627" top="0" right="645" bottom="23" /> |
| 128 | </bezel> |
| 129 | <bezel name="vfd34" element="vfd0"> |
| 130 | <bounds left="646" top="0" right="664" bottom="23" /> |
| 131 | </bezel> |
| 132 | <bezel name="vfd35" element="vfd0"> |
| 133 | <bounds left="665" top="0" right="683" bottom="23" /> |
| 134 | </bezel> |
| 135 | <bezel name="vfd36" element="vfd0"> |
| 136 | <bounds left="684" top="0" right="702" bottom="23" /> |
| 137 | </bezel> |
| 138 | <bezel name="vfd37" element="vfd0"> |
| 139 | <bounds left="703" top="0" right="721" bottom="23" /> |
| 140 | </bezel> |
| 141 | <bezel name="vfd38" element="vfd0"> |
| 142 | <bounds left="722" top="0" right="740" bottom="23" /> |
| 143 | </bezel> |
| 144 | <bezel name="vfd39" element="vfd0"> |
| 145 | <bounds left="741" top="0" right="759" bottom="23" /> |
| 146 | </bezel> |
| 147 | <bezel name="vfd40" element="vfd0"> |
| 148 | <bounds left="0" top="24" right="18" bottom="47" /> |
| 149 | </bezel> |
| 150 | <bezel name="vfd41" element="vfd0"> |
| 151 | <bounds left="19" top="24" right="37" bottom="47" /> |
| 152 | </bezel> |
| 153 | <bezel name="vfd42" element="vfd0"> |
| 154 | <bounds left="38" top="24" right="56" bottom="47" /> |
| 155 | </bezel> |
| 156 | <bezel name="vfd43" element="vfd0"> |
| 157 | <bounds left="57" top="24" right="75" bottom="47" /> |
| 158 | </bezel> |
| 159 | <bezel name="vfd44" element="vfd0"> |
| 160 | <bounds left="76" top="24" right="94" bottom="47" /> |
| 161 | </bezel> |
| 162 | <bezel name="vfd45" element="vfd0"> |
| 163 | <bounds left="95" top="24" right="113" bottom="47" /> |
| 164 | </bezel> |
| 165 | <bezel name="vfd46" element="vfd0"> |
| 166 | <bounds left="114" top="24" right="132" bottom="47" /> |
| 167 | </bezel> |
| 168 | <bezel name="vfd47" element="vfd0"> |
| 169 | <bounds left="133" top="24" right="151" bottom="47" /> |
| 170 | </bezel> |
| 171 | <bezel name="vfd48" element="vfd0"> |
| 172 | <bounds left="152" top="24" right="170" bottom="47" /> |
| 173 | </bezel> |
| 174 | <bezel name="vfd49" element="vfd0"> |
| 175 | <bounds left="171" top="24" right="189" bottom="47" /> |
| 176 | </bezel> |
| 177 | <bezel name="vfd50" element="vfd0"> |
| 178 | <bounds left="190" top="24" right="208" bottom="47" /> |
| 179 | </bezel> |
| 180 | <bezel name="vfd51" element="vfd0"> |
| 181 | <bounds left="209" top="24" right="227" bottom="47" /> |
| 182 | </bezel> |
| 183 | <bezel name="vfd52" element="vfd0"> |
| 184 | <bounds left="228" top="24" right="246" bottom="47" /> |
| 185 | </bezel> |
| 186 | <bezel name="vfd53" element="vfd0"> |
| 187 | <bounds left="247" top="24" right="265" bottom="47" /> |
| 188 | </bezel> |
| 189 | <bezel name="vfd54" element="vfd0"> |
| 190 | <bounds left="266" top="24" right="284" bottom="47" /> |
| 191 | </bezel> |
| 192 | <bezel name="vfd55" element="vfd0"> |
| 193 | <bounds left="285" top="24" right="303" bottom="47" /> |
| 194 | </bezel> |
| 195 | <bezel name="vfd56" element="vfd0"> |
| 196 | <bounds left="304" top="24" right="322" bottom="47" /> |
| 197 | </bezel> |
| 198 | <bezel name="vfd57" element="vfd0"> |
| 199 | <bounds left="323" top="24" right="341" bottom="47" /> |
| 200 | </bezel> |
| 201 | <bezel name="vfd58" element="vfd0"> |
| 202 | <bounds left="342" top="24" right="360" bottom="47" /> |
| 203 | </bezel> |
| 204 | <bezel name="vfd59" element="vfd0"> |
| 205 | <bounds left="361" top="24" right="379" bottom="47" /> |
| 206 | </bezel> |
| 207 | <bezel name="vfd60" element="vfd0"> |
| 208 | <bounds left="380" top="24" right="398" bottom="47" /> |
| 209 | </bezel> |
| 210 | <bezel name="vfd61" element="vfd0"> |
| 211 | <bounds left="399" top="24" right="417" bottom="47" /> |
| 212 | </bezel> |
| 213 | <bezel name="vfd62" element="vfd0"> |
| 214 | <bounds left="418" top="24" right="436" bottom="47" /> |
| 215 | </bezel> |
| 216 | <bezel name="vfd63" element="vfd0"> |
| 217 | <bounds left="437" top="24" right="455" bottom="47" /> |
| 218 | </bezel> |
| 219 | <bezel name="vfd64" element="vfd0"> |
| 220 | <bounds left="456" top="24" right="474" bottom="47" /> |
| 221 | </bezel> |
| 222 | <bezel name="vfd65" element="vfd0"> |
| 223 | <bounds left="475" top="24" right="493" bottom="47" /> |
| 224 | </bezel> |
| 225 | <bezel name="vfd66" element="vfd0"> |
| 226 | <bounds left="494" top="24" right="512" bottom="47" /> |
| 227 | </bezel> |
| 228 | <bezel name="vfd67" element="vfd0"> |
| 229 | <bounds left="513" top="24" right="531" bottom="47" /> |
| 230 | </bezel> |
| 231 | <bezel name="vfd68" element="vfd0"> |
| 232 | <bounds left="532" top="24" right="550" bottom="47" /> |
| 233 | </bezel> |
| 234 | <bezel name="vfd69" element="vfd0"> |
| 235 | <bounds left="551" top="24" right="569" bottom="47" /> |
| 236 | </bezel> |
| 237 | <bezel name="vfd70" element="vfd0"> |
| 238 | <bounds left="570" top="24" right="588" bottom="47" /> |
| 239 | </bezel> |
| 240 | <bezel name="vfd71" element="vfd0"> |
| 241 | <bounds left="589" top="24" right="607" bottom="47" /> |
| 242 | </bezel> |
| 243 | <bezel name="vfd72" element="vfd0"> |
| 244 | <bounds left="608" top="24" right="626" bottom="47" /> |
| 245 | </bezel> |
| 246 | <bezel name="vfd73" element="vfd0"> |
| 247 | <bounds left="627" top="24" right="645" bottom="47" /> |
| 248 | </bezel> |
| 249 | <bezel name="vfd74" element="vfd0"> |
| 250 | <bounds left="646" top="24" right="664" bottom="47" /> |
| 251 | </bezel> |
| 252 | <bezel name="vfd75" element="vfd0"> |
| 253 | <bounds left="665" top="24" right="683" bottom="47" /> |
| 254 | </bezel> |
| 255 | <bezel name="vfd76" element="vfd0"> |
| 256 | <bounds left="684" top="24" right="702" bottom="47" /> |
| 257 | </bezel> |
| 258 | <bezel name="vfd77" element="vfd0"> |
| 259 | <bounds left="703" top="24" right="721" bottom="47" /> |
| 260 | </bezel> |
| 261 | <bezel name="vfd78" element="vfd0"> |
| 262 | <bounds left="722" top="24" right="740" bottom="47" /> |
| 263 | </bezel> |
| 264 | <bezel name="vfd79" element="vfd0"> |
| 265 | <bounds left="741" top="24" right="759" bottom="47" /> |
| 266 | </bezel> |
| 267 | </view> |
| 268 | |
| 269 | </mamelayout> |
src/mess/drivers/esq1.c
| r15328 | r15329 | |
| 2 | 2 | |
| 3 | 3 | drivers/esq1.c |
| 4 | 4 | |
| 5 | | Ensoniq ESQ-1, ESQ-m, and SQ-80 Digital Wave Synthesizers |
| 6 | | Preliminary driver by R. Belmont |
| 5 | Ensoniq ESQ-1 Digital Wave Synthesizer |
| 6 | Ensoniq SQ-80 Cross Wave Synthesizer |
| 7 | Driver by R. Belmont |
| 7 | 8 | |
| 8 | 9 | Map for ESQ-1 and ESQ-m: |
| 9 | 10 | 0000-1fff: OS RAM |
| r15328 | r15329 | |
| 56 | 57 | #include "cpu/m6809/m6809.h" |
| 57 | 58 | #include "sound/es5503.h" |
| 58 | 59 | #include "machine/68681.h" |
| 60 | #include "machine/wd1772.h" |
| 59 | 61 | |
| 62 | #include "machine/esqvfd.h" |
| 63 | |
| 64 | #define WD1772_TAG "wd1772" |
| 65 | |
| 60 | 66 | #define KEYBOARD_HACK (0) |
| 61 | 67 | |
| 62 | 68 | class esq1_state : public driver_device |
| r15328 | r15329 | |
| 64 | 70 | public: |
| 65 | 71 | esq1_state(const machine_config &mconfig, device_type type, const char *tag) |
| 66 | 72 | : driver_device(mconfig, type, tag), |
| 67 | | m_duart(*this, "duart") |
| 73 | m_maincpu(*this, "maincpu"), |
| 74 | m_duart(*this, "duart"), |
| 75 | m_fdc(*this, WD1772_TAG), |
| 76 | m_vfd(*this, "vfd") |
| 68 | 77 | { } |
| 69 | 78 | |
| 79 | required_device<device_t> m_maincpu; |
| 70 | 80 | required_device<device_t> m_duart; |
| 81 | optional_device<wd1772_t> m_fdc; |
| 82 | optional_device<esq2x40_t> m_vfd; |
| 71 | 83 | |
| 84 | DECLARE_READ8_MEMBER(wd1772_r); |
| 85 | DECLARE_WRITE8_MEMBER(wd1772_w); |
| 86 | DECLARE_READ8_MEMBER(seqdosram_r); |
| 87 | DECLARE_WRITE8_MEMBER(seqdosram_w); |
| 88 | DECLARE_WRITE8_MEMBER(mapper_w); |
| 89 | |
| 90 | int m_mapper_state; |
| 91 | int m_seq_bank; |
| 92 | UINT8 m_seqram[0x10000]; |
| 93 | UINT8 m_dosram[0x2000]; |
| 72 | 94 | }; |
| 73 | 95 | |
| 74 | 96 | |
| r15328 | r15329 | |
| 81 | 103 | return 0x80; |
| 82 | 104 | } |
| 83 | 105 | |
| 84 | | static VIDEO_START( esq1 ) |
| 106 | static MACHINE_RESET( esq1 ) |
| 85 | 107 | { |
| 108 | // set default OSROM banking |
| 109 | esq1_state *state = machine.driver_data<esq1_state>(); |
| 110 | state->membank("osbank")->set_base(machine.root_device().memregion("osrom")->base() ); |
| 111 | |
| 112 | state->m_mapper_state = 0; |
| 113 | state->m_seq_bank = 0; |
| 86 | 114 | } |
| 87 | 115 | |
| 88 | | static SCREEN_UPDATE_RGB32( esq1 ) |
| 116 | READ8_MEMBER(esq1_state::wd1772_r) |
| 89 | 117 | { |
| 90 | | return 0; |
| 118 | return m_fdc->read(space, offset&3); |
| 91 | 119 | } |
| 92 | 120 | |
| 93 | | static MACHINE_RESET( esq1 ) |
| 121 | WRITE8_MEMBER(esq1_state::wd1772_w) |
| 94 | 122 | { |
| 95 | | // set default OSROM banking |
| 96 | | esq1_state *state = machine.driver_data<esq1_state>(); |
| 97 | | state->membank("osbank")->set_base(machine.root_device().memregion("osrom")->base() ); |
| 123 | m_fdc->write(space, offset&3, data); |
| 98 | 124 | } |
| 99 | 125 | |
| 126 | WRITE8_MEMBER(esq1_state::mapper_w) |
| 127 | { |
| 128 | m_mapper_state = (data & 1) ^ 1; |
| 129 | |
| 130 | // printf("mapper_state = %d\n", data ^ 1); |
| 131 | } |
| 132 | |
| 133 | READ8_MEMBER(esq1_state::seqdosram_r) |
| 134 | { |
| 135 | if (m_mapper_state) |
| 136 | { |
| 137 | return m_dosram[offset]; |
| 138 | } |
| 139 | else |
| 140 | { |
| 141 | return m_seqram[offset + m_seq_bank]; |
| 142 | } |
| 143 | } |
| 144 | |
| 145 | WRITE8_MEMBER(esq1_state::seqdosram_w) |
| 146 | { |
| 147 | if (m_mapper_state) |
| 148 | { |
| 149 | m_dosram[offset] = data; |
| 150 | } |
| 151 | else |
| 152 | { |
| 153 | m_seqram[offset + m_seq_bank] = data; |
| 154 | } |
| 155 | } |
| 156 | |
| 100 | 157 | static ADDRESS_MAP_START( esq1_map, AS_PROGRAM, 8, esq1_state ) |
| 101 | 158 | AM_RANGE(0x0000, 0x1fff) AM_RAM // OSRAM |
| 102 | 159 | AM_RANGE(0x4000, 0x5fff) AM_RAM // SEQRAM |
| r15328 | r15329 | |
| 106 | 163 | AM_RANGE(0x8000, 0xffff) AM_ROM AM_REGION("osrom", 0x8000) // OS "high" ROM is always mapped here |
| 107 | 164 | ADDRESS_MAP_END |
| 108 | 165 | |
| 166 | static ADDRESS_MAP_START( sq80_map, AS_PROGRAM, 8, esq1_state ) |
| 167 | AM_RANGE(0x0000, 0x1fff) AM_RAM // OSRAM |
| 168 | AM_RANGE(0x4000, 0x5fff) AM_RAM // SEQRAM |
| 169 | // AM_RANGE(0x4000, 0x5fff) AM_READWRITE(seqdosram_r, seqdosram_w) |
| 170 | AM_RANGE(0x6000, 0x63ff) AM_DEVREADWRITE("es5503", es5503_device, read, write) |
| 171 | AM_RANGE(0x6400, 0x640f) AM_DEVREADWRITE_LEGACY("duart", duart68681_r, duart68681_w) |
| 172 | AM_RANGE(0x6c00, 0x6dff) AM_WRITE(mapper_w) |
| 173 | AM_RANGE(0x6e00, 0x6fff) AM_READWRITE(wd1772_r, wd1772_w) |
| 174 | AM_RANGE(0x7000, 0x7fff) AM_ROMBANK("osbank") |
| 175 | AM_RANGE(0x8000, 0xffff) AM_ROM AM_REGION("osrom", 0x8000) // OS "high" ROM is always mapped here |
| 176 | ADDRESS_MAP_END |
| 177 | |
| 109 | 178 | // from the schematics: |
| 110 | 179 | // |
| 111 | 180 | // DUART channel A is MIDI |
| r15328 | r15329 | |
| 137 | 206 | esq1_state *state = device->machine().driver_data<esq1_state>(); |
| 138 | 207 | // printf("DP [%02x]: %d mlo %d mhi %d tape %d\n", data, data&1, (data>>4)&1, (data>>5)&1, (data>>6)&3); |
| 139 | 208 | // printf("[%02x] bank %d => offset %x (PC=%x)\n", data, bank, bank * 0x1000, cpu_get_pc(device->machine().firstcpu)); |
| 140 | | state->membank("osbank")->set_base(state->memregion("osrom")->base() + (bank * 0x1000) ); |
| 209 | state->membank("osbank")->set_base(state->memregion("osrom")->base() + (bank * 0x1000) ); |
| 210 | |
| 211 | state->m_seq_bank = (data & 0x8) ? 0x8000 : 0x0000; |
| 212 | state->m_seq_bank += ((data>>1) & 3) * 0x2000; |
| 213 | // printf("seqram_bank = %x\n", state->m_seq_bank); |
| 141 | 214 | } |
| 142 | 215 | |
| 143 | 216 | static void duart_tx(device_t *device, int channel, UINT8 data) |
| 144 | 217 | { |
| 218 | esq1_state *state = device->machine().driver_data<esq1_state>(); |
| 219 | |
| 145 | 220 | if (channel == 1) |
| 146 | 221 | { |
| 222 | #if 0 |
| 147 | 223 | if (data >= 0x20 && data <= 0x7f) |
| 148 | 224 | { |
| 149 | 225 | printf("%c", data); |
| r15328 | r15329 | |
| 152 | 228 | { |
| 153 | 229 | printf("[%02x]", data); |
| 154 | 230 | } |
| 231 | #endif |
| 232 | |
| 233 | state->m_vfd->write_char(data); |
| 155 | 234 | } |
| 156 | 235 | } |
| 157 | 236 | |
| r15328 | r15329 | |
| 192 | 271 | |
| 193 | 272 | MCFG_DUART68681_ADD("duart", 4000000, duart_config) |
| 194 | 273 | |
| 195 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 196 | | MCFG_SCREEN_REFRESH_RATE(60) |
| 197 | | MCFG_SCREEN_UPDATE_STATIC(esq1) |
| 198 | | MCFG_SCREEN_SIZE(320, 240) |
| 199 | | MCFG_SCREEN_VISIBLE_AREA(0, 319, 1, 239) |
| 274 | MCFG_ESQ2x40_ADD("vfd") |
| 200 | 275 | |
| 201 | | MCFG_VIDEO_START(esq1) |
| 202 | | |
| 203 | 276 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| 204 | 277 | MCFG_ES5503_ADD("es5503", 7000000, esq1_doc_irq, esq1_adc_read) |
| 205 | 278 | MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) |
| 206 | 279 | MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) |
| 207 | 280 | MACHINE_CONFIG_END |
| 208 | 281 | |
| 282 | static MACHINE_CONFIG_DERIVED(sq80, esq1) |
| 283 | MCFG_CPU_MODIFY("maincpu") |
| 284 | MCFG_CPU_PROGRAM_MAP(sq80_map) |
| 285 | |
| 286 | MCFG_WD1772x_ADD(WD1772_TAG, 4000000) |
| 287 | MACHINE_CONFIG_END |
| 288 | |
| 209 | 289 | static INPUT_PORTS_START( esq1 ) |
| 210 | 290 | #if KEYBOARD_HACK |
| 211 | 291 | PORT_START("KEY0") |
| r15328 | r15329 | |
| 250 | 330 | ROM_LOAD( "esq1wavhi.bin", 0x8000, 0x8000, CRC(94c554a3) SHA1(ed0318e5253637585559e8cf24c06d6115bd18f6) ) |
| 251 | 331 | ROM_END |
| 252 | 332 | |
| 253 | | CONS( 1986, esq1, 0, 0, esq1, esq1, 0, "Ensoniq", "ESQ-1", GAME_NOT_WORKING ) |
| 333 | ROM_START( sq80 ) |
| 334 | ROM_REGION(0x10000, "osrom", 0) |
| 335 | ROM_LOAD( "sq80rom.low", 0x0000, 0x008000, CRC(97ecd9a0) SHA1(cadff16ebbc15b52cf1d3335d22dc930d430a058) ) |
| 336 | ROM_LOAD( "sq80rom.hig", 0x8000, 0x008000, CRC(f83962b1) SHA1(e3e5cf41f15a37f8bf29b88fb1c85c0fca9ea912) ) |
| 337 | |
| 338 | ROM_REGION(0x40000, "es5503", 0) |
| 339 | ROM_LOAD( "2202.bin", 0x0000, 0x010000, CRC(dffd538c) SHA1(e90f6ff3a7804b54c8a3b1b574ec9c223a6c2bf9) ) |
| 340 | ROM_LOAD( "2203.bin", 0x0000, 0x010000, CRC(9be8cceb) SHA1(1ee4d7e6d2171b44e88e464071bdc4b800b69c4a) ) |
| 341 | ROM_LOAD( "2204.bin", 0x0000, 0x010000, CRC(4937c6f7) SHA1(4505efb9b28fe6d4bcc1f79e81a70bb215c399cb) ) |
| 342 | ROM_LOAD( "2205.bin", 0x0000, 0x010000, CRC(0f917d40) SHA1(1cfae9c80088f4c90b3c9e0b284c3b91f7ff61b9) ) |
| 343 | |
| 344 | ROM_REGION(0x8000, "kpc", 0) // 68HC11 keyboard/front panel processor |
| 345 | ROM_LOAD( "sq80_kpc_150.bin", 0x000000, 0x008000, CRC(8170b728) SHA1(3ad68bb03948e51b20d2e54309baa5c02a468f7c) ) |
| 346 | ROM_END |
| 347 | |
| 348 | CONS( 1986, esq1, 0 , 0, esq1, esq1, 0, "Ensoniq", "ESQ-1", GAME_NOT_WORKING ) |
| 349 | CONS( 1988, sq80, 0, 0, sq80, esq1, 0, "Ensoniq", "SQ-80", GAME_NOT_WORKING ) |
src/mess/drivers/esq5505.c
| r15328 | r15329 | |
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | |
| 3 | | esq5505.c - Ensoniq ES5505 + ES5510 based synthesizers |
| 3 | esq5505.c - Ensoniq ES5505 + ES5510 based synthesizers and samplers |
| 4 | 4 | |
| 5 | | Ensoniq VFX, EPS-16 Plus, and SQ-1 (VFX-SD, SD-1, SQ-1 Plus, SQ-2, |
| 5 | Ensoniq VFX, VFX-SD, EPS-16 Plus, SD-1, SD-1 32, and SQ-1 (SQ-1 Plus, SQ-2, |
| 6 | 6 | and KS-32 are known to also be this architecture). |
| 7 | 7 | |
| 8 | 8 | The Taito sound system in taito_en.c is directly derived from the SQ-1. |
| 9 | 9 | |
| 10 | 10 | Driver by R. Belmont |
| 11 | 11 | |
| 12 | | 00 - harsh piano |
| 13 | | 01 - bells/chimes |
| 14 | | 04 - organ |
| 15 | | 13 - transwave brass |
| 16 | | 17 - slow string |
| 17 | | 18 - plucked string |
| 18 | | 19 - layered strings |
| 19 | | 20 - marimba |
| 20 | | 26 - Hammond |
| 21 | | 29 - slow organ |
| 22 | | 38 - nylon guitar |
| 23 | | 41 - layered strings |
| 24 | | 51/52 - RE-style slow strings |
| 25 | | 53 - RE-style fast strings |
| 26 | | 69 - orch hit |
| 27 | | 70 - organ |
| 28 | | 73 - orch hit with strings |
| 29 | | 74 - bell tone |
| 30 | | 80 - drums |
| 31 | | |
| 12 | Memory map: |
| 13 | |
| 14 | 0x000000-0x00ffff work RAM low |
| 15 | 0x200000-0x20001f OTTO (5505) regs |
| 16 | 0x240000-0x24003f ??? regs |
| 17 | 0x260000-0x2601ff ESP (5510) regs |
| 18 | 0x280000-0x28001f DUART (68681) regs |
| 19 | 0x2C0000-0x2C0003 Floppy (WD1772) regs (VFX-SD, SD-1, and EPS-16) |
| 20 | 0x300000-0x300003 EPS-16 SCSI (WD33C93, register at 300001, data at 300003) |
| 21 | 0x340000-0x3bffff EPS-16 sample RAM |
| 22 | 0xc00000-0xc3ffff OS ROM |
| 23 | 0xff0000-0xffffff work RAM hi (may or may not be mirrored with work RAM low) |
| 24 | |
| 25 | Interrupts: |
| 26 | 68681 uses custom vector 0x40 (address 0x100) |
| 27 | 5505 interrupts are on normal autovector IRQ 1 |
| 28 | |
| 32 | 29 | ***************************************************************************/ |
| 33 | 30 | |
| 34 | 31 | #include "emu.h" |
| 35 | 32 | #include "cpu/m68000/m68000.h" |
| 36 | 33 | #include "sound/es5506.h" |
| 37 | 34 | #include "machine/68681.h" |
| 35 | #include "machine/wd1772.h" |
| 36 | #include "formats/esq16_dsk.h" |
| 37 | #include "formats/mfi_dsk.h" |
| 38 | #include "formats/dfi_dsk.h" |
| 39 | #include "formats/ipf_dsk.h" |
| 38 | 40 | |
| 39 | | #define KEYBOARD_HACK (0) |
| 41 | #include "machine/esqvfd.h" |
| 40 | 42 | |
| 41 | | #if KEYBOARD_HACK |
| 42 | | static int program = 1; |
| 43 | | #endif |
| 44 | | |
| 45 | 43 | class esq5505_state : public driver_device |
| 46 | 44 | { |
| 47 | 45 | public: |
| 48 | 46 | esq5505_state(const machine_config &mconfig, device_type type, const char *tag) |
| 49 | 47 | : driver_device(mconfig, type, tag), |
| 50 | 48 | m_maincpu(*this, "maincpu"), |
| 51 | | m_duart(*this, "duart") |
| 49 | m_duart(*this, "duart"), |
| 50 | m_fdc(*this, "wd1772"), |
| 51 | m_vfd(*this, "vfd") |
| 52 | 52 | { } |
| 53 | 53 | |
| 54 | 54 | required_device<device_t> m_maincpu; |
| 55 | 55 | required_device<device_t> m_duart; |
| 56 | optional_device<wd1772_t> m_fdc; |
| 57 | optional_device<esq2x40_t> m_vfd; |
| 56 | 58 | |
| 57 | 59 | virtual void machine_reset(); |
| 58 | 60 | |
| r15328 | r15329 | |
| 61 | 63 | DECLARE_READ16_MEMBER(mc68681_r); |
| 62 | 64 | DECLARE_WRITE16_MEMBER(mc68681_w); |
| 63 | 65 | |
| 66 | bool m_bIsEPS16; |
| 67 | UINT8 m_duart_io; |
| 68 | bool m_bCalibSecondByte; |
| 69 | |
| 70 | static const floppy_format_type floppy_formats[]; |
| 71 | |
| 64 | 72 | private: |
| 65 | 73 | UINT16 es5510_dsp_ram[0x200]; |
| 66 | 74 | UINT32 es5510_gpr[0xc0]; |
| r15328 | r15329 | |
| 72 | 80 | UINT8 es5510_ram_sel; |
| 73 | 81 | }; |
| 74 | 82 | |
| 83 | const floppy_format_type esq5505_state::floppy_formats[] = { |
| 84 | FLOPPY_ESQIMG_FORMAT, FLOPPY_IPF_FORMAT, FLOPPY_MFI_FORMAT, FLOPPY_DFI_FORMAT, |
| 85 | NULL |
| 86 | }; |
| 75 | 87 | |
| 76 | | static VIDEO_START( esq5505 ) |
| 77 | | { |
| 78 | | } |
| 88 | static SLOT_INTERFACE_START( ensoniq_floppies ) |
| 89 | SLOT_INTERFACE( "35dd", FLOPPY_35_DD ) |
| 90 | SLOT_INTERFACE_END |
| 79 | 91 | |
| 80 | | static SCREEN_UPDATE_RGB32( esq5505 ) |
| 81 | | { |
| 82 | | #if KEYBOARD_HACK |
| 83 | | if( screen.machine().input().code_pressed_once( KEYCODE_Q ) ) |
| 84 | | { |
| 85 | | program--; |
| 86 | | if (program < 0) |
| 87 | | { |
| 88 | | program = 0; |
| 89 | | } |
| 90 | | printf("program to %d\n", program); |
| 91 | | } |
| 92 | | if( screen.machine().input().code_pressed_once( KEYCODE_W ) ) |
| 93 | | { |
| 94 | | program++; |
| 95 | | if (program > 127) |
| 96 | | { |
| 97 | | program = 127; |
| 98 | | } |
| 99 | | printf("program to %d\n", program); |
| 100 | | } |
| 101 | | #endif |
| 102 | | return 0; |
| 103 | | } |
| 104 | | |
| 105 | 92 | void esq5505_state::machine_reset() |
| 106 | 93 | { |
| 107 | 94 | UINT8 *ROM = machine().root_device().memregion("osrom")->base(); |
| r15328 | r15329 | |
| 111 | 98 | |
| 112 | 99 | // pick up the new vectors |
| 113 | 100 | m_maincpu->reset(); |
| 101 | |
| 102 | m_bCalibSecondByte = false; |
| 114 | 103 | } |
| 115 | 104 | |
| 116 | 105 | READ16_MEMBER(esq5505_state::es5510_dsp_r) |
| r15328 | r15329 | |
| 204 | 193 | AM_RANGE(0xfc0000, 0xffffff) AM_RAM AM_SHARE("osram") |
| 205 | 194 | ADDRESS_MAP_END |
| 206 | 195 | |
| 196 | static ADDRESS_MAP_START( vfxsd_map, AS_PROGRAM, 16, esq5505_state ) |
| 197 | AM_RANGE(0x000000, 0x00ffff) AM_RAM AM_SHARE("osram") AM_MIRROR(0x30000) |
| 198 | AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w) |
| 199 | AM_RANGE(0x260000, 0x2601ff) AM_READWRITE(es5510_dsp_r, es5510_dsp_w) |
| 200 | AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8_LEGACY("duart", duart68681_r, duart68681_w, 0x00ff) |
| 201 | AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff) |
| 202 | AM_RANGE(0x340000, 0x3bffff) AM_RAM // sequencer memory? |
| 203 | AM_RANGE(0xc00000, 0xc3ffff) AM_ROM AM_REGION("osrom", 0) |
| 204 | AM_RANGE(0xff0000, 0xffffff) AM_RAM |
| 205 | ADDRESS_MAP_END |
| 206 | |
| 207 | 207 | static ADDRESS_MAP_START( eps16_map, AS_PROGRAM, 16, esq5505_state ) |
| 208 | 208 | AM_RANGE(0x000000, 0x03ffff) AM_RAM AM_SHARE("osram") |
| 209 | 209 | AM_RANGE(0x200000, 0x20001f) AM_DEVREADWRITE_LEGACY("ensoniq", es5505_r, es5505_w) |
| 210 | 210 | AM_RANGE(0x280000, 0x28001f) AM_DEVREADWRITE8_LEGACY("duart", duart68681_r, duart68681_w, 0x00ff) |
| 211 | | AM_RANGE(0x580000, 0x77ffff) AM_RAM // sample RAM (2 MB max represented here) |
| 211 | AM_RANGE(0x2c0000, 0x2c0007) AM_DEVREADWRITE8("wd1772", wd1772_t, read, write, 0x00ff) |
| 212 | AM_RANGE(0x580000, 0x77ffff) AM_RAM // sample RAM? |
| 212 | 213 | AM_RANGE(0xc00000, 0xc0ffff) AM_ROM AM_REGION("osrom", 0) |
| 213 | 214 | ADDRESS_MAP_END |
| 214 | 215 | |
| 216 | static UINT16 esq5505_read_adc(device_t *device) |
| 217 | { |
| 218 | esq5505_state *state = device->machine().driver_data<esq5505_state>(); |
| 219 | |
| 220 | // bit 0 controls reading the battery; other bits likely |
| 221 | // control other analog sources |
| 222 | if (state->m_duart_io & 1) |
| 223 | { |
| 224 | return 0x5b00; // vRef |
| 225 | } |
| 226 | else |
| 227 | { |
| 228 | return 0x7f00; // vBattery |
| 229 | } |
| 230 | } |
| 231 | |
| 215 | 232 | static void duart_irq_handler(device_t *device, int state, UINT8 vector) |
| 216 | 233 | { |
| 217 | 234 | esq5505_state *esq5505 = device->machine().driver_data<esq5505_state>(); |
| r15328 | r15329 | |
| 230 | 247 | |
| 231 | 248 | static UINT8 duart_input(device_t *device) |
| 232 | 249 | { |
| 233 | | return 0; |
| 250 | esq5505_state *state = device->machine().driver_data<esq5505_state>(); |
| 251 | |
| 252 | return state->m_duart_io; |
| 234 | 253 | } |
| 235 | 254 | |
| 236 | 255 | static void duart_output(device_t *device, UINT8 data) |
| 237 | 256 | { |
| 238 | | // printf("DUART output: %02x\n", data); |
| 257 | esq5505_state *state = device->machine().driver_data<esq5505_state>(); |
| 258 | |
| 259 | state->m_duart_io = data; |
| 260 | // printf("DUART output: %02x (PC=%x)\n", data, cpu_get_pc(state->m_maincpu)); |
| 239 | 261 | } |
| 240 | 262 | |
| 241 | 263 | static void duart_tx(device_t *device, int channel, UINT8 data) |
| 242 | 264 | { |
| 243 | | if (data >= 0x20 && data <= 0x7f) |
| 265 | esq5505_state *state = device->machine().driver_data<esq5505_state>(); |
| 266 | |
| 267 | // printf("ch %d: [%02x]\n", channel, data); |
| 268 | |
| 269 | if (channel == 1) |
| 244 | 270 | { |
| 245 | | printf("%c", data); |
| 271 | state->m_vfd->write_char(data); |
| 272 | |
| 273 | // c023ea = Rx B on vfxsd calib at c033ba |
| 274 | if (state->m_bCalibSecondByte) |
| 275 | { |
| 276 | // printf("Calibrate second byte %02x\n", data); |
| 277 | duart68681_rx_data(state->m_duart, 1, (UINT8)(FPTR)0xff); // this is the correct response for "calibration OK" |
| 278 | state->m_bCalibSecondByte = false; |
| 279 | } |
| 280 | else if (data == 0xfb) // request calibration |
| 281 | { |
| 282 | // printf("KPC command, waiting on second byte (PC=%x)\n", cpu_get_pc(state->m_maincpu)); |
| 283 | state->m_bCalibSecondByte = true; |
| 284 | } |
| 285 | else |
| 286 | { |
| 287 | // EPS-16+ wants a throwaway reply byte for each byte sent to the KPC |
| 288 | // VFX-SD and SD-1 definitely don't :) |
| 289 | if (state->m_bIsEPS16) |
| 290 | { |
| 291 | // 0xe7 must respond with any byte that isn't 0xc8 or the ROM dies. |
| 292 | // 0x71 must respond with anything (return not checked) |
| 293 | |
| 294 | duart68681_rx_data(state->m_duart, 1, (UINT8)(FPTR)0x00); // actual value of response is never checked |
| 295 | } |
| 296 | } |
| 297 | |
| 246 | 298 | } |
| 247 | | else |
| 248 | | { |
| 249 | | printf("[%02x]", data); |
| 250 | | } |
| 251 | 299 | } |
| 252 | 300 | |
| 253 | 301 | static const duart68681_config duart_config = |
| r15328 | r15329 | |
| 265 | 313 | { |
| 266 | 314 | "waverom", /* Bank 0 */ |
| 267 | 315 | "waverom", /* Bank 1 */ |
| 268 | | NULL /* irq */ |
| 316 | NULL, /* irq */ |
| 317 | esq5505_read_adc |
| 269 | 318 | }; |
| 270 | 319 | |
| 271 | 320 | static MACHINE_CONFIG_START( vfx, esq5505_state ) |
| 272 | | MCFG_CPU_ADD("maincpu", M68000, 16000000) |
| 321 | MCFG_CPU_ADD("maincpu", M68000, 8000000) |
| 273 | 322 | MCFG_CPU_PROGRAM_MAP(vfx_map) |
| 274 | 323 | |
| 275 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 276 | | MCFG_SCREEN_REFRESH_RATE(60) |
| 277 | | MCFG_SCREEN_UPDATE_STATIC(esq5505) |
| 278 | | MCFG_SCREEN_SIZE(320, 240) |
| 279 | | MCFG_SCREEN_VISIBLE_AREA(0, 319, 1, 239) |
| 324 | MCFG_ESQ2x40_ADD("vfd") |
| 280 | 325 | |
| 281 | | MCFG_VIDEO_START(esq5505) |
| 282 | | |
| 283 | 326 | MCFG_DUART68681_ADD("duart", 2000000, duart_config) |
| 284 | 327 | |
| 285 | 328 | MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") |
| r15328 | r15329 | |
| 292 | 335 | static MACHINE_CONFIG_DERIVED(eps16, vfx) |
| 293 | 336 | MCFG_CPU_MODIFY( "maincpu" ) |
| 294 | 337 | MCFG_CPU_PROGRAM_MAP(eps16_map) |
| 338 | |
| 339 | MCFG_WD1772x_ADD("wd1772", 8000000) |
| 340 | MCFG_FLOPPY_DRIVE_ADD("fd0", ensoniq_floppies, "35dd", 0, esq5505_state::floppy_formats) |
| 295 | 341 | MACHINE_CONFIG_END |
| 296 | 342 | |
| 297 | | #if KEYBOARD_HACK |
| 298 | | static INPUT_CHANGED( key_stroke ) |
| 299 | | { |
| 300 | | esq5505_state *state = device.machine().driver_data<esq5505_state>(); |
| 343 | static MACHINE_CONFIG_DERIVED(vfxsd, vfx) |
| 344 | MCFG_CPU_MODIFY( "maincpu" ) |
| 345 | MCFG_CPU_PROGRAM_MAP(vfxsd_map) |
| 301 | 346 | |
| 302 | | // send a MIDI Note On |
| 303 | | if (oldval == 0 && newval == 1) |
| 304 | | { |
| 305 | | if ((UINT8)(FPTR)param == 0x40) |
| 306 | | { |
| 307 | | duart68681_rx_data(state->m_duart, 0, (UINT8)(FPTR)0xc0); // program change |
| 308 | | duart68681_rx_data(state->m_duart, 0, program); // program |
| 309 | | } |
| 310 | | else |
| 311 | | { |
| 312 | | duart68681_rx_data(state->m_duart, 0, (UINT8)(FPTR)0x90); // note on |
| 313 | | duart68681_rx_data(state->m_duart, 0, (UINT8)(FPTR)param); |
| 314 | | duart68681_rx_data(state->m_duart, 0, (UINT8)(FPTR)0x7f); |
| 315 | | } |
| 316 | | } |
| 317 | | else if (oldval == 1 && newval == 0) |
| 318 | | { |
| 319 | | if ((UINT8)(FPTR)param != 0x40) |
| 320 | | { |
| 321 | | duart68681_rx_data(state->m_duart, 0, (UINT8)(FPTR)0x80); // note off |
| 322 | | duart68681_rx_data(state->m_duart, 0, (UINT8)(FPTR)param); |
| 323 | | duart68681_rx_data(state->m_duart, 0, (UINT8)(FPTR)0x7f); |
| 324 | | } |
| 325 | | } |
| 326 | | } |
| 327 | | #endif |
| 347 | MCFG_WD1772x_ADD("wd1772", 8000000) |
| 348 | MCFG_FLOPPY_DRIVE_ADD("fd0", ensoniq_floppies, "35dd", 0, esq5505_state::floppy_formats) |
| 349 | MACHINE_CONFIG_END |
| 328 | 350 | |
| 329 | 351 | static INPUT_PORTS_START( vfx ) |
| 330 | | #if KEYBOARD_HACK |
| 331 | | PORT_START("KEY0") |
| 332 | | PORT_BIT(0x0001, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_A) PORT_CHAR('a') PORT_CHAR('A') PORT_CHANGED(key_stroke, 0x40) |
| 333 | | PORT_BIT(0x0002, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S') PORT_CHANGED(key_stroke, 0x41) |
| 334 | | PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D') PORT_CHANGED(key_stroke, 0x42) |
| 335 | | PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F) PORT_CHAR('f') PORT_CHAR('F') PORT_CHANGED(key_stroke, 0x43) |
| 336 | | PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_G) PORT_CHAR('g') PORT_CHAR('G') PORT_CHANGED(key_stroke, 0x44) |
| 337 | | PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_H) PORT_CHAR('h') PORT_CHAR('H') PORT_CHANGED(key_stroke, 0x45) |
| 338 | | PORT_BIT(0x0040, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_J) PORT_CHAR('j') PORT_CHAR('J') PORT_CHANGED(key_stroke, 0x46) |
| 339 | | PORT_BIT(0x0080, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K') PORT_CHANGED(key_stroke, 0x47) |
| 340 | | PORT_BIT(0x0100, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L') PORT_CHANGED(key_stroke, 0x48) |
| 341 | | PORT_BIT(0x0200, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q') PORT_CHANGED(key_stroke, 0x49) |
| 342 | | PORT_BIT(0x0400, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W') PORT_CHANGED(key_stroke, 0x4a) |
| 343 | | PORT_BIT(0x0800, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_B) PORT_CHAR('e') PORT_CHAR('E') PORT_CHANGED(key_stroke, 0x4b) |
| 344 | | PORT_BIT(0x1000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('r') PORT_CHAR('R') PORT_CHANGED(key_stroke, 0x4c) |
| 345 | | PORT_BIT(0x2000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('t') PORT_CHAR('T') PORT_CHANGED(key_stroke, 0x4d) |
| 346 | | PORT_BIT(0x4000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('y') PORT_CHAR('Y') PORT_CHANGED(key_stroke, 0x4e) |
| 347 | | PORT_BIT(0x8000, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_R) PORT_CHAR('u') PORT_CHAR('U') PORT_CHANGED(key_stroke, 0x4f) |
| 348 | | #endif |
| 349 | 352 | INPUT_PORTS_END |
| 350 | 353 | |
| 351 | 354 | ROM_START( vfx ) |
| r15328 | r15329 | |
| 358 | 361 | ROM_LOAD( "vfx-waves-2.bin", 0x100000, 0x080000, NO_DUMP ) |
| 359 | 362 | ROM_END |
| 360 | 363 | |
| 364 | ROM_START( vfxsd ) |
| 365 | ROM_REGION(0x40000, "osrom", 0) |
| 366 | ROM_LOAD16_BYTE( "vfxsd_200_lower.bin", 0x000000, 0x010000, CRC(7bd31aea) SHA1(812bf73c4861a5d963f128def14a4a98171c93ad) ) |
| 367 | ROM_LOAD16_BYTE( "vfxsd_200_upper.bin", 0x000001, 0x010000, CRC(9a40efa2) SHA1(e38a2a4514519c1573361cb1526139bfcf94e45a) ) |
| 368 | |
| 369 | ROM_REGION(0x200000, "waverom", ROMREGION_ERASE00) |
| 370 | ROM_LOAD( "vfxsd-waves-1.bin", 0x000000, 0x080000, NO_DUMP ) |
| 371 | ROM_LOAD( "vfxsd-waves-2.bin", 0x100000, 0x080000, NO_DUMP ) |
| 372 | ROM_END |
| 373 | |
| 374 | ROM_START( sd1 ) |
| 375 | ROM_REGION(0x40000, "osrom", 0) |
| 376 | ROM_LOAD16_BYTE( "sd1_410_lo.bin", 0x000000, 0x020000, CRC(faa613a6) SHA1(60066765cddfa9d3b5d09057d8f83fb120f4e65e) ) |
| 377 | ROM_LOAD16_BYTE( "sd1_410_hi.bin", 0x000001, 0x010000, CRC(618c0aa8) SHA1(74acf458aa1d04a0a7a0cd5855c49e6855dbd301) ) |
| 378 | |
| 379 | ROM_REGION(0x200000, "waverom", ROMREGION_ERASE00) |
| 380 | ROM_LOAD( "sd1-waves-1.bin", 0x000000, 0x080000, NO_DUMP ) |
| 381 | ROM_LOAD( "sd1-waves-2.bin", 0x100000, 0x080000, NO_DUMP ) |
| 382 | ROM_END |
| 383 | |
| 384 | ROM_START( sd132 ) |
| 385 | ROM_REGION(0x40000, "osrom", 0) |
| 386 | ROM_LOAD16_BYTE( "sd1_32_402_lo.bin", 0x000000, 0x020000, CRC(5da2572b) SHA1(cb6ddd637ed13bfeb40a99df56000479e63fc8ec) ) |
| 387 | ROM_LOAD16_BYTE( "sd1_32_402_hi.bin", 0x000001, 0x010000, CRC(fc45c210) SHA1(23b81ebd9176112e6eae0c7c75b39fcb1656c953) ) |
| 388 | |
| 389 | ROM_REGION(0x200000, "waverom", ROMREGION_ERASE00) |
| 390 | ROM_LOAD( "sd1-waves-1.bin", 0x000000, 0x080000, NO_DUMP ) |
| 391 | ROM_LOAD( "sd1-waves-2.bin", 0x100000, 0x080000, NO_DUMP ) |
| 392 | ROM_END |
| 393 | |
| 361 | 394 | ROM_START( sq1 ) |
| 362 | 395 | ROM_REGION(0x20000, "osrom", 0) |
| 363 | 396 | ROM_LOAD16_BYTE( "esq5505lo.bin", 0x000000, 0x010000, CRC(b004cf05) SHA1(567b0dae2e35b06e39da108f9c041fd9bc38fa35) ) |
| r15328 | r15329 | |
| 376 | 409 | ROM_REGION(0x200000, "waverom", ROMREGION_ERASE00) // did the EPS-16 have ROM sounds or is it a pure sampler? |
| 377 | 410 | ROM_END |
| 378 | 411 | |
| 379 | | CONS( 1989, vfx, 0, 0, vfx, vfx, 0, "Ensoniq", "VFX", GAME_NOT_WORKING ) |
| 380 | | CONS( 1990, sq1, 0, 0, vfx, vfx, 0, "Ensoniq", "SQ-1", GAME_NOT_WORKING ) |
| 381 | | CONS( 1990, eps16, 0, 0, eps16, vfx, 0, "Ensoniq", "EPS-16 Plus", GAME_NOT_WORKING ) |
| 412 | static DRIVER_INIT(common) |
| 413 | { |
| 414 | esq5505_state *state = machine.driver_data<esq5505_state>(); |
| 382 | 415 | |
| 416 | state->m_bIsEPS16 = false; |
| 417 | state->m_duart_io = 0; |
| 418 | |
| 419 | floppy_connector *con = machine.device<floppy_connector>("fd0"); |
| 420 | floppy_image_device *floppy = con ? con->get_device() : 0; |
| 421 | if (floppy) |
| 422 | { |
| 423 | state->m_fdc->set_floppy(floppy); |
| 424 | floppy->ss_w(0); |
| 425 | } |
| 426 | } |
| 427 | |
| 428 | static DRIVER_INIT(eps16) |
| 429 | { |
| 430 | esq5505_state *state = machine.driver_data<esq5505_state>(); |
| 431 | |
| 432 | DRIVER_INIT_CALL(common); |
| 433 | state->m_bIsEPS16 = true; |
| 434 | } |
| 435 | |
| 436 | CONS( 1989, vfx, 0, 0, vfx, vfx, common, "Ensoniq", "VFX", GAME_NOT_WORKING ) // 2x40 VFD |
| 437 | CONS( 1989, vfxsd, 0, 0, vfxsd, vfx, common, "Ensoniq", "VFX-SD", GAME_NOT_WORKING ) // 2x40 VFD |
| 438 | CONS( 1990, sd1, 0, 0, vfxsd, vfx, common, "Ensoniq", "SD-1", GAME_NOT_WORKING ) // 2x40 VFD |
| 439 | CONS( 1990, sd132, 0, 0, vfxsd, vfx, common, "Ensoniq", "SD-1 32", GAME_NOT_WORKING ) // 2x40 VFD |
| 440 | CONS( 1990, sq1, 0, 0, vfx, vfx, common, "Ensoniq", "SQ-1", GAME_NOT_WORKING ) // LCD of some sort |
| 441 | CONS( 1990, eps16, 0, 0, eps16, vfx, eps16, "Ensoniq", "EPS-16 Plus", GAME_NOT_WORKING ) // 1x40? (20? 32?) VFD |
| 442 | |