summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/machine/dai.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/machine/dai.c')
-rw-r--r--src/mame/machine/dai.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/mame/machine/dai.c b/src/mame/machine/dai.c
new file mode 100644
index 00000000000..9ea8258f805
--- /dev/null
+++ b/src/mame/machine/dai.c
@@ -0,0 +1,216 @@
+// license:BSD-3-Clause
+// copyright-holders:Krzysztof Strzecha, Nathan Woods
+/***************************************************************************
+
+ 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)
+
+void dai_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_BOOTSTRAP:
+ m_maincpu->set_pc(0xc000);
+ break;
+ case TIMER_TMS5501:
+ m_tms5501->xi7_w((ioport("IN8")->read() & 0x04) ? 1:0);
+ timer_set(attotime::from_hz(100), TIMER_TMS5501);
+ break;
+ default:
+ assert_always(FALSE, "Unknown id in dai_state::device_timer");
+ }
+}
+
+
+/* Discrete I/O devices */
+
+
+/* Memory */
+
+WRITE8_MEMBER(dai_state::dai_stack_interrupt_circuit_w)
+{
+ m_tms5501->sens_w(1);
+ m_tms5501->sens_w(0);
+}
+
+void dai_state::dai_update_memory(int dai_rom_bank)
+{
+ membank("bank2")->set_entry(dai_rom_bank);
+}
+
+
+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;
+}
+
+IRQ_CALLBACK_MEMBER(dai_state::int_ack)
+{
+ return m_tms5501->get_vector();
+}
+
+void dai_state::machine_start()
+{
+ membank("bank2")->configure_entries(0, 4, memregion("maincpu")->base() + 0x010000, 0x1000);
+ timer_set(attotime::zero, TIMER_BOOTSTRAP);
+ timer_set(attotime::from_hz(100), TIMER_TMS5501);
+
+ memset(m_ram->pointer(), 0, m_ram->size());
+}
+
+void dai_state::machine_reset()
+{
+ membank("bank1")->set_base(m_ram->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 (m_cassette->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;
+ m_cassette->change_state(m_cassette_motor[0]?CASSETTE_MOTOR_DISABLED:CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
+ m_cassette->output((data & 0x01) ? -1.0 : 1.0);
+ dai_update_memory ((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 m_pit->read(space, (offset >> 1) & 3);
+}
+
+WRITE8_MEMBER(dai_state::dai_pit_w)
+{
+ m_pit->write(space, (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);
+}