trunk/src/mess/machine/super80.c
| r20485 | r20486 | |
| 1 | 1 | /* Super80.c written by Robbbert, 2005-2009. See driver source for documentation. */ |
| 2 | 2 | |
| 3 | | #include "emu.h" |
| 4 | 3 | #include "includes/super80.h" |
| 5 | 4 | |
| 6 | 5 | |
| r20485 | r20486 | |
| 12 | 11 | m_keylatch = data; |
| 13 | 12 | }; |
| 14 | 13 | |
| 15 | | READ8_MEMBER(super80_state::pio_port_b_r)// cannot be modernised yet as super80 hangs at start |
| 14 | READ8_MEMBER(super80_state::pio_port_b_r) |
| 16 | 15 | { |
| 17 | | char kbdrow[6]; |
| 18 | | UINT8 i; |
| 19 | 16 | UINT8 data = 0xff; |
| 20 | 17 | |
| 21 | | for (i = 0; i < 8; i++) |
| 22 | | { |
| 23 | | sprintf(kbdrow,"X%d",i); |
| 24 | | if (!BIT(m_keylatch, i)) data &= ioport(kbdrow)->read(); |
| 25 | | } |
| 18 | if (!BIT(m_keylatch, 0)) |
| 19 | data &= m_io_x0->read(); |
| 20 | if (!BIT(m_keylatch, 1)) |
| 21 | data &= m_io_x1->read(); |
| 22 | if (!BIT(m_keylatch, 2)) |
| 23 | data &= m_io_x2->read(); |
| 24 | if (!BIT(m_keylatch, 3)) |
| 25 | data &= m_io_x3->read(); |
| 26 | if (!BIT(m_keylatch, 4)) |
| 27 | data &= m_io_x4->read(); |
| 28 | if (!BIT(m_keylatch, 5)) |
| 29 | data &= m_io_x5->read(); |
| 30 | if (!BIT(m_keylatch, 6)) |
| 31 | data &= m_io_x6->read(); |
| 32 | if (!BIT(m_keylatch, 7)) |
| 33 | data &= m_io_x7->read(); |
| 26 | 34 | |
| 27 | 35 | return data; |
| 28 | 36 | }; |
| r20485 | r20486 | |
| 50 | 58 | state->m_cass->change_state(CASSETTE_MOTOR_ENABLED,CASSETTE_MASK_MOTOR); |
| 51 | 59 | |
| 52 | 60 | /* does user want to hear the sound? */ |
| 53 | | if BIT(machine.root_device().ioport("CONFIG")->read(), 3) |
| 61 | if BIT(state->m_io_config->read(), 3) |
| 54 | 62 | state->m_cass->change_state(CASSETTE_SPEAKER_ENABLED,CASSETTE_MASK_SPEAKER); |
| 55 | 63 | else |
| 56 | 64 | state->m_cass->change_state(CASSETTE_SPEAKER_MUTED,CASSETTE_MASK_SPEAKER); |
| r20485 | r20486 | |
| 104 | 112 | TIMER_CALLBACK_MEMBER(super80_state::super80_halfspeed) |
| 105 | 113 | { |
| 106 | 114 | UINT8 go_fast = 0; |
| 107 | | if ( (!BIT(m_shared, 2)) | (!BIT(machine().root_device().ioport("CONFIG")->read(), 1)) ) /* bit 2 of port F0 is low, OR user turned on config switch */ |
| 115 | if ( (!BIT(m_shared, 2)) | (!BIT(m_io_config->read(), 1)) ) /* bit 2 of port F0 is low, OR user turned on config switch */ |
| 108 | 116 | go_fast++; |
| 109 | 117 | |
| 110 | 118 | /* code to slow down computer to 1 MHz by halting cpu on every second frame */ |
| 111 | 119 | if (!go_fast) |
| 112 | 120 | { |
| 113 | 121 | if (!m_int_sw) |
| 114 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); // if going, stop it |
| 122 | m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE); // if going, stop it |
| 115 | 123 | |
| 116 | 124 | m_int_sw++; |
| 117 | 125 | if (m_int_sw > 1) |
| 118 | 126 | { |
| 119 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); // if stopped, start it |
| 127 | m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); // if stopped, start it |
| 120 | 128 | m_int_sw = 0; |
| 121 | 129 | } |
| 122 | 130 | } |
| r20485 | r20486 | |
| 124 | 132 | { |
| 125 | 133 | if (m_int_sw < 8) // @2MHz, reset just once |
| 126 | 134 | { |
| 127 | | machine().device("maincpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 135 | m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 128 | 136 | m_int_sw = 8; // ...not every time |
| 129 | 137 | } |
| 130 | 138 | } |
| r20485 | r20486 | |
| 156 | 164 | |
| 157 | 165 | READ8_MEMBER( super80_state::super80_f2_r ) |
| 158 | 166 | { |
| 159 | | UINT8 data = ioport("DSW")->read() & 0xf0; // dip switches on pcb |
| 167 | UINT8 data = m_io_dsw->read() & 0xf0; // dip switches on pcb |
| 160 | 168 | data |= m_cass_data[2]; // bit 0 = output of U1, bit 1 = MDS cass state, bit 2 = current wave_state |
| 161 | 169 | data |= 0x08; // bit 3 - not used |
| 162 | 170 | return data; |
trunk/src/mess/includes/super80.h
| r20485 | r20486 | |
| 1 | #include "emu.h" |
| 1 | 2 | #include "cpu/z80/z80.h" |
| 2 | 3 | #include "cpu/z80/z80daisy.h" |
| 3 | 4 | #include "sound/wave.h" |
| r20485 | r20486 | |
| 28 | 29 | m_wave(*this, WAVE_TAG), |
| 29 | 30 | m_speaker(*this, SPEAKER_TAG), |
| 30 | 31 | m_centronics(*this, "centronics"), |
| 31 | | m_6845(*this, "crtc") |
| 32 | m_6845(*this, "crtc"), |
| 33 | m_io_dsw(*this, "DSW"), |
| 34 | m_io_x0(*this, "X0"), |
| 35 | m_io_x1(*this, "X1"), |
| 36 | m_io_x2(*this, "X2"), |
| 37 | m_io_x3(*this, "X3"), |
| 38 | m_io_x4(*this, "X4"), |
| 39 | m_io_x5(*this, "X5"), |
| 40 | m_io_x6(*this, "X6"), |
| 41 | m_io_x7(*this, "X7"), |
| 42 | m_io_config(*this, "CONFIG") |
| 32 | 43 | { } |
| 33 | 44 | |
| 34 | | required_device<cpu_device> m_maincpu; |
| 35 | | required_device<z80pio_device> m_pio; |
| 36 | | required_device<cassette_image_device> m_cass; |
| 37 | | required_device<wave_device> m_wave; |
| 38 | | required_device<speaker_sound_device> m_speaker; |
| 39 | | required_device<centronics_device> m_centronics; |
| 40 | | optional_device<mc6845_device> m_6845; |
| 41 | 45 | DECLARE_READ8_MEMBER( super80v_low_r ); |
| 42 | 46 | DECLARE_READ8_MEMBER( super80v_high_r ); |
| 43 | 47 | DECLARE_WRITE8_MEMBER( super80v_low_w ); |
| r20485 | r20486 | |
| 52 | 56 | DECLARE_WRITE8_MEMBER( super80r_f0_w ); |
| 53 | 57 | DECLARE_READ8_MEMBER( super80_read_ff ); |
| 54 | 58 | DECLARE_WRITE8_MEMBER( pio_port_a_w ); |
| 55 | | //DECLARE_READ8_MEMBER( pio_port_b_r ); |
| 59 | DECLARE_READ8_MEMBER( pio_port_b_r ); |
| 56 | 60 | virtual void machine_reset(); |
| 57 | 61 | UINT8 m_shared; |
| 58 | 62 | UINT8 m_keylatch; |
| r20485 | r20486 | |
| 74 | 78 | UINT8 *m_p_videoram; |
| 75 | 79 | UINT8 *m_p_colorram; |
| 76 | 80 | UINT8 *m_p_pcgram; |
| 81 | UINT8 *m_p_ram; |
| 77 | 82 | void mc6845_cursor_configure(); |
| 78 | 83 | DECLARE_DRIVER_INIT(super80); |
| 79 | 84 | DECLARE_DRIVER_INIT(super80v); |
| r20485 | r20486 | |
| 89 | 94 | TIMER_CALLBACK_MEMBER(super80_timer); |
| 90 | 95 | TIMER_CALLBACK_MEMBER(super80_reset); |
| 91 | 96 | TIMER_CALLBACK_MEMBER(super80_halfspeed); |
| 92 | | DECLARE_READ8_MEMBER(pio_port_b_r); |
| 97 | required_device<cpu_device> m_maincpu; |
| 98 | required_device<z80pio_device> m_pio; |
| 99 | required_device<cassette_image_device> m_cass; |
| 100 | required_device<wave_device> m_wave; |
| 101 | required_device<speaker_sound_device> m_speaker; |
| 102 | required_device<centronics_device> m_centronics; |
| 103 | optional_device<mc6845_device> m_6845; |
| 104 | required_ioport m_io_dsw; |
| 105 | required_ioport m_io_x0; |
| 106 | required_ioport m_io_x1; |
| 107 | required_ioport m_io_x2; |
| 108 | required_ioport m_io_x3; |
| 109 | required_ioport m_io_x4; |
| 110 | required_ioport m_io_x5; |
| 111 | required_ioport m_io_x6; |
| 112 | required_ioport m_io_x7; |
| 113 | required_ioport m_io_config; |
| 93 | 114 | }; |
| 94 | 115 | |
| 95 | 116 | |
trunk/src/mess/video/super80.c
| r20485 | r20486 | |
| 5 | 5 | 2. Undocumented cursor start and end-lines is not supported by MMD, so we do it here. */ |
| 6 | 6 | |
| 7 | 7 | |
| 8 | | #include "emu.h" |
| 9 | 8 | #include "includes/super80.h" |
| 10 | 9 | |
| 11 | 10 | |
| r20485 | r20486 | |
| 76 | 75 | if (state) |
| 77 | 76 | { |
| 78 | 77 | /* if we chose another palette or colour mode, enable it */ |
| 79 | | UINT8 chosen_palette = (machine().root_device().ioport("CONFIG")->read() & 0x60)>>5; // read colour dipswitches |
| 78 | UINT8 chosen_palette = (m_io_config->read() & 0x60)>>5; // read colour dipswitches |
| 80 | 79 | |
| 81 | 80 | if (chosen_palette != m_current_palette) // any changes? |
| 82 | 81 | { |
| r20485 | r20486 | |
| 93 | 92 | { |
| 94 | 93 | UINT8 y,ra,chr=32,gfx,screen_on=0; |
| 95 | 94 | UINT16 sy=0,ma=m_vidpg,x; |
| 96 | | UINT8 *RAM = memregion("maincpu")->base(); |
| 97 | 95 | |
| 98 | | output_set_value("cass_led",(m_shared & 0x20) ? 1 : 0); |
| 96 | output_set_value("cass_led",BIT(m_shared, 5)); |
| 99 | 97 | |
| 100 | | if ((m_shared & 4) || (!(machine().root_device().ioport("CONFIG")->read() & 4))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 98 | if ((BIT(m_shared, 2)) | (!BIT(m_io_config->read(), 2))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 101 | 99 | screen_on++; |
| 102 | 100 | |
| 103 | 101 | for (y = 0; y < 16; y++) |
| r20485 | r20486 | |
| 109 | 107 | for (x = 0; x < 32; x++) // done this way to avoid x overflowing on page FF |
| 110 | 108 | { |
| 111 | 109 | if (screen_on) |
| 112 | | chr = RAM[ma | x] & 0x3f; |
| 110 | chr = m_p_ram[ma | x] & 0x3f; |
| 113 | 111 | |
| 114 | 112 | /* get pattern of pixels for that character scanline */ |
| 115 | 113 | gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; |
| r20485 | r20486 | |
| 134 | 132 | { |
| 135 | 133 | UINT8 y,ra,chr=32,gfx,screen_on=0; |
| 136 | 134 | UINT16 sy=0,ma=m_vidpg,x; |
| 137 | | UINT8 *RAM = memregion("maincpu")->base(); |
| 138 | 135 | |
| 139 | | output_set_value("cass_led",(m_shared & 0x20) ? 1 : 0); |
| 136 | output_set_value("cass_led",BIT(m_shared, 5)); |
| 140 | 137 | |
| 141 | | if ((m_shared & 4) || (!(machine().root_device().ioport("CONFIG")->read() & 4))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 138 | if ((BIT(m_shared, 2)) | (!BIT(m_io_config->read(), 2))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 142 | 139 | screen_on++; |
| 143 | 140 | |
| 144 | 141 | for (y = 0; y < 16; y++) |
| r20485 | r20486 | |
| 150 | 147 | for (x = 0; x < 32; x++) |
| 151 | 148 | { |
| 152 | 149 | if (screen_on) |
| 153 | | chr = RAM[ma | x]; |
| 150 | chr = m_p_ram[ma | x]; |
| 154 | 151 | |
| 155 | 152 | /* get pattern of pixels for that character scanline */ |
| 156 | 153 | gfx = m_p_chargen[((chr & 0x7f)<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)] ^ ((chr & 0x80) ? 0xff : 0); |
| r20485 | r20486 | |
| 175 | 172 | { |
| 176 | 173 | UINT8 y,ra,chr=32,gfx,screen_on=0; |
| 177 | 174 | UINT16 sy=0,ma=m_vidpg,x; |
| 178 | | UINT8 *RAM = memregion("maincpu")->base(); |
| 179 | 175 | |
| 180 | | output_set_value("cass_led",(m_shared & 0x20) ? 1 : 0); |
| 176 | output_set_value("cass_led",BIT(m_shared, 5)); |
| 181 | 177 | |
| 182 | | if ((m_shared & 4) || (!(machine().root_device().ioport("CONFIG")->read() & 4))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 178 | if ((BIT(m_shared, 2)) | (!BIT(m_io_config->read(), 2))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 183 | 179 | screen_on++; |
| 184 | 180 | |
| 185 | 181 | for (y = 0; y < 16; y++) |
| r20485 | r20486 | |
| 191 | 187 | for (x = 0; x < 32; x++) |
| 192 | 188 | { |
| 193 | 189 | if (screen_on) |
| 194 | | chr = RAM[ma | x]; |
| 190 | chr = m_p_ram[ma | x]; |
| 195 | 191 | |
| 196 | 192 | /* get pattern of pixels for that character scanline */ |
| 197 | 193 | gfx = m_p_chargen[(chr<<4) | ((ra & 8) >> 3) | ((ra & 7) << 1)]; |
| r20485 | r20486 | |
| 216 | 212 | { |
| 217 | 213 | UINT8 y,ra,chr=32,gfx,screen_on=0; |
| 218 | 214 | UINT16 sy=0,ma=m_vidpg,x; |
| 219 | | UINT8 col, bg=0, fg=0, options=machine().root_device().ioport("CONFIG")->read(); |
| 220 | | UINT8 *RAM = memregion("maincpu")->base(); |
| 215 | UINT8 col, bg=0, fg=0, options=m_io_config->read(); |
| 221 | 216 | |
| 222 | 217 | /* get selected character generator */ |
| 223 | 218 | UINT8 cgen = m_current_charset ^ ((options & 0x10)>>4); /* bit 0 of port F1 and cgen config switch */ |
| 224 | 219 | |
| 225 | | output_set_value("cass_led",(m_shared & 0x20) ? 1 : 0); |
| 220 | output_set_value("cass_led",BIT(m_shared, 5)); |
| 226 | 221 | |
| 227 | | if ((m_shared & 4) || (!(options & 4))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 222 | if ((BIT(m_shared, 2)) | (!BIT(options, 2))) /* bit 2 of port F0 is high, OR user turned on config switch */ |
| 228 | 223 | screen_on++; |
| 229 | 224 | |
| 230 | 225 | if (screen_on) |
| r20485 | r20486 | |
| 244 | 239 | for (x = 0; x < 32; x++) |
| 245 | 240 | { |
| 246 | 241 | if (screen_on) |
| 247 | | chr = RAM[ma | x]; |
| 242 | chr = m_p_ram[ma | x]; |
| 248 | 243 | |
| 249 | 244 | if (!(options & 0x40)) |
| 250 | 245 | { |
| 251 | | col = RAM[0xfe00 | ma | x]; /* byte of colour to display */ |
| 246 | col = m_p_ram[0xfe00 | ma | x]; /* byte of colour to display */ |
| 252 | 247 | fg = col & 0x0f; |
| 253 | 248 | bg = (col & 0xf0) >> 4; |
| 254 | 249 | } |
| r20485 | r20486 | |
| 279 | 274 | { |
| 280 | 275 | m_vidpg = 0xfe00; |
| 281 | 276 | m_p_chargen = memregion("chargen")->base(); |
| 277 | m_p_ram = memregion("maincpu")->base(); |
| 282 | 278 | } |
| 283 | 279 | |
| 284 | 280 | /**************************** I/O PORTS *****************************************************************/ |
| r20485 | r20486 | |
| 384 | 380 | m_framecnt++; |
| 385 | 381 | m_speed = m_mc6845_reg[10]&0x20, m_flash = m_mc6845_reg[10]&0x40; // cursor modes |
| 386 | 382 | m_cursor = (m_mc6845_reg[14]<<8) | m_mc6845_reg[15]; // get cursor position |
| 387 | | m_s_options=machine().root_device().ioport("CONFIG")->read(); |
| 388 | | output_set_value("cass_led",(m_shared & 0x20) ? 1 : 0); |
| 383 | m_s_options=m_io_config->read(); |
| 384 | output_set_value("cass_led",BIT(m_shared, 5)); |
| 389 | 385 | m_6845->screen_update(screen, bitmap, cliprect); |
| 390 | 386 | return 0; |
| 391 | 387 | } |