src/mess/drivers/rainbow.c
| r15098 | r15099 | |
| 3 | 3 | DEC Rainbow 100 |
| 4 | 4 | |
| 5 | 5 | 04/01/2012 Skeleton driver. |
| 6 | | |
| 6 | |
| 7 | TODO: Z80 boots, but no Z80/8088 comms happen (neither CPU writes |
| 8 | to the latch) |
| 9 | |
| 7 | 10 | ****************************************************************************/ |
| 8 | 11 | #include "emu.h" |
| 9 | 12 | #include "cpu/i86/i86.h" |
| 10 | 13 | #include "cpu/z80/z80.h" |
| 11 | 14 | #include "video/vtvideo.h" |
| 15 | #include "machine/wd17xx.h" |
| 16 | #include "imagedev/flopdrv.h" |
| 12 | 17 | |
| 13 | 18 | class rainbow_state : public driver_device |
| 14 | 19 | { |
| 15 | 20 | public: |
| 16 | 21 | rainbow_state(const machine_config &mconfig, device_type type, const char *tag) |
| 17 | 22 | : driver_device(mconfig, type, tag), |
| 18 | | m_crtc(*this, "vt100_video") |
| 19 | | , |
| 23 | m_crtc(*this, "vt100_video"), |
| 24 | m_i8088(*this, "maincpu"), |
| 25 | m_z80(*this, "subcpu"), |
| 26 | m_fdc(*this, "wd1793"), |
| 20 | 27 | m_p_ram(*this, "p_ram"){ } |
| 21 | 28 | |
| 22 | 29 | required_device<device_t> m_crtc; |
| 30 | required_device<device_t> m_i8088; |
| 31 | required_device<device_t> m_z80; |
| 32 | required_device<device_t> m_fdc; |
| 23 | 33 | required_shared_ptr<UINT8> m_p_ram; |
| 24 | 34 | UINT8 m_diagnostic; |
| 25 | 35 | |
| 36 | virtual void machine_start(); |
| 37 | |
| 26 | 38 | DECLARE_READ8_MEMBER(read_video_ram_r); |
| 27 | 39 | DECLARE_WRITE8_MEMBER(clear_video_interrupt); |
| 28 | 40 | |
| 29 | 41 | DECLARE_READ8_MEMBER(diagnostic_r); |
| 30 | 42 | DECLARE_WRITE8_MEMBER(diagnostic_w); |
| 43 | |
| 44 | DECLARE_READ8_MEMBER(share_8088_r); |
| 45 | DECLARE_WRITE8_MEMBER(share_8088_w); |
| 46 | DECLARE_READ8_MEMBER(share_z80_r); |
| 47 | DECLARE_WRITE8_MEMBER(share_z80_w); |
| 48 | |
| 49 | DECLARE_READ8_MEMBER(i8088_latch_r); |
| 50 | DECLARE_WRITE8_MEMBER(i8088_latch_w); |
| 51 | DECLARE_READ8_MEMBER(z80_latch_r); |
| 52 | DECLARE_WRITE8_MEMBER(z80_latch_w); |
| 53 | |
| 54 | DECLARE_WRITE8_MEMBER(z80_diskdiag_read_w); |
| 55 | DECLARE_WRITE8_MEMBER(z80_diskdiag_write_w); |
| 56 | |
| 57 | bool m_zflip; // Z80 alternate memory map with A15 inverted |
| 58 | |
| 59 | private: |
| 60 | UINT8 m_shared[64*1024]; // 62k of shared RAM (to make the code simpler, we have 64k and ignore the lower 2k) |
| 61 | UINT8 m_z80_private[0x800]; // Z80 private 2K |
| 62 | UINT8 m_8088_private[0x800]; // 8088 private 2K |
| 63 | UINT8 m_z80_mailbox, m_8088_mailbox; |
| 31 | 64 | }; |
| 32 | 65 | |
| 66 | void rainbow_state::machine_start() |
| 67 | { |
| 68 | save_item(NAME(m_shared)); |
| 69 | save_item(NAME(m_z80_private)); |
| 70 | save_item(NAME(m_8088_private)); |
| 71 | save_item(NAME(m_z80_mailbox)); |
| 72 | save_item(NAME(m_8088_mailbox)); |
| 73 | save_item(NAME(m_zflip)); |
| 74 | } |
| 33 | 75 | |
| 34 | 76 | static ADDRESS_MAP_START( rainbow8088_map, AS_PROGRAM, 8, rainbow_state) |
| 35 | 77 | ADDRESS_MAP_UNMAP_HIGH |
| 36 | | AM_RANGE(0x00000, 0x1ffff) AM_RAM |
| 78 | AM_RANGE(0x00000, 0x0ffff) AM_READWRITE(share_8088_r, share_8088_w) |
| 79 | AM_RANGE(0x10000, 0x1ffff) AM_RAM |
| 37 | 80 | AM_RANGE(0xec000, 0xedfff) AM_RAM |
| 38 | 81 | AM_RANGE(0xee000, 0xeffff) AM_RAM AM_SHARE("p_ram") |
| 39 | 82 | AM_RANGE(0xf0000, 0xfffff) AM_ROM |
| r15098 | r15099 | |
| 42 | 85 | static ADDRESS_MAP_START( rainbow8088_io , AS_IO, 8, rainbow_state) |
| 43 | 86 | ADDRESS_MAP_UNMAP_HIGH |
| 44 | 87 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 88 | AM_RANGE (0x00, 0x00) AM_READWRITE(i8088_latch_r, i8088_latch_w) |
| 45 | 89 | // 0x04 Video processor DC011 |
| 46 | 90 | AM_RANGE (0x04, 0x04) AM_DEVWRITE_LEGACY("vt100_video", vt_video_dc011_w) |
| 47 | 91 | |
| r15098 | r15099 | |
| 52 | 96 | |
| 53 | 97 | static ADDRESS_MAP_START(rainbowz80_mem, AS_PROGRAM, 8, rainbow_state) |
| 54 | 98 | ADDRESS_MAP_UNMAP_HIGH |
| 55 | | AM_RANGE( 0x0000, 0xffff ) AM_RAM |
| 99 | AM_RANGE( 0x0000, 0xffff ) AM_READWRITE(share_z80_r, share_z80_w) |
| 56 | 100 | ADDRESS_MAP_END |
| 57 | 101 | |
| 58 | 102 | static ADDRESS_MAP_START( rainbowz80_io, AS_IO, 8, rainbow_state) |
| 59 | 103 | ADDRESS_MAP_UNMAP_HIGH |
| 60 | 104 | ADDRESS_MAP_GLOBAL_MASK(0xff) |
| 105 | AM_RANGE(0x00, 0x00) AM_READWRITE(z80_latch_r, z80_latch_w) |
| 106 | AM_RANGE(0x20, 0x20) AM_WRITE(z80_diskdiag_read_w) |
| 107 | AM_RANGE(0x21, 0x21) AM_WRITE(z80_diskdiag_write_w) |
| 108 | |
| 109 | AM_RANGE(0x60, 0x60) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_status_r, wd17xx_command_w) |
| 110 | AM_RANGE(0x61, 0x61) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_track_r, wd17xx_track_w) |
| 111 | AM_RANGE(0x62, 0x62) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_sector_r, wd17xx_sector_w) |
| 112 | AM_RANGE(0x63, 0x63) AM_DEVREADWRITE_LEGACY("wd1793", wd17xx_data_r, wd17xx_data_w) |
| 61 | 113 | ADDRESS_MAP_END |
| 62 | 114 | |
| 63 | 115 | /* Input ports */ |
| r15098 | r15099 | |
| 67 | 119 | |
| 68 | 120 | static MACHINE_RESET( rainbow ) |
| 69 | 121 | { |
| 122 | rainbow_state *state = machine.driver_data<rainbow_state>(); |
| 123 | |
| 124 | state->m_zflip = true; |
| 70 | 125 | } |
| 71 | 126 | |
| 72 | 127 | static SCREEN_UPDATE_IND16( rainbow ) |
| r15098 | r15099 | |
| 76 | 131 | return 0; |
| 77 | 132 | } |
| 78 | 133 | |
| 134 | READ8_MEMBER(rainbow_state::share_z80_r) |
| 135 | { |
| 136 | if (m_zflip) |
| 137 | { |
| 138 | if (offset < 0x8000) |
| 139 | { |
| 140 | return m_shared[offset + 0x8000]; |
| 141 | } |
| 142 | else if (offset < 0x8800) |
| 143 | { |
| 144 | return m_z80_private[offset & 0x7ff]; |
| 145 | } |
| 146 | |
| 147 | return m_shared[offset ^ 0x8000]; |
| 148 | } |
| 149 | else |
| 150 | { |
| 151 | if (offset < 0x800) |
| 152 | { |
| 153 | return m_z80_private[offset]; |
| 154 | } |
| 155 | |
| 156 | return m_shared[offset-0x800]; |
| 157 | } |
| 158 | |
| 159 | return 0xff; |
| 160 | } |
| 161 | |
| 162 | WRITE8_MEMBER(rainbow_state::share_z80_w) |
| 163 | { |
| 164 | if (m_zflip) |
| 165 | { |
| 166 | if (offset < 0x8000) |
| 167 | { |
| 168 | m_shared[offset + 0x8000] = data; |
| 169 | } |
| 170 | else if (offset < 0x8800) |
| 171 | { |
| 172 | m_z80_private[offset & 0x7ff] = data; |
| 173 | } |
| 174 | |
| 175 | m_shared[offset ^ 0x8000] = data; |
| 176 | } |
| 177 | else |
| 178 | { |
| 179 | if (offset < 0x800) |
| 180 | { |
| 181 | m_z80_private[offset] = data; |
| 182 | } |
| 183 | else |
| 184 | { |
| 185 | m_shared[offset-0x800] = data; |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | READ8_MEMBER(rainbow_state::share_8088_r) |
| 191 | { |
| 192 | if (offset < 0x800) |
| 193 | { |
| 194 | return m_8088_private[offset]; |
| 195 | } |
| 196 | |
| 197 | return m_shared[offset]; |
| 198 | } |
| 199 | |
| 200 | WRITE8_MEMBER(rainbow_state::share_8088_w) |
| 201 | { |
| 202 | if (offset < 0x800) |
| 203 | { |
| 204 | m_8088_private[offset] = data; |
| 205 | } |
| 206 | else |
| 207 | { |
| 208 | m_shared[offset] = data; |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | READ8_MEMBER(rainbow_state::i8088_latch_r) |
| 213 | { |
| 214 | return m_8088_mailbox; |
| 215 | } |
| 216 | |
| 217 | WRITE8_MEMBER(rainbow_state::i8088_latch_w) |
| 218 | { |
| 219 | // todo: this should trigger IRQ 27 vector 0x9c on the i8088 |
| 220 | m_z80_mailbox = data; |
| 221 | } |
| 222 | |
| 223 | READ8_MEMBER(rainbow_state::z80_latch_r) |
| 224 | { |
| 225 | device_set_input_line(m_z80, 0, CLEAR_LINE); |
| 226 | return m_z80_mailbox; |
| 227 | } |
| 228 | |
| 229 | WRITE8_MEMBER(rainbow_state::z80_latch_w) |
| 230 | { |
| 231 | device_set_input_line_and_vector(m_z80, 0, ASSERT_LINE, 0xf7); |
| 232 | m_8088_mailbox = data; |
| 233 | } |
| 234 | |
| 235 | WRITE8_MEMBER(rainbow_state::z80_diskdiag_read_w) |
| 236 | { |
| 237 | m_zflip = true; |
| 238 | } |
| 239 | |
| 240 | WRITE8_MEMBER(rainbow_state::z80_diskdiag_write_w) |
| 241 | { |
| 242 | m_zflip = false; |
| 243 | } |
| 244 | |
| 79 | 245 | READ8_MEMBER( rainbow_state::read_video_ram_r ) |
| 80 | 246 | { |
| 81 | 247 | return m_p_ram[offset]; |
| r15098 | r15099 | |
| 121 | 287 | GFXDECODE_ENTRY( "chargen", 0x0000, rainbow_charlayout, 0, 1 ) |
| 122 | 288 | GFXDECODE_END |
| 123 | 289 | |
| 290 | // Rainbow Z80 polls only, no IRQ/DRQ are connected |
| 291 | const wd17xx_interface rainbow_wd17xx_interface = |
| 292 | { |
| 293 | DEVCB_NULL, |
| 294 | DEVCB_NULL, |
| 295 | DEVCB_NULL, |
| 296 | {FLOPPY_0, FLOPPY_1} |
| 297 | }; |
| 298 | |
| 299 | static const floppy_interface floppy_intf = |
| 300 | { |
| 301 | DEVCB_NULL, |
| 302 | DEVCB_NULL, |
| 303 | DEVCB_NULL, |
| 304 | DEVCB_NULL, |
| 305 | DEVCB_NULL, |
| 306 | FLOPPY_STANDARD_5_25_SSDD, |
| 307 | LEGACY_FLOPPY_OPTIONS_NAME(default), |
| 308 | "floppy_5_25", |
| 309 | NULL |
| 310 | }; |
| 311 | |
| 124 | 312 | static MACHINE_CONFIG_START( rainbow, rainbow_state ) |
| 125 | 313 | /* basic machine hardware */ |
| 126 | 314 | MCFG_CPU_ADD("maincpu",I8088, XTAL_24_0734MHz / 5) |
| r15098 | r15099 | |
| 130 | 318 | MCFG_CPU_ADD("subcpu",Z80, XTAL_24_0734MHz / 6) |
| 131 | 319 | MCFG_CPU_PROGRAM_MAP(rainbowz80_mem) |
| 132 | 320 | MCFG_CPU_IO_MAP(rainbowz80_io) |
| 133 | | MCFG_DEVICE_DISABLE() |
| 134 | 321 | |
| 135 | 322 | MCFG_MACHINE_RESET(rainbow) |
| 136 | 323 | |
| r15098 | r15099 | |
| 145 | 332 | MCFG_PALETTE_LENGTH(2) |
| 146 | 333 | MCFG_PALETTE_INIT(monochrome_green) |
| 147 | 334 | MCFG_VT100_VIDEO_ADD("vt100_video", video_interface) |
| 335 | |
| 336 | MCFG_FD1793_ADD("wd1793", rainbow_wd17xx_interface ) |
| 337 | MCFG_LEGACY_FLOPPY_2_DRIVES_ADD(floppy_intf) |
| 148 | 338 | MACHINE_CONFIG_END |
| 149 | 339 | |
| 150 | 340 | /* ROM definition */ |