trunk/src/mess/drivers/applix.c
| r22631 | r22632 | |
| 18 | 18 | - Keyboard is a standard pc keyboard |
| 19 | 19 | - Sound is stereo dac-sound, plus an analog output. Details unknown. |
| 20 | 20 | |
| 21 | In non-debug mode it runs for a few seconds then freezes requiring MESS |
| 22 | to be forceably closed. In debug mode, it can be seen that a processor |
| 23 | exeception occurs, although sometimes the cpu 'just stops', causing a |
| 24 | MESS freeze. Obviously the real machine doesn't do these things. |
| 25 | |
| 21 | 26 | ****************************************************************************/ |
| 22 | 27 | |
| 23 | 28 | #include "emu.h" |
| 24 | 29 | #include "cpu/m68000/m68000.h" |
| 25 | 30 | #include "video/mc6845.h" |
| 31 | #include "machine/6522via.h" |
| 26 | 32 | |
| 27 | 33 | |
| 28 | 34 | class applix_state : public driver_device |
| r22631 | r22632 | |
| 30 | 36 | public: |
| 31 | 37 | applix_state(const machine_config &mconfig, device_type type, const char *tag) |
| 32 | 38 | : driver_device(mconfig, type, tag), |
| 33 | | m_maincpu(*this, "maincpu"), |
| 34 | | m_crtc(*this, "crtc") |
| 35 | | , |
| 39 | m_maincpu(*this, "maincpu"), |
| 40 | m_crtc(*this, "crtc"), |
| 41 | m_via(*this, "via6522"), |
| 36 | 42 | m_base(*this, "base"){ } |
| 37 | 43 | |
| 38 | | required_device<cpu_device> m_maincpu; |
| 39 | | required_device<mc6845_device> m_crtc; |
| 40 | 44 | DECLARE_READ16_MEMBER(applix_inputs_r); |
| 41 | 45 | DECLARE_WRITE16_MEMBER(applix_index_w); |
| 42 | 46 | DECLARE_WRITE16_MEMBER(applix_register_w); |
| 43 | | required_shared_ptr<UINT16> m_base; |
| 47 | DECLARE_WRITE16_MEMBER(palette_w); |
| 48 | DECLARE_WRITE16_MEMBER(analog_latch_w); |
| 49 | DECLARE_WRITE16_MEMBER(dac_latch_w); |
| 50 | DECLARE_WRITE16_MEMBER(video_latch_w); |
| 51 | DECLARE_READ8_MEMBER(applix_pa_r); |
| 52 | DECLARE_READ8_MEMBER(applix_pb_r); |
| 53 | DECLARE_WRITE8_MEMBER(applix_pa_w); |
| 54 | DECLARE_WRITE8_MEMBER(applix_pb_w); |
| 55 | DECLARE_WRITE_LINE_MEMBER(vsync_w); |
| 56 | UINT8 m_pa; |
| 57 | UINT8 m_pb; |
| 58 | UINT8 m_analog_latch; |
| 59 | UINT8 m_dac_latch; |
| 60 | UINT8 m_video_latch; |
| 61 | UINT8 m_palette_latch[4]; |
| 44 | 62 | virtual void machine_reset(); |
| 45 | 63 | virtual void video_start(); |
| 46 | 64 | virtual void palette_init(); |
| 65 | required_device<cpu_device> m_maincpu; |
| 66 | required_device<mc6845_device> m_crtc; |
| 67 | required_device<via6522_device> m_via; |
| 68 | required_shared_ptr<UINT16> m_base; |
| 47 | 69 | }; |
| 48 | 70 | |
| 71 | // dac-latch seems to be: |
| 72 | // bit 7 cassette relay, low=on |
| 73 | // bit 6,5,4 sound outputs |
| 74 | // bit 3 cassette LED, low=on |
| 75 | // bit 2,1,0 joystick |
| 76 | WRITE16_MEMBER( applix_state::dac_latch_w ) |
| 77 | {//printf("%X ",data); |
| 78 | if (ACCESSING_BITS_0_7) |
| 79 | m_dac_latch = data; |
| 80 | } |
| 81 | |
| 82 | WRITE16_MEMBER( applix_state::analog_latch_w ) |
| 83 | {//printf("%X ",data); |
| 84 | if (ACCESSING_BITS_0_7) |
| 85 | m_analog_latch = data; |
| 86 | } |
| 87 | |
| 88 | //cent = odd, video = even |
| 89 | WRITE16_MEMBER( applix_state::palette_w ) |
| 90 | { |
| 91 | offset >>= 4; |
| 92 | if (ACCESSING_BITS_0_7) |
| 93 | {} //centronics |
| 94 | else |
| 95 | m_palette_latch[offset] = (data >> 8) & 15; |
| 96 | } |
| 97 | |
| 98 | WRITE16_MEMBER( applix_state::video_latch_w ) |
| 99 | {//printf("%X ",data); |
| 100 | if (ACCESSING_BITS_0_7) |
| 101 | m_video_latch = data; |
| 102 | } |
| 103 | |
| 49 | 104 | WRITE16_MEMBER( applix_state::applix_index_w ) |
| 50 | 105 | { |
| 51 | | m_crtc->address_w( space, offset, data >> 8 ); |
| 106 | if (ACCESSING_BITS_8_15) |
| 107 | m_crtc->address_w( space, offset, data >> 8 ); |
| 52 | 108 | } |
| 53 | 109 | |
| 54 | 110 | WRITE16_MEMBER( applix_state::applix_register_w ) |
| 55 | 111 | { |
| 56 | | m_crtc->register_w( space, offset, data >> 8 ); |
| 112 | if (ACCESSING_BITS_8_15) |
| 113 | m_crtc->register_w( space, offset, data >> 8 ); |
| 57 | 114 | } |
| 58 | 115 | |
| 59 | 116 | READ16_MEMBER( applix_state::applix_inputs_r ) |
| r22631 | r22632 | |
| 62 | 119 | // bits 2,3 joystick in |
| 63 | 120 | // bit 1 cassette in |
| 64 | 121 | // bit 0 something to do with audio |
| 65 | | return 0; |
| 122 | return 0x70; // video test, screen changes colours. This is the only thing working atm. |
| 66 | 123 | } |
| 67 | 124 | |
| 68 | | // dac-latch seems to be: |
| 69 | | // bit 7 cassette relay, low=on |
| 70 | | // bit 6,5,4 sound outputs |
| 71 | | // bit 3 cassette LED, low=on |
| 72 | | // bit 2,1,0 joystick |
| 125 | READ8_MEMBER( applix_state::applix_pa_r ) |
| 126 | { |
| 127 | return m_pa; |
| 128 | } |
| 73 | 129 | |
| 130 | READ8_MEMBER( applix_state::applix_pb_r ) |
| 131 | { |
| 132 | return m_pb; |
| 133 | } |
| 134 | |
| 135 | WRITE8_MEMBER( applix_state::applix_pa_w ) |
| 136 | { |
| 137 | m_pa = data; |
| 138 | } |
| 139 | |
| 140 | WRITE8_MEMBER( applix_state::applix_pb_w ) |
| 141 | {//printf("%X ",data); |
| 142 | m_pb = data; |
| 143 | } |
| 144 | |
| 74 | 145 | static ADDRESS_MAP_START(applix_mem, AS_PROGRAM, 16, applix_state) |
| 75 | 146 | ADDRESS_MAP_UNMAP_HIGH |
| 76 | 147 | ADDRESS_MAP_GLOBAL_MASK(0xffffff) |
| 77 | 148 | AM_RANGE(0x000000, 0x07ffff) AM_RAM AM_SHARE("base") |
| 78 | 149 | AM_RANGE(0x080000, 0x47ffff) AM_NOP //AM_RAM // expansion |
| 79 | 150 | AM_RANGE(0x500000, 0x5fffff) AM_ROM |
| 80 | | //AM_RANGE(0x600000, 0x600001) centronics latch (odd), video palette entry 0 (even) |
| 81 | | //AM_RANGE(0x600020, 0x600021) video palette entry 1 (even) |
| 82 | | //AM_RANGE(0x600040, 0x600041) video palette entry 2 (even) |
| 83 | | //AM_RANGE(0x600060, 0x600061) video palette entry 3 (even) |
| 84 | | //AM_RANGE(0x600080, 0x600081) dac latch (odd) |
| 85 | | //AM_RANGE(0x600100, 0x600101) video latch (=border colour, high nybble; video base, low nybble) (odd) |
| 86 | | //AM_RANGE(0x600180, 0x600181) analog multiplexer latch (odd) |
| 151 | AM_RANGE(0x600000, 0x60007f) AM_WRITE(palette_w) |
| 152 | AM_RANGE(0x600080, 0x6000ff) AM_WRITE(dac_latch_w) |
| 153 | AM_RANGE(0x600100, 0x60017f) AM_WRITE(video_latch_w) //video latch (=border colour, high nybble; video base, low nybble) (odd) |
| 154 | AM_RANGE(0x600180, 0x6001ff) AM_WRITE(analog_latch_w) //analog multiplexer latch (odd) |
| 87 | 155 | //AM_RANGE(0x700000, 0x700007) z80-scc (ch b control, ch b data, ch a control, ch a data) on even addresses |
| 88 | | AM_RANGE(0x700080, 0x700081) AM_READ(applix_inputs_r) //input port (odd) |
| 89 | | //AM_RANGE(0x700100, 0x70011f) VIA base address (even) |
| 90 | | AM_RANGE(0x700180, 0x700181) AM_WRITE(applix_index_w) |
| 91 | | AM_RANGE(0x700182, 0x700183) AM_WRITE(applix_register_w) |
| 156 | AM_RANGE(0x700080, 0x7000ff) AM_READ(applix_inputs_r) //input port (odd) |
| 157 | AM_RANGE(0x700100, 0x70011f) AM_MIRROR(0x60) AM_DEVREADWRITE8("via6522", via6522_device, read, write, 0xff00) |
| 158 | AM_RANGE(0x700180, 0x700181) AM_MIRROR(0x7c) AM_WRITE(applix_index_w) |
| 159 | AM_RANGE(0x700182, 0x700183) AM_MIRROR(0x7c) AM_WRITE(applix_register_w) |
| 92 | 160 | //600000, 6FFFFF io ports and latches |
| 93 | 161 | //700000, 7FFFFF peripheral chips and devices |
| 94 | 162 | //800000, FFC000 optional roms |
| r22631 | r22632 | |
| 147 | 215 | { |
| 148 | 216 | } |
| 149 | 217 | |
| 150 | | MC6845_UPDATE_ROW( applix_update_row ) |
| 218 | static MC6845_UPDATE_ROW( applix_update_row ) |
| 151 | 219 | { |
| 152 | | #if 0 |
| 153 | | // This needs complete rewriting |
| 154 | | // Need to display a border but the mame mc6845 code doesn't allow it. |
| 155 | | // 640x200, display 4 of 16 colours, each 2 bits points at a palette entry. |
| 156 | | // 320x200, display all 16 colours, each nybble has the colour code |
| 220 | // The display is bitmapped. 2 modes are supported here, 320x200x16 and 640x200x4. |
| 221 | // Need to display a border colour. |
| 157 | 222 | // There is a monochrome mode, but no info found as yet. |
| 158 | | // Display is bitmapped, no character generator. |
| 159 | | // The video page can be moved around to almost anywhere in memory. |
| 160 | 223 | applix_state *state = device->machine().driver_data<applix_state>(); |
| 161 | 224 | const rgb_t *palette = palette_entry_list_raw(bitmap.palette()); |
| 162 | | UINT8 chr,gfx,fg,bg; |
| 163 | | UINT16 mem,x,col; |
| 164 | | UINT16 colourm = (state->m_08 & 0x0e) << 7; |
| 165 | | UINT32 *p = &bitmap.pix32(y); |
| 225 | UINT8 i; |
| 226 | UINT16 chr,x; |
| 227 | UINT32 mem, vidbase = (state->m_video_latch & 15) << 14, *p = &bitmap.pix32(y); |
| 166 | 228 | |
| 167 | | for (x = 0; x < x_count; x++) // for each character |
| 229 | for (x = 0; x < x_count; x++) |
| 168 | 230 | { |
| 169 | | UINT8 inv=0; |
| 170 | | mem = (ma + x) & 0x7ff; |
| 171 | | chr = state->m_videoram[mem]; |
| 172 | | col = state->m_colorram[mem] | colourm; // read a byte of colour |
| 231 | mem = vidbase + ma + x + ra * x_count; |
| 232 | chr = state->m_base[mem]; |
| 173 | 233 | |
| 174 | | /* get pattern of pixels for that character scanline */ |
| 175 | | gfx = state->m_gfxram[(chr<<4) | ra] ^ inv; |
| 176 | | fg = (col & 0x001f) | 64; // map to foreground palette |
| 177 | | bg = (col & 0x07e0) >> 5; // and background palette |
| 178 | | |
| 179 | | /* Display a scanline of a character (8 pixels) */ |
| 180 | | *p++ = palette[( gfx & 0x80 ) ? fg : bg]; |
| 181 | | *p++ = palette[( gfx & 0x40 ) ? fg : bg]; |
| 182 | | *p++ = palette[( gfx & 0x20 ) ? fg : bg]; |
| 183 | | *p++ = palette[( gfx & 0x10 ) ? fg : bg]; |
| 184 | | *p++ = palette[( gfx & 0x08 ) ? fg : bg]; |
| 185 | | *p++ = palette[( gfx & 0x04 ) ? fg : bg]; |
| 186 | | *p++ = palette[( gfx & 0x02 ) ? fg : bg]; |
| 187 | | *p++ = palette[( gfx & 0x01 ) ? fg : bg]; |
| 234 | if (BIT(state->m_pa, 3)) |
| 235 | // 640 x 200 x 4of16 mode |
| 236 | { |
| 237 | for (i = 0; i < 8; i++) |
| 238 | { |
| 239 | *p++ = palette[state->m_palette_latch[chr>>14]]; |
| 240 | chr <<= 2; |
| 241 | } |
| 242 | } |
| 243 | else |
| 244 | // 320 x 200 x 16 mode |
| 245 | { |
| 246 | for (i = 0; i < 4; i++) |
| 247 | { |
| 248 | *p++ = palette[chr>>12]; |
| 249 | *p++ = palette[chr>>12]; |
| 250 | chr <<= 4; |
| 251 | } |
| 252 | } |
| 188 | 253 | } |
| 189 | | #endif |
| 190 | 254 | } |
| 191 | 255 | |
| 192 | 256 | static MC6845_INTERFACE( applix_crtc ) |
| r22631 | r22632 | |
| 200 | 264 | DEVCB_NULL, |
| 201 | 265 | DEVCB_NULL, |
| 202 | 266 | DEVCB_NULL, |
| 203 | | DEVCB_NULL, |
| 267 | DEVCB_DRIVER_LINE_MEMBER(applix_state, vsync_w), |
| 204 | 268 | NULL |
| 205 | 269 | }; |
| 206 | 270 | |
| 271 | WRITE_LINE_MEMBER( applix_state::vsync_w ) |
| 272 | { |
| 273 | m_via->write_ca2(state); |
| 274 | } |
| 275 | |
| 276 | static const via6522_interface applix_via = |
| 277 | { |
| 278 | DEVCB_DRIVER_MEMBER(applix_state, applix_pa_r), // in port A |
| 279 | DEVCB_DRIVER_MEMBER(applix_state, applix_pb_r), // in port B |
| 280 | DEVCB_NULL, // in CA1 cent ack |
| 281 | DEVCB_NULL, // in CB1 kbd clk |
| 282 | DEVCB_NULL, // in CA2 vsync |
| 283 | DEVCB_NULL, // in CB2 kdb data |
| 284 | DEVCB_DRIVER_MEMBER(applix_state, applix_pa_w),// out Port A |
| 285 | DEVCB_DRIVER_MEMBER(applix_state, applix_pb_w), // out port B |
| 286 | DEVCB_NULL, // out CA1 |
| 287 | DEVCB_NULL, // out CB1 |
| 288 | DEVCB_NULL, // out CA2 |
| 289 | DEVCB_NULL, // out CB2 |
| 290 | DEVCB_CPU_INPUT_LINE("maincpu", M68K_IRQ_2) //IRQ |
| 291 | }; |
| 292 | |
| 207 | 293 | static MACHINE_CONFIG_START( applix, applix_state ) |
| 208 | 294 | /* basic machine hardware */ |
| 209 | 295 | MCFG_CPU_ADD("maincpu", M68000, 7500000) |
| 210 | 296 | MCFG_CPU_PROGRAM_MAP(applix_mem) |
| 211 | 297 | |
| 212 | | |
| 213 | 298 | /* video hardware */ |
| 214 | 299 | MCFG_SCREEN_ADD("screen", RASTER) |
| 215 | 300 | MCFG_SCREEN_REFRESH_RATE(50) |
| 216 | 301 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 217 | | MCFG_SCREEN_SIZE(640, 480) |
| 218 | | MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1) |
| 302 | MCFG_SCREEN_SIZE(640, 200) |
| 303 | MCFG_SCREEN_VISIBLE_AREA(0, 640-1, 0, 200-1) |
| 219 | 304 | MCFG_SCREEN_UPDATE_DEVICE("crtc", mc6845_device, screen_update) |
| 220 | | |
| 221 | 305 | MCFG_PALETTE_LENGTH(16) |
| 222 | 306 | |
| 307 | /* Devices */ |
| 223 | 308 | MCFG_MC6845_ADD("crtc", MC6845, 1875000, applix_crtc) // 6545 |
| 309 | MCFG_VIA6522_ADD("via6522", 0, applix_via) |
| 224 | 310 | MACHINE_CONFIG_END |
| 225 | 311 | |
| 226 | 312 | /* ROM definition */ |
| r22631 | r22632 | |
| 228 | 314 | ROM_REGION(0x1000000, "maincpu", 0) |
| 229 | 315 | ROM_LOAD16_BYTE( "1616oshv.044", 0x500000, 0x10000, CRC(4a1a90d3) SHA1(4df504bbf6fc5dad76c29e9657bfa556500420a6) ) |
| 230 | 316 | ROM_LOAD16_BYTE( "1616oslv.044", 0x500001, 0x10000, CRC(ef619994) SHA1(ff16fe9e2c99a1ffc855baf89278a97a2a2e881a) ) |
| 231 | | //ROM_LOAD16_BYTE( "1616oshv.045", 0x520000, 0x10000, CRC(9dfb3224) SHA1(5223833a357f90b147f25826c01713269fc1945f) ) |
| 232 | | //ROM_LOAD16_BYTE( "1616oslv.045", 0x520001, 0x10000, CRC(951bd441) SHA1(e0a38c8d0d38d84955c1de3f6a7d56ce06b063f6) ) |
| 233 | | //ROM_LOAD( "1616osv.045", 0x540000, 0x20000, CRC(b9f75432) SHA1(278964e2a02b1fe26ff34f09dc040e03c1d81a6d) ) |
| 234 | | //ROM_LOAD( "1616ssdv.022", 0x560000, 0x08000, CRC(6d8e413a) SHA1(fc27d92c34f231345a387b06670f36f8c1705856) ) |
| 317 | |
| 318 | ROM_REGION(0x50000, "user1", 0) |
| 319 | ROM_LOAD16_BYTE( "1616oshv.045", 0x00000, 0x10000, CRC(9dfb3224) SHA1(5223833a357f90b147f25826c01713269fc1945f) ) |
| 320 | ROM_LOAD16_BYTE( "1616oslv.045", 0x00001, 0x10000, CRC(951bd441) SHA1(e0a38c8d0d38d84955c1de3f6a7d56ce06b063f6) ) |
| 321 | ROM_LOAD( "1616osv.045", 0x20000, 0x20000, CRC(b9f75432) SHA1(278964e2a02b1fe26ff34f09dc040e03c1d81a6d) ) |
| 322 | ROM_LOAD( "1616ssdv.022", 0x40000, 0x08000, CRC(6d8e413a) SHA1(fc27d92c34f231345a387b06670f36f8c1705856) ) |
| 235 | 323 | ROM_END |
| 236 | 324 | |
| 237 | 325 | /* Driver */ |