diff options
Diffstat (limited to 'src/mess/machine/dai.c')
-rw-r--r-- | src/mess/machine/dai.c | 254 |
1 files changed, 254 insertions, 0 deletions
diff --git a/src/mess/machine/dai.c b/src/mess/machine/dai.c new file mode 100644 index 00000000000..9ee389ae3ba --- /dev/null +++ b/src/mess/machine/dai.c @@ -0,0 +1,254 @@ +/*************************************************************************** + + machine/dai.c + + Functions to emulate general aspects of DAI (RAM, ROM, interrupts, I/O ports) + + Krzysztof Strzecha + Nathan Woods + +***************************************************************************/ + +#include "emu.h" +#include "includes/dai.h" + +#define DEBUG_DAI_PORTS 0 + +#define LOG_DAI_PORT_R(_port, _data, _comment) do { if (DEBUG_DAI_PORTS) logerror ("DAI port read : %04x, Data: %02x (%s)\n", _port, _data, _comment); } while (0) +#define LOG_DAI_PORT_W(_port, _data, _comment) do { if (DEBUG_DAI_PORTS) logerror ("DAI port write: %04x, Data: %02x (%s)\n", _port, _data, _comment); } while (0) + +/* Discrete I/O devices */ + + +/* Memory */ + +WRITE8_MEMBER(dai_state::dai_stack_interrupt_circuit_w) +{ + m_tms5501->set_sensor(1); + m_tms5501->set_sensor(0); +} + +static void dai_update_memory(running_machine &machine, int dai_rom_bank) +{ + dai_state *state = machine.driver_data<dai_state>(); + state->membank("bank2")->set_entry(dai_rom_bank); +} + +static TIMER_CALLBACK(dai_bootstrap_callback) +{ + cpu_set_reg(machine.device("maincpu"), STATE_GENPC, 0xc000); +} + + +READ8_MEMBER(dai_state::dai_keyboard_r) +{ + UINT8 data = 0x00; + static const char *const keynames[] = { "IN0", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6", "IN7" }; + + for (int i = 0; i < 8; i++) + { + if (m_keyboard_scan_mask & (1 << i)) + data |= ioport(keynames[i])->read(); + } + + return data; +} + +WRITE8_MEMBER(dai_state::dai_keyboard_w) +{ + m_keyboard_scan_mask = data; +} + +static TMS5501_IRQ_CALLBACK(dai_interrupt_callback) +{ + if (intreq) + cputag_set_input_line_and_vector(device.machine(), "maincpu", 0, HOLD_LINE, vector); + else + cputag_set_input_line(device.machine(), "maincpu", 0, CLEAR_LINE); +} + +TMS5501_INTERFACE( dai_tms5501_interface ) +{ + DEVCB_DRIVER_MEMBER(dai_state, dai_keyboard_r), + DEVCB_DRIVER_MEMBER(dai_state, dai_keyboard_w), + dai_interrupt_callback +}; + +I8255A_INTERFACE( dai_ppi82555_intf ) +{ + DEVCB_NULL, /* Port A read */ + DEVCB_NULL, /* Port A write */ + DEVCB_NULL, /* Port B read */ + DEVCB_NULL, /* Port B write */ + DEVCB_NULL, /* Port C read */ + DEVCB_NULL /* Port C write */ +}; + +const struct pit8253_config dai_pit8253_intf = +{ + { + { + 2000000, + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER("custom", dai_sound_device, set_input_ch0), + }, + { + 2000000, + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER("custom", dai_sound_device, set_input_ch1), + }, + { + 2000000, + DEVCB_NULL, + DEVCB_DEVICE_LINE_MEMBER("custom", dai_sound_device, set_input_ch2), + } + } +}; + +static TIMER_CALLBACK( dai_timer ) +{ + dai_state *state = machine.driver_data<dai_state>(); + state->m_tms5501->set_pio_bit_7((state->ioport("IN8")->read() & 0x04) ? 1:0); +} + +MACHINE_START( dai ) +{ + dai_state *state = machine.driver_data<dai_state>(); + + state->membank("bank2")->configure_entries(0, 4, state->memregion("maincpu")->base() + 0x010000, 0x1000); + machine.scheduler().timer_set(attotime::zero, FUNC(dai_bootstrap_callback)); + machine.scheduler().timer_pulse(attotime::from_hz(100), FUNC(dai_timer)); /* timer for tms5501 */ + + memset(machine.device<ram_device>(RAM_TAG)->pointer(), 0, machine.device<ram_device>(RAM_TAG)->size()); +} + +MACHINE_RESET( dai ) +{ + dai_state *state = machine.driver_data<dai_state>(); + state->membank("bank1")->set_base(machine.device<ram_device>(RAM_TAG)->pointer()); +} + +/*************************************************************************** + + Discrete Devices IO + + FD00 POR1: IN bit 0 - + bit 1 - + bit 2 PIPGE: Page signal + bit 3 PIDTR: Serial output ready + bit 4 PIBU1: Button on paddle 1 (1 = closed) + bit 5 PIBU1: Button on paddle 2 (1 = closed) + bit 6 PIRPI: Random data + bit 7 PICAI: Cassette input data + + FD01 PDLST: IN Single pulse used to trigger paddle timer circuit + + FD04 POR1: OUT bit 0-3 Volume oscillator channel 0 + bit 4-7 Volume oscillator channel 1 + + FD05 POR1: OUT bit 0-3 Volume oscillator channel 2 + bit 4-7 Volume random noise generator + + FD06 POR0: OUT bit 0 POCAS: Cassette data output + bit 1-2 PDLMSK: Paddle select + bit 3 PDPNA: Paddle enable + bit 4 POCM1: Cassette 1 motor control (0 = run) + bit 5 POCM2: Cassette 2 motor control (0 = run) + bit 6-7 ROM bank switching +***************************************************************************/ + +READ8_MEMBER(dai_state::dai_io_discrete_devices_r) +{ + UINT8 data = 0x00; + + switch(offset & 0x000f) { + case 0x00: + data = ioport("IN8")->read(); + data |= 0x08; // serial ready + if (machine().rand()&0x01) + data |= 0x40; // random number generator + if (machine().device<cassette_image_device>(CASSETTE_TAG)->input() > 0.01) + data |= 0x80; // tape input + break; + + default: + data = 0xff; + LOG_DAI_PORT_R (offset, data, "discrete devices - unmapped"); + + break; + } + return data; +} + +WRITE8_MEMBER(dai_state::dai_io_discrete_devices_w) +{ + switch(offset & 0x000f) { + case 0x04: + m_sound->set_volume(space, offset, data); + LOG_DAI_PORT_W (offset, data&0x0f, "discrete devices - osc. 0 volume"); + LOG_DAI_PORT_W (offset, (data&0xf0)>>4, "discrete devices - osc. 1 volume"); + break; + + case 0x05: + m_sound->set_volume(space, offset, data); + LOG_DAI_PORT_W (offset, data&0x0f, "discrete devices - osc. 2 volume"); + LOG_DAI_PORT_W (offset, (data&0xf0)>>4, "discrete devices - noise volume"); + break; + + case 0x06: + m_paddle_select = (data&0x06)>>2; + m_paddle_enable = (data&0x08)>>3; + m_cassette_motor[0] = (data&0x10)>>4; + m_cassette_motor[1] = (data&0x20)>>5; + machine().device<cassette_image_device>(CASSETTE_TAG)->change_state(m_cassette_motor[0]?CASSETTE_MOTOR_DISABLED:CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR); + machine().device<cassette_image_device>(CASSETTE_TAG)->output((data & 0x01) ? -1.0 : 1.0); + dai_update_memory (machine(), (data&0xc0)>>6); + LOG_DAI_PORT_W (offset, (data&0x06)>>2, "discrete devices - paddle select"); + LOG_DAI_PORT_W (offset, (data&0x08)>>3, "discrete devices - paddle enable"); + LOG_DAI_PORT_W (offset, (data&0x10)>>4, "discrete devices - cassette motor 1"); + LOG_DAI_PORT_W (offset, (data&0x20)>>5, "discrete devices - cassette motor 2"); + LOG_DAI_PORT_W (offset, (data&0xc0)>>6, "discrete devices - ROM bank"); + break; + + default: + LOG_DAI_PORT_W (offset, data, "discrete devices - unmapped"); + break; + } +} + +/*************************************************************************** + + PIT8253 + + Offset need to be shifted by 1 to right, because the PIT is + connected to A1 and A2 + +***************************************************************************/ + +READ8_MEMBER(dai_state::dai_pit_r) +{ + return pit8253_r(m_pit, (offset>>1) & 3); +} + +WRITE8_MEMBER(dai_state::dai_pit_w) +{ + pit8253_w(m_pit, (offset>>1) & 3, data); +} + +/*************************************************************************** + + AMD 9911 mathematical coprocesor + +***************************************************************************/ + +READ8_MEMBER(dai_state::dai_amd9511_r) +{ + /* optional and no present at this moment */ + return 0xff; +} + +WRITE8_MEMBER(dai_state::dai_amd9511_w) +{ + logerror ("Writing to AMD9511 math chip, %04x, %02x\n", offset, data); +} + |