mirror of
https://github.com/holub/mame
synced 2025-10-05 00:38:58 +03:00
Add device emulation for MM5307 Baud Rate Generator
This commit is contained in:
parent
70389c5762
commit
e49e75c122
@ -1974,6 +1974,18 @@ if (MACHINES["MICROTOUCH"]~=null) then
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---------------------------------------------------
|
||||||
|
--
|
||||||
|
--@src/devices/machine/mm5307.h,MACHINES["MM5307"] = true
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
if (MACHINES["MM5307"]~=null) then
|
||||||
|
files {
|
||||||
|
MAME_DIR .. "src/devices/machine/mm5307.cpp",
|
||||||
|
MAME_DIR .. "src/devices/machine/mm5307.h",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
--
|
--
|
||||||
--@src/devices/machine/mm58274c.h,MACHINES["MM58274C"] = true
|
--@src/devices/machine/mm58274c.h,MACHINES["MM58274C"] = true
|
||||||
|
@ -520,6 +520,7 @@ MACHINES["MCF5206E"] = true
|
|||||||
MACHINES["METERS"] = true
|
MACHINES["METERS"] = true
|
||||||
MACHINES["MICROTOUCH"] = true
|
MACHINES["MICROTOUCH"] = true
|
||||||
--MACHINES["MIOT6530"] = true
|
--MACHINES["MIOT6530"] = true
|
||||||
|
--MACHINES["MM5307"] = true
|
||||||
--MACHINES["MM58167"] = true
|
--MACHINES["MM58167"] = true
|
||||||
MACHINES["MM58274C"] = true
|
MACHINES["MM58274C"] = true
|
||||||
MACHINES["MM74C922"] = true
|
MACHINES["MM74C922"] = true
|
||||||
|
@ -524,6 +524,7 @@ MACHINES["MCCS1850"] = true
|
|||||||
MACHINES["MCF5206E"] = true
|
MACHINES["MCF5206E"] = true
|
||||||
MACHINES["MICROTOUCH"] = true
|
MACHINES["MICROTOUCH"] = true
|
||||||
MACHINES["MIOT6530"] = true
|
MACHINES["MIOT6530"] = true
|
||||||
|
MACHINES["MM5307"] = true
|
||||||
MACHINES["MM58167"] = true
|
MACHINES["MM58167"] = true
|
||||||
MACHINES["MM58274C"] = true
|
MACHINES["MM58274C"] = true
|
||||||
MACHINES["MM74C922"] = true
|
MACHINES["MM74C922"] = true
|
||||||
|
222
src/devices/machine/mm5307.cpp
Normal file
222
src/devices/machine/mm5307.cpp
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:AJR
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
National Semiconductor MM5307 Baud Rate Generator/Programmable Divider
|
||||||
|
|
||||||
|
The MM5307 divides the frequency of a crystal oscillator or external
|
||||||
|
clock (maximum 1 MHz, ideally 921.6 kHz) to generate a single baud
|
||||||
|
rate output. (The undivided frequency is also output on another pin,
|
||||||
|
not emulated here.)
|
||||||
|
|
||||||
|
The four control inputs (A, B, C, D) select one of 15 mask-programmed
|
||||||
|
divisors or an independent external frequency. When the selected
|
||||||
|
divisor is 2N, the output has a duty cycle of exactly 50%. When the
|
||||||
|
selected divisor is 2N + 1, the high output is always one clock cycle
|
||||||
|
longer than the low output. When the selected divisor is 2N + 0.5,
|
||||||
|
the duty cycle varies slightly from phase to phase.
|
||||||
|
|
||||||
|
The MM5307 resets its output frequency when the reset input is pulsed
|
||||||
|
low or the control inputs change.
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "mm5307.h"
|
||||||
|
|
||||||
|
#define VERBOSE 0
|
||||||
|
#include "logmacro.h"
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// GLOBAL VARIABLES
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// device type definitions
|
||||||
|
DEFINE_DEVICE_TYPE(MM5307AA, mm5307aa_device, "mm5307aa", "MM5307AA Baud Rate Generator")
|
||||||
|
DEFINE_DEVICE_TYPE(MM5307AB, mm5307ab_device, "mm5307ab", "MM5307AB Baud Rate Generator")
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// DIVISOR TABLES
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
const std::array<u16, 16> mm5307aa_device::s_divisors_x2 = {
|
||||||
|
0, // external frequency (not divided)
|
||||||
|
2304, // 50 baud (divide by 1152)
|
||||||
|
1536, // 75 baud (divide by 768)
|
||||||
|
1048, // 110 baud (divide by 524)
|
||||||
|
857, // 134.5 baud (divide by 428.5)
|
||||||
|
768, // 150 baud (divide by 384)
|
||||||
|
384, // 300 baud (divide by 192)
|
||||||
|
192, // 600 baud (divide by 96)
|
||||||
|
128, // 900 baud (divide by 64)
|
||||||
|
96, // 1200 baud (divide by 48)
|
||||||
|
64, // 1800 baud (divide by 32)
|
||||||
|
48, // 2400 baud (divide by 24)
|
||||||
|
32, // 3600 baud (divide by 16)
|
||||||
|
24, // 4800 baud (divide by 12)
|
||||||
|
16, // 7200 baud (divide by 8)
|
||||||
|
12 // 9600 baud (divide by 6)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const std::array<u16, 16> mm5307ab_device::s_divisors_x2 = {
|
||||||
|
0, // external frequency (not divided)
|
||||||
|
2304, // 50 baud (divide by 1152)
|
||||||
|
576, // 200 baud (divide by 288)
|
||||||
|
1048, // 110 baud (divide by 524)
|
||||||
|
857, // 134.5 baud (divide by 428.5)
|
||||||
|
768, // 150 baud (divide by 384)
|
||||||
|
384, // 300 baud (divide by 192)
|
||||||
|
192, // 600 baud (divide by 96)
|
||||||
|
128, // 900 baud (divide by 64)
|
||||||
|
96, // 1200 baud (divide by 48)
|
||||||
|
64, // 1800 baud (divide by 32)
|
||||||
|
48, // 2400 baud (divide by 24)
|
||||||
|
32, // 3600 baud (divide by 16)
|
||||||
|
24, // 4800 baud (divide by 12)
|
||||||
|
1536, // 75 baud (divide by 768)
|
||||||
|
12 // 9600 baud (divide by 6)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// DEVICE IMPLEMENTATION
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// mm5307_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
mm5307_device::mm5307_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const std::array<u16, 16> &divisors_x2)
|
||||||
|
: device_t(mconfig, type, tag, owner, clock)
|
||||||
|
, m_divisors_x2(divisors_x2)
|
||||||
|
, m_output_cb(*this)
|
||||||
|
, m_ext_freq(0)
|
||||||
|
, m_freq_control(0)
|
||||||
|
, m_phase(0)
|
||||||
|
, m_periodic_timer(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// mm5307aa_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
mm5307aa_device::mm5307aa_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
|
: mm5307_device(mconfig, MM5307AA, tag, owner, clock, s_divisors_x2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// mm5307ab_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
mm5307ab_device::mm5307ab_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
|
: mm5307_device(mconfig, MM5307AB, tag, owner, clock, s_divisors_x2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_resolve_objects - resolve objects that
|
||||||
|
// may be needed for other devices to set
|
||||||
|
// initial conditions at start time
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void mm5307_device::device_resolve_objects()
|
||||||
|
{
|
||||||
|
// Resolve callback
|
||||||
|
m_output_cb.resolve_safe();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void mm5307_device::device_start()
|
||||||
|
{
|
||||||
|
// Create timer
|
||||||
|
m_periodic_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mm5307_device::periodic_update), this));
|
||||||
|
|
||||||
|
// Register for saving
|
||||||
|
save_item(NAME(m_freq_control));
|
||||||
|
save_item(NAME(m_phase));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_reset - device-specific reset
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void mm5307_device::device_reset()
|
||||||
|
{
|
||||||
|
// Output delay from reset
|
||||||
|
m_periodic_timer->adjust(attotime::from_usec(500) + clocks_to_attotime(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// control_w - set frequency control
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void mm5307_device::control_w(u8 data)
|
||||||
|
{
|
||||||
|
data &= 15;
|
||||||
|
if (data != m_freq_control)
|
||||||
|
{
|
||||||
|
m_freq_control = data;
|
||||||
|
|
||||||
|
if (m_divisors_x2[data] == 0)
|
||||||
|
LOG("%s: External frequency selected\n", machine().describe_context());
|
||||||
|
else
|
||||||
|
LOG("%s: %.1f baud selected\n", machine().describe_context(), clock() / (8.0 * m_divisors_x2[data]));
|
||||||
|
|
||||||
|
// Emulate access time
|
||||||
|
m_periodic_timer->adjust(attotime::from_usec(2800) + clocks_to_attotime(13));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// periodic_update - update output state and
|
||||||
|
// reset timer for next period
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
TIMER_CALLBACK_MEMBER(mm5307_device::periodic_update)
|
||||||
|
{
|
||||||
|
// Up to four different phases
|
||||||
|
m_phase = (m_phase + 1) & 3;
|
||||||
|
m_output_cb(BIT(m_phase, 0));
|
||||||
|
|
||||||
|
u16 divisor = m_divisors_x2[m_freq_control];
|
||||||
|
if (divisor == 0)
|
||||||
|
{
|
||||||
|
m_periodic_timer->adjust(m_ext_freq == 0 ? attotime::never : attotime::from_hz(m_ext_freq) / 2);
|
||||||
|
}
|
||||||
|
else switch (m_phase)
|
||||||
|
{
|
||||||
|
// First low output phase
|
||||||
|
case 0:
|
||||||
|
m_periodic_timer->adjust(clocks_to_attotime(divisor & ~2) / 2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// First high output phase
|
||||||
|
case 1:
|
||||||
|
m_periodic_timer->adjust(clocks_to_attotime(divisor >> 1));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Second low output phase
|
||||||
|
case 2:
|
||||||
|
m_periodic_timer->adjust(clocks_to_attotime((divisor & ~2) >> 1 | (divisor & 1)));
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Second high output phase
|
||||||
|
case 3:
|
||||||
|
m_periodic_timer->adjust(clocks_to_attotime(divisor - ((divisor & 1) << 1)) / 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
99
src/devices/machine/mm5307.h
Normal file
99
src/devices/machine/mm5307.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:AJR
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
National Semiconductor MM5307 Baud Rate Generator/Programmable Divider
|
||||||
|
|
||||||
|
****************************************************************************
|
||||||
|
___ ___
|
||||||
|
EXTERNAL FREQ 1 |* \__/ | 14 ϕOUT
|
||||||
|
NC 2 | | 13 RESET
|
||||||
|
OUTPUT 3 | | 12 Vgg
|
||||||
|
Vss 4 | MM5307 | 11 A
|
||||||
|
EXTERNAL CLOCK 5 | | 10 B
|
||||||
|
CRYSTAL 6 | | 9 C
|
||||||
|
CRYSTAL 7 |__________| 8 D
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MAME_MACHINE_MM5307_H
|
||||||
|
#define MAME_MACHINE_MM5307_H 1
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// ======================> mm5307_device
|
||||||
|
|
||||||
|
class mm5307_device : public device_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// configuration
|
||||||
|
void set_ext_freq(u32 freq) { m_ext_freq = freq; }
|
||||||
|
void set_ext_freq(const XTAL &freq) { m_ext_freq = freq.value(); }
|
||||||
|
auto output_cb() { return m_output_cb.bind(); }
|
||||||
|
|
||||||
|
// frequency control
|
||||||
|
void control_w(u8 data);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// base class constructor
|
||||||
|
mm5307_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const std::array<u16, 16> &divisors_x2);
|
||||||
|
|
||||||
|
// device-specific overrides
|
||||||
|
virtual void device_resolve_objects() override;
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// timed update callback
|
||||||
|
TIMER_CALLBACK_MEMBER(periodic_update);
|
||||||
|
|
||||||
|
// internal divisors
|
||||||
|
const std::array<u16, 16> &m_divisors_x2;
|
||||||
|
|
||||||
|
// callbacks
|
||||||
|
devcb_write_line m_output_cb;
|
||||||
|
|
||||||
|
// external input frequency
|
||||||
|
u32 m_ext_freq;
|
||||||
|
|
||||||
|
// internal state
|
||||||
|
u8 m_freq_control;
|
||||||
|
u8 m_phase;
|
||||||
|
|
||||||
|
// timer
|
||||||
|
emu_timer *m_periodic_timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> mm5307aa_device
|
||||||
|
|
||||||
|
class mm5307aa_device : public mm5307_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
mm5307aa_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const std::array<u16, 16> s_divisors_x2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> mm5307ab_device
|
||||||
|
|
||||||
|
class mm5307ab_device : public mm5307_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
mm5307ab_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const std::array<u16, 16> s_divisors_x2;
|
||||||
|
};
|
||||||
|
|
||||||
|
// device type declarations
|
||||||
|
DECLARE_DEVICE_TYPE(MM5307AA, mm5307aa_device)
|
||||||
|
DECLARE_DEVICE_TYPE(MM5307AB, mm5307ab_device)
|
||||||
|
|
||||||
|
#endif // MAME_MACHINE_MM5307_H
|
@ -69,7 +69,7 @@ void poly88_state::poly88_io(address_map &map)
|
|||||||
{
|
{
|
||||||
map.unmap_value_high();
|
map.unmap_value_high();
|
||||||
map.global_mask(0xff);
|
map.global_mask(0xff);
|
||||||
map(0x00, 0x01).rw(m_uart, FUNC(i8251_device::read), FUNC(i8251_device::write));
|
map(0x00, 0x01).rw(m_usart, FUNC(i8251_device::read), FUNC(i8251_device::write));
|
||||||
map(0x04, 0x04).w(FUNC(poly88_state::poly88_baud_rate_w));
|
map(0x04, 0x04).w(FUNC(poly88_state::poly88_baud_rate_w));
|
||||||
map(0x08, 0x08).w(FUNC(poly88_state::poly88_intr_w));
|
map(0x08, 0x08).w(FUNC(poly88_state::poly88_intr_w));
|
||||||
map(0xf8, 0xf8).r(FUNC(poly88_state::poly88_keyboard_r));
|
map(0xf8, 0xf8).r(FUNC(poly88_state::poly88_keyboard_r));
|
||||||
@ -201,7 +201,7 @@ GFXDECODE_END
|
|||||||
|
|
||||||
MACHINE_CONFIG_START(poly88_state::poly88)
|
MACHINE_CONFIG_START(poly88_state::poly88)
|
||||||
/* basic machine hardware */
|
/* basic machine hardware */
|
||||||
I8080A(config, m_maincpu, XTAL(16'588'800) / 9); // uses 8224 clock generator
|
I8080A(config, m_maincpu, 16.5888_MHz_XTAL / 9); // uses 8224 clock generator
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &poly88_state::poly88_mem);
|
m_maincpu->set_addrmap(AS_PROGRAM, &poly88_state::poly88_mem);
|
||||||
m_maincpu->set_addrmap(AS_IO, &poly88_state::poly88_io);
|
m_maincpu->set_addrmap(AS_IO, &poly88_state::poly88_io);
|
||||||
m_maincpu->set_vblank_int("screen", FUNC(poly88_state::poly88_interrupt));
|
m_maincpu->set_vblank_int("screen", FUNC(poly88_state::poly88_interrupt));
|
||||||
@ -230,9 +230,12 @@ MACHINE_CONFIG_START(poly88_state::poly88)
|
|||||||
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED);
|
m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED);
|
||||||
|
|
||||||
/* uart */
|
/* uart */
|
||||||
I8251(config, m_uart, XTAL(16'588'800) / 9);
|
I8251(config, m_usart, 16.5888_MHz_XTAL / 9);
|
||||||
m_uart->txd_handler().set(FUNC(poly88_state::write_cas_tx));
|
m_usart->txd_handler().set(FUNC(poly88_state::write_cas_tx));
|
||||||
m_uart->rxrdy_handler().set(FUNC(poly88_state::poly88_usart_rxready));
|
m_usart->rxrdy_handler().set(FUNC(poly88_state::poly88_usart_rxready));
|
||||||
|
|
||||||
|
MM5307AA(config, m_brg, 16.5888_MHz_XTAL / 18);
|
||||||
|
m_brg->output_cb().set(FUNC(poly88_state::cassette_txc_rxc_w));
|
||||||
|
|
||||||
/* snapshot */
|
/* snapshot */
|
||||||
MCFG_SNAPSHOT_ADD("snapshot", poly88_state, poly88, "img", attotime::from_seconds(2))
|
MCFG_SNAPSHOT_ADD("snapshot", poly88_state, poly88, "img", attotime::from_seconds(2))
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "machine/i8251.h"
|
#include "machine/i8251.h"
|
||||||
|
#include "machine/mm5307.h"
|
||||||
#include "imagedev/cassette.h"
|
#include "imagedev/cassette.h"
|
||||||
#include "imagedev/snapquik.h"
|
#include "imagedev/snapquik.h"
|
||||||
|
|
||||||
@ -20,15 +21,15 @@ public:
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TIMER_USART,
|
TIMER_USART,
|
||||||
TIMER_KEYBOARD,
|
TIMER_KEYBOARD
|
||||||
TIMER_CASSETTE
|
|
||||||
};
|
};
|
||||||
|
|
||||||
poly88_state(const machine_config &mconfig, device_type type, const char *tag) :
|
poly88_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||||
driver_device(mconfig, type, tag),
|
driver_device(mconfig, type, tag),
|
||||||
m_video_ram(*this, "video_ram"),
|
m_video_ram(*this, "video_ram"),
|
||||||
m_maincpu(*this, "maincpu"),
|
m_maincpu(*this, "maincpu"),
|
||||||
m_uart(*this, "uart"),
|
m_usart(*this, "usart"),
|
||||||
|
m_brg(*this, "brg"),
|
||||||
m_cassette(*this, "cassette"),
|
m_cassette(*this, "cassette"),
|
||||||
m_linec(*this, "LINEC"),
|
m_linec(*this, "LINEC"),
|
||||||
m_line0(*this, "LINE0"),
|
m_line0(*this, "LINE0"),
|
||||||
@ -51,8 +52,8 @@ private:
|
|||||||
uint8_t m_intr;
|
uint8_t m_intr;
|
||||||
uint8_t m_last_code;
|
uint8_t m_last_code;
|
||||||
uint8_t m_int_vector;
|
uint8_t m_int_vector;
|
||||||
emu_timer * m_cassette_timer;
|
|
||||||
emu_timer * m_usart_timer;
|
emu_timer * m_usart_timer;
|
||||||
|
emu_timer * m_keyboard_timer;
|
||||||
int m_previous_level;
|
int m_previous_level;
|
||||||
int m_clk_level;
|
int m_clk_level;
|
||||||
int m_clk_level_tape;
|
int m_clk_level_tape;
|
||||||
@ -65,7 +66,7 @@ private:
|
|||||||
INTERRUPT_GEN_MEMBER(poly88_interrupt);
|
INTERRUPT_GEN_MEMBER(poly88_interrupt);
|
||||||
TIMER_CALLBACK_MEMBER(poly88_usart_timer_callback);
|
TIMER_CALLBACK_MEMBER(poly88_usart_timer_callback);
|
||||||
TIMER_CALLBACK_MEMBER(keyboard_callback);
|
TIMER_CALLBACK_MEMBER(keyboard_callback);
|
||||||
TIMER_CALLBACK_MEMBER(poly88_cassette_timer_callback);
|
DECLARE_WRITE_LINE_MEMBER(cassette_txc_rxc_w);
|
||||||
DECLARE_WRITE_LINE_MEMBER(write_cas_tx);
|
DECLARE_WRITE_LINE_MEMBER(write_cas_tx);
|
||||||
DECLARE_WRITE_LINE_MEMBER(poly88_usart_rxready);
|
DECLARE_WRITE_LINE_MEMBER(poly88_usart_rxready);
|
||||||
IRQ_CALLBACK_MEMBER(poly88_irq_callback);
|
IRQ_CALLBACK_MEMBER(poly88_irq_callback);
|
||||||
@ -77,7 +78,8 @@ private:
|
|||||||
void poly88_mem(address_map &map);
|
void poly88_mem(address_map &map);
|
||||||
|
|
||||||
required_device<cpu_device> m_maincpu;
|
required_device<cpu_device> m_maincpu;
|
||||||
required_device<i8251_device> m_uart;
|
required_device<i8251_device> m_usart;
|
||||||
|
required_device<mm5307_device> m_brg;
|
||||||
required_device<cassette_image_device> m_cassette;
|
required_device<cassette_image_device> m_cassette;
|
||||||
required_ioport m_linec;
|
required_ioport m_linec;
|
||||||
required_ioport m_line0;
|
required_ioport m_line0;
|
||||||
|
@ -24,9 +24,6 @@ void poly88_state::device_timer(emu_timer &timer, device_timer_id id, int param,
|
|||||||
case TIMER_KEYBOARD:
|
case TIMER_KEYBOARD:
|
||||||
keyboard_callback(ptr, param);
|
keyboard_callback(ptr, param);
|
||||||
break;
|
break;
|
||||||
case TIMER_CASSETTE:
|
|
||||||
poly88_cassette_timer_callback(ptr, param);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
assert_always(false, "Unknown id in poly88_state::device_timer");
|
assert_always(false, "Unknown id in poly88_state::device_timer");
|
||||||
}
|
}
|
||||||
@ -42,9 +39,10 @@ TIMER_CALLBACK_MEMBER(poly88_state::poly88_usart_timer_callback)
|
|||||||
WRITE8_MEMBER(poly88_state::poly88_baud_rate_w)
|
WRITE8_MEMBER(poly88_state::poly88_baud_rate_w)
|
||||||
{
|
{
|
||||||
logerror("poly88_baud_rate_w %02x\n",data);
|
logerror("poly88_baud_rate_w %02x\n",data);
|
||||||
m_usart_timer = timer_alloc(TIMER_USART);
|
m_brg->control_w(data & 15);
|
||||||
m_usart_timer->adjust(attotime::zero, 0, attotime::from_hz(300));
|
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
m_usart_timer->adjust(attotime::zero, 0, attotime::from_hz(300));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t poly88_state::row_number(uint8_t code) {
|
uint8_t poly88_state::row_number(uint8_t code) {
|
||||||
@ -149,8 +147,6 @@ TIMER_CALLBACK_MEMBER(poly88_state::keyboard_callback)
|
|||||||
} else {
|
} else {
|
||||||
m_last_code = key_code;
|
m_last_code = key_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_set(attotime::from_hz(24000), TIMER_KEYBOARD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IRQ_CALLBACK_MEMBER(poly88_state::poly88_irq_callback)
|
IRQ_CALLBACK_MEMBER(poly88_state::poly88_irq_callback)
|
||||||
@ -163,7 +159,7 @@ WRITE_LINE_MEMBER(poly88_state::write_cas_tx)
|
|||||||
m_cas_tx = state;
|
m_cas_tx = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIMER_CALLBACK_MEMBER(poly88_state::poly88_cassette_timer_callback)
|
WRITE_LINE_MEMBER(poly88_state::cassette_txc_rxc_w)
|
||||||
{
|
{
|
||||||
int data;
|
int data;
|
||||||
int current_level;
|
int current_level;
|
||||||
@ -186,13 +182,13 @@ TIMER_CALLBACK_MEMBER(poly88_state::poly88_cassette_timer_callback)
|
|||||||
{
|
{
|
||||||
data = (!m_previous_level && current_level) ? 1 : 0;
|
data = (!m_previous_level && current_level) ? 1 : 0;
|
||||||
//data = current_level;
|
//data = current_level;
|
||||||
m_uart->write_rxd(data);
|
m_usart->write_rxd(data);
|
||||||
|
|
||||||
m_clk_level_tape = 1;
|
m_clk_level_tape = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_uart->write_rxc(m_clk_level_tape);
|
m_usart->write_rxc(m_clk_level_tape);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* tape writing */
|
/* tape writing */
|
||||||
@ -203,15 +199,14 @@ TIMER_CALLBACK_MEMBER(poly88_state::poly88_cassette_timer_callback)
|
|||||||
m_cassette->output(data&0x01 ? 1 : -1);
|
m_cassette->output(data&0x01 ? 1 : -1);
|
||||||
|
|
||||||
m_clk_level_tape = m_clk_level_tape ? 0 : 1;
|
m_clk_level_tape = m_clk_level_tape ? 0 : 1;
|
||||||
m_uart->write_txc(m_clk_level_tape);
|
m_usart->write_txc(m_clk_level_tape);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_clk_level_tape = 1;
|
m_clk_level_tape = 1;
|
||||||
|
|
||||||
m_clk_level = m_clk_level ? 0 : 1;
|
m_usart->write_txc(state);
|
||||||
m_uart->write_txc(m_clk_level);
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,17 +214,19 @@ TIMER_CALLBACK_MEMBER(poly88_state::poly88_cassette_timer_callback)
|
|||||||
void poly88_state::init_poly88()
|
void poly88_state::init_poly88()
|
||||||
{
|
{
|
||||||
m_previous_level = 0;
|
m_previous_level = 0;
|
||||||
m_clk_level = m_clk_level_tape = 1;
|
m_clk_level_tape = 1;
|
||||||
m_cassette_timer = timer_alloc(TIMER_CASSETTE);
|
|
||||||
m_cassette_timer->adjust(attotime::zero, 0, attotime::from_hz(600));
|
|
||||||
|
|
||||||
timer_set(attotime::from_hz(24000), TIMER_KEYBOARD);
|
m_usart_timer = timer_alloc(TIMER_USART);
|
||||||
|
m_keyboard_timer = timer_alloc(TIMER_KEYBOARD);
|
||||||
|
m_keyboard_timer->adjust(attotime::from_hz(24000), 0, attotime::from_hz(24000));
|
||||||
}
|
}
|
||||||
|
|
||||||
void poly88_state::machine_reset()
|
void poly88_state::machine_reset()
|
||||||
{
|
{
|
||||||
m_intr = 0;
|
m_intr = 0;
|
||||||
m_last_code = 0;
|
m_last_code = 0;
|
||||||
|
|
||||||
|
m_brg->control_w(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
INTERRUPT_GEN_MEMBER(poly88_state::poly88_interrupt)
|
INTERRUPT_GEN_MEMBER(poly88_state::poly88_interrupt)
|
||||||
@ -327,6 +324,6 @@ SNAPSHOT_LOAD_MEMBER( poly88_state, poly88 )
|
|||||||
}
|
}
|
||||||
pos+=recordLen;
|
pos+=recordLen;
|
||||||
}
|
}
|
||||||
m_uart->reset();
|
m_usart->reset();
|
||||||
return image_init_result::PASS;
|
return image_init_result::PASS;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user