src/mess/drivers/d6800.c
| r9896 | r9897 | |
| 30 | 30 | - Keyboard (should work but it doesn't) |
| 31 | 31 | */ |
| 32 | 32 | |
| 33 | #define ADDRESS_MAP_MODERN |
| 34 | |
| 33 | 35 | #include "emu.h" |
| 34 | 36 | #include "cpu/m6800/m6800.h" |
| 35 | 37 | #include "sound/beep.h" |
| r9896 | r9897 | |
| 37 | 39 | #include "sound/wave.h" |
| 38 | 40 | #include "sound/speaker.h" |
| 39 | 41 | #include "machine/6821pia.h" |
| 40 | | #include "machine/rescap.h" |
| 41 | 42 | |
| 42 | 43 | |
| 43 | 44 | class d6800_state : public driver_device |
| 44 | 45 | { |
| 45 | 46 | public: |
| 46 | 47 | d6800_state(running_machine &machine, const driver_device_config_base &config) |
| 47 | | : driver_device(machine, config) { } |
| 48 | : driver_device(machine, config), |
| 49 | m_maincpu(*this, "maincpu"), |
| 50 | m_cass(*this, "cassette"), |
| 51 | m_pia(*this, "pia"), |
| 52 | m_speaker(*this, "speaker") |
| 53 | { } |
| 48 | 54 | |
| 49 | | UINT8 dummy; |
| 50 | | UINT8 keylatch; |
| 51 | | UINT8 keydown; |
| 52 | | UINT8 screen; |
| 53 | | UINT8 rtc; |
| 54 | | device_t *cassette; |
| 55 | | device_t *speaker; |
| 55 | required_device<cpu_device> m_maincpu; |
| 56 | required_device<device_t> m_cass; |
| 57 | required_device<device_t> m_pia; |
| 58 | required_device<device_t> m_speaker; |
| 59 | DECLARE_READ8_MEMBER( d6800_cassette_r ); |
| 60 | DECLARE_WRITE8_MEMBER( d6800_cassette_w ); |
| 61 | DECLARE_READ8_MEMBER( d6800_keyboard_r ); |
| 62 | DECLARE_WRITE8_MEMBER( d6800_keyboard_w ); |
| 63 | DECLARE_READ_LINE_MEMBER( d6800_fn_key_r ); |
| 64 | DECLARE_READ_LINE_MEMBER( d6800_keydown_r ); |
| 65 | DECLARE_READ_LINE_MEMBER( d6800_rtc_pulse ); |
| 66 | DECLARE_WRITE_LINE_MEMBER( d6800_screen_w ); |
| 67 | UINT8 m_keylatch; |
| 68 | UINT8 m_keydown; |
| 69 | UINT8 m_screen; |
| 70 | UINT8 m_rtc; |
| 71 | UINT8 *m_videoram; |
| 56 | 72 | }; |
| 57 | 73 | |
| 58 | 74 | |
| 59 | 75 | /* Memory Maps */ |
| 60 | 76 | |
| 61 | | static ADDRESS_MAP_START( d6800_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 62 | | AM_RANGE(0x0000, 0x07ff) AM_RAM AM_REGION("maincpu", 0x0000) |
| 63 | | AM_RANGE(0x8010, 0x8013) AM_DEVREADWRITE("pia", pia6821_r, pia6821_w) |
| 77 | static ADDRESS_MAP_START( d6800_map, ADDRESS_SPACE_PROGRAM, 8, d6800_state ) |
| 78 | AM_RANGE(0x0000, 0x00ff) AM_RAM |
| 79 | AM_RANGE(0x0100, 0x01ff) AM_RAM AM_BASE( m_videoram ) |
| 80 | AM_RANGE(0x0200, 0x07ff) AM_RAM |
| 81 | AM_RANGE(0x8010, 0x8013) AM_DEVREADWRITE_LEGACY("pia", pia6821_r, pia6821_w) |
| 64 | 82 | AM_RANGE(0xc000, 0xc3ff) AM_MIRROR(0x3c00) AM_ROM |
| 65 | 83 | ADDRESS_MAP_END |
| 66 | 84 | |
| r9896 | r9897 | |
| 105 | 123 | { |
| 106 | 124 | d6800_state *state = screen->machine->driver_data<d6800_state>(); |
| 107 | 125 | UINT8 x,y,gfx=0; |
| 108 | | UINT8 *RAM = screen->machine->region("maincpu")->base(); |
| 109 | 126 | |
| 110 | 127 | for (y = 0; y < 32; y++) |
| 111 | 128 | { |
| r9896 | r9897 | |
| 113 | 130 | |
| 114 | 131 | for (x = 0; x < 8; x++) |
| 115 | 132 | { |
| 116 | | if (state->screen) |
| 117 | | gfx = RAM[0x100 | x | (y<<3)]; |
| 133 | if (state->m_screen) |
| 134 | gfx = state->m_videoram[ x | (y<<3)]; |
| 118 | 135 | |
| 119 | 136 | *p++ = ( gfx & 0x80 ) ? 1 : 0; |
| 120 | 137 | *p++ = ( gfx & 0x40 ) ? 1 : 0; |
| r9896 | r9897 | |
| 134 | 151 | static INTERRUPT_GEN( d6800_interrupt ) |
| 135 | 152 | { |
| 136 | 153 | d6800_state *state = device->machine->driver_data<d6800_state>(); |
| 137 | | state->rtc = 1; |
| 154 | state->m_rtc = 1; |
| 138 | 155 | } |
| 139 | 156 | |
| 140 | | static READ_LINE_DEVICE_HANDLER( d6800_rtc_pulse ) |
| 157 | READ_LINE_MEMBER( d6800_state::d6800_rtc_pulse ) |
| 141 | 158 | { |
| 142 | | d6800_state *state = device->machine->driver_data<d6800_state>(); |
| 143 | | UINT8 res = state->rtc; |
| 144 | | state->rtc = 0; |
| 159 | UINT8 res = m_rtc; |
| 160 | m_rtc = 0; |
| 145 | 161 | return res; |
| 146 | 162 | } |
| 147 | 163 | |
| 148 | | static READ_LINE_DEVICE_HANDLER( d6800_keydown_r ) |
| 164 | READ_LINE_MEMBER( d6800_state::d6800_keydown_r ) |
| 149 | 165 | { |
| 150 | | d6800_state *state = device->machine->driver_data<d6800_state>(); |
| 151 | | return state->keydown; |
| 166 | return m_keydown; |
| 152 | 167 | } |
| 153 | 168 | |
| 154 | | static READ_LINE_DEVICE_HANDLER( d6800_fn_key_r ) |
| 169 | READ_LINE_MEMBER( d6800_state::d6800_fn_key_r ) |
| 155 | 170 | { |
| 156 | | return input_port_read(device->machine, "SPECIAL"); |
| 171 | return input_port_read(machine, "SPECIAL"); |
| 157 | 172 | } |
| 158 | 173 | |
| 159 | | static WRITE_LINE_DEVICE_HANDLER( d6800_screen_w ) |
| 174 | WRITE_LINE_MEMBER( d6800_state::d6800_screen_w ) |
| 160 | 175 | { |
| 161 | | d6800_state *drvstate = device->machine->driver_data<d6800_state>(); |
| 162 | | drvstate->screen = state; |
| 176 | m_screen = state; |
| 163 | 177 | } |
| 164 | 178 | |
| 165 | | static READ8_DEVICE_HANDLER( d6800_cassette_r ) |
| 179 | READ8_MEMBER( d6800_state::d6800_cassette_r ) |
| 166 | 180 | { |
| 167 | 181 | /* |
| 168 | 182 | Cassette circuit consists of a 741 op-amp, a 74121 oneshot, and a 74LS74. |
| r9896 | r9897 | |
| 174 | 188 | return 0xff; |
| 175 | 189 | } |
| 176 | 190 | |
| 177 | | static WRITE8_DEVICE_HANDLER( d6800_cassette_w ) |
| 191 | WRITE8_MEMBER( d6800_state::d6800_cassette_w ) |
| 178 | 192 | { |
| 179 | | d6800_state *state = device->machine->driver_data<d6800_state>(); |
| 180 | 193 | /* |
| 181 | 194 | Cassette circuit consists of a 566 and a transistor. The 556 runs at 2400 |
| 182 | 195 | or 1200 Hz depending on the state of the transistor. This is controlled by |
| 183 | 196 | bit 0 of the PIA. Bit 6 drives the speaker. |
| 184 | 197 | */ |
| 185 | 198 | |
| 186 | | speaker_level_w(state->speaker, (data & 0x40) ? 0 : 1); |
| 199 | speaker_level_w(m_speaker, (data & 0x40) ? 0 : 1); |
| 187 | 200 | } |
| 188 | 201 | |
| 189 | | static READ8_DEVICE_HANDLER( d6800_keyboard_r ) |
| 202 | READ8_MEMBER( d6800_state::d6800_keyboard_r ) |
| 190 | 203 | { |
| 191 | | d6800_state *state = device->machine->driver_data<d6800_state>(); |
| 192 | 204 | UINT8 data = 0xff; |
| 193 | 205 | |
| 194 | | if (!BIT(state->keylatch, 4)) data &= input_port_read(device->machine, "LINE0"); |
| 195 | | if (!BIT(state->keylatch, 5)) data &= input_port_read(device->machine, "LINE1"); |
| 196 | | if (!BIT(state->keylatch, 6)) data &= input_port_read(device->machine, "LINE2"); |
| 197 | | if (!BIT(state->keylatch, 7)) data &= input_port_read(device->machine, "LINE3"); |
| 206 | if (!BIT(m_keylatch, 4)) data &= input_port_read(machine, "LINE0"); |
| 207 | if (!BIT(m_keylatch, 5)) data &= input_port_read(machine, "LINE1"); |
| 208 | if (!BIT(m_keylatch, 6)) data &= input_port_read(machine, "LINE2"); |
| 209 | if (!BIT(m_keylatch, 7)) data &= input_port_read(machine, "LINE3"); |
| 198 | 210 | |
| 199 | | state->keydown = (data==0xff) ? 0 : 1; |
| 211 | m_keydown = (data==0xff) ? 0 : 1; |
| 200 | 212 | |
| 201 | 213 | return data; |
| 202 | 214 | } |
| 203 | 215 | |
| 204 | | static WRITE8_DEVICE_HANDLER( d6800_keyboard_w ) |
| 216 | WRITE8_MEMBER( d6800_state::d6800_keyboard_w ) |
| 205 | 217 | { |
| 206 | | d6800_state *state = device->machine->driver_data<d6800_state>(); |
| 207 | 218 | /* |
| 208 | 219 | |
| 209 | 220 | bit description |
| r9896 | r9897 | |
| 220 | 231 | */ |
| 221 | 232 | |
| 222 | 233 | |
| 223 | | state->keylatch = data & 0xf0; |
| 234 | m_keylatch = data & 0xf0; |
| 224 | 235 | } |
| 225 | 236 | |
| 226 | 237 | static const pia6821_interface d6800_mc6821_intf = |
| 227 | 238 | { |
| 228 | | DEVCB_HANDLER(d6800_keyboard_r), /* port A input */ |
| 229 | | DEVCB_HANDLER(d6800_cassette_r), /* port B input */ |
| 230 | | DEVCB_LINE(d6800_keydown_r), /* CA1 input */ |
| 231 | | DEVCB_LINE(d6800_rtc_pulse), /* CB1 input */ |
| 232 | | DEVCB_LINE(d6800_fn_key_r), /* CA2 input */ |
| 239 | DEVCB_DRIVER_MEMBER(d6800_state, d6800_keyboard_r), /* port A input */ |
| 240 | DEVCB_DRIVER_MEMBER(d6800_state, d6800_cassette_r), /* port B input */ |
| 241 | DEVCB_DRIVER_LINE_MEMBER(d6800_state, d6800_keydown_r), /* CA1 input */ |
| 242 | DEVCB_DRIVER_LINE_MEMBER(d6800_state, d6800_rtc_pulse), /* CB1 input */ |
| 243 | DEVCB_DRIVER_LINE_MEMBER(d6800_state, d6800_fn_key_r), /* CA2 input */ |
| 233 | 244 | DEVCB_NULL, /* CB2 input */ |
| 234 | | DEVCB_HANDLER(d6800_keyboard_w), /* port A output */ |
| 235 | | DEVCB_HANDLER(d6800_cassette_w), /* port B output */ |
| 245 | DEVCB_DRIVER_MEMBER(d6800_state, d6800_keyboard_w), /* port A output */ |
| 246 | DEVCB_DRIVER_MEMBER(d6800_state, d6800_cassette_w), /* port B output */ |
| 236 | 247 | DEVCB_NULL, /* CA2 output */ |
| 237 | | DEVCB_LINE(d6800_screen_w), /* CB2 output */ |
| 248 | DEVCB_DRIVER_LINE_MEMBER(d6800_state, d6800_screen_w), /* CB2 output */ |
| 238 | 249 | DEVCB_CPU_INPUT_LINE("maincpu", M6800_IRQ_LINE), /* IRQA output */ |
| 239 | 250 | DEVCB_CPU_INPUT_LINE("maincpu", M6800_IRQ_LINE) /* IRQB output */ |
| 240 | 251 | }; |
| r9896 | r9897 | |
| 243 | 254 | |
| 244 | 255 | static MACHINE_START( d6800 ) |
| 245 | 256 | { |
| 246 | | d6800_state *state = machine->driver_data<d6800_state>(); |
| 247 | | state->speaker = machine->device("speaker"); |
| 248 | | state->cassette = machine->device("cassette"); |
| 249 | 257 | } |
| 250 | 258 | |
| 251 | 259 | static MACHINE_RESET( d6800 ) |