dvk_ksm: baud rate generator + source cleanup (#2432)

This commit is contained in:
Sergey Svishchev 2017-08-23 04:49:47 +03:00 committed by Vas Crabb
parent 47ea72ae0c
commit 14891e3c99

View File

@ -3,22 +3,12 @@
/***************************************************************************
KSM (Kontroller Simvolnogo Monitora = Character Display Controller),
a single-board replacement for standalone 15IE-00-013 terminal (ie15.c)
in later-model DVK desktops.
a single-board replacement for standalone 15IE-00-013 terminal (ie15.c
driver in MAME) in later-model DVK desktops.
MPI (Q-Bus clone) board, consumes only power from the bus.
Interfaces with MS7004 (DEC LK201 workalike) keyboard and monochrome CRT.
Hardware revisions (XXX verify everything):
- 7.102.076 -- has DIP switches, SRAM at 0x2000, model name "KSM"
- 7.102.228 -- no DIP switches, ?? SRAM at 0x2100, model name "KSM-01"
Two sets of dumps exist:
- one puts SRAM at 0x2000, which is where technical manual puts it,
but chargen has 1 missing pixel in 'G' character.
- another puts SRAM at 0x2100, but has no missing pixel.
Merge them for now into one (SRAM at 0x2000 and no missing pixel).
Emulates a VT52 without copier (ESC Z response is ESC / M), with
Hold Screen mode and Graphics character set (but it is unique and
mapped to a different range -- 100..137).
@ -54,8 +44,9 @@ ksm|DVK KSM,
To do:
- verify if pixel stretching is done by hw
- verify details of hw revisions (memory map, DIP presence...)
- baud rate selection
- verify details of hw revisions. known ones:
- decimal 7.102.076 -- has DIP switches, model name "KSM".
- decimal 7.102.228 -- no DIP switches, model name "KSM-01" -- no dump.
****************************************************************************/
@ -77,13 +68,14 @@ ksm|DVK KSM,
#define KSM_DISP_HORZ 800
#define KSM_HORZ_START 200
#define KSM_TOTAL_VERT 28*11
#define KSM_DISP_VERT 25*11
#define KSM_VERT_START 2*11
#define KSM_TOTAL_VERT (28 * 11)
#define KSM_DISP_VERT (25 * 11)
#define KSM_VERT_START (2 * 11)
#define KSM_STATUSLINE_TOTAL 11
#define KSM_STATUSLINE_VRAM 0xF8B0
#define VERBOSE_DBG 0 /* general debug messages */
#define DBG_LOG(N,M,A) \
@ -119,8 +111,13 @@ public:
virtual void video_start() override;
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock);
DECLARE_WRITE_LINE_MEMBER(write_line_clock);
DECLARE_WRITE_LINE_MEMBER(write_brga);
DECLARE_WRITE_LINE_MEMBER(write_brgb);
DECLARE_WRITE_LINE_MEMBER(write_brgc);
DECLARE_WRITE8_MEMBER(ksm_ppi_porta_w);
DECLARE_WRITE8_MEMBER(ksm_ppi_portc_w);
@ -136,6 +133,17 @@ private:
uint16_t ptr;
} m_video;
enum
{
TIMER_ID_BRG = 0
};
bool brg_state;
int brga, brgb, brgc;
emu_timer *m_brg = nullptr;
void update_brg(bool a, bool b, int c);
required_shared_ptr<uint8_t> m_p_videoram;
required_device<cpu_device> m_maincpu;
required_device<pic8259_device> m_pic8259;
@ -206,15 +214,31 @@ static INPUT_PORTS_START( ksm )
PORT_DIPSETTING(0x0E, "75")
INPUT_PORTS_END
void ksm_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if (id == TIMER_ID_BRG)
{
brg_state = !brg_state;
m_i8251line->write_txc(brg_state);
m_i8251line->write_rxc(brg_state);
}
}
void ksm_state::machine_reset()
{
memset(&m_video, 0, sizeof(m_video));
brga = 0;
brgb = 0;
brgc = 0;
brg_state = 0;
}
void ksm_state::video_start()
{
m_tmpclip = rectangle(0, KSM_DISP_HORZ - 1, 0, KSM_DISP_VERT - 1);
m_tmpbmp.allocate(KSM_DISP_HORZ, KSM_DISP_VERT);
m_brg = timer_alloc(TIMER_ID_BRG);
}
WRITE8_MEMBER(ksm_state::ksm_ppi_porta_w)
@ -225,7 +249,11 @@ WRITE8_MEMBER(ksm_state::ksm_ppi_porta_w)
WRITE8_MEMBER(ksm_state::ksm_ppi_portc_w)
{
DBG_LOG(1, "PPI port C", ("blink %d speed %d\n", BIT(data, 7), ((data >> 4) & 7)));
brgc = (data >> 5) & 3;
DBG_LOG(1, "PPI port C", ("raw %02x blink %d speed %d\n", data, BIT(data, 7), brgc));
update_brg(brga, brgb, brgc);
}
WRITE_LINE_MEMBER(ksm_state::write_keyboard_clock)
@ -234,10 +262,50 @@ WRITE_LINE_MEMBER(ksm_state::write_keyboard_clock)
m_i8251kbd->write_rxc(state);
}
WRITE_LINE_MEMBER(ksm_state::write_line_clock)
WRITE_LINE_MEMBER(ksm_state::write_brga)
{
m_i8251line->write_txc(state);
m_i8251line->write_rxc(state);
brga = state;
update_brg(brga, brgb, brgc);
}
WRITE_LINE_MEMBER(ksm_state::write_brgb)
{
brgb = state;
update_brg(brga, brgb, brgc);
}
void ksm_state::update_brg(bool a, bool b, int c)
{
DBG_LOG(2, "brg", ("%d %d %d\n", a, b, c));
if (a && b) return;
switch ((a << 3) + (b << 2) + c)
{
case 0xa:
m_brg->adjust(attotime::from_hz(9600*16*2), 0, attotime::from_hz(9600*16*2));
break;
case 0x8:
m_brg->adjust(attotime::from_hz(4800*16*2), 0, attotime::from_hz(4800*16*2));
break;
case 0x4:
m_brg->adjust(attotime::from_hz(2400*16*2), 0, attotime::from_hz(2400*16*2));
break;
case 0x5:
m_brg->adjust(attotime::from_hz(1200*16*2), 0, attotime::from_hz(1200*16*2));
break;
case 0x6:
m_brg->adjust(attotime::from_hz(600*16*2), 0, attotime::from_hz(600*16*2));
break;
case 0x7:
m_brg->adjust(attotime::from_hz(300*16*2), 0, attotime::from_hz(300*16*2));
break;
}
}
/*
@ -362,13 +430,14 @@ static MACHINE_CONFIG_START( ksm )
MCFG_PIC8259_ADD( "pic8259", INPUTLINE("maincpu", 0), VCC, NOOP)
// D30
MCFG_DEVICE_ADD("ppi8255", I8255, 0)
MCFG_I8255_OUT_PORTA_CB(WRITE8(ksm_state, ksm_ppi_porta_w))
MCFG_I8255_IN_PORTB_CB(IOPORT("SA1"))
MCFG_I8255_IN_PORTC_CB(IOPORT("SA2"))
MCFG_I8255_OUT_PORTC_CB(WRITE8(ksm_state, ksm_ppi_portc_w))
// serial connection to host
// D42 - serial connection to host
MCFG_DEVICE_ADD( "i8251line", I8251, 0)
MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd))
MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("pic8259", pic8259_device, ir3_w))
@ -378,13 +447,11 @@ static MACHINE_CONFIG_START( ksm )
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("i8251line", i8251_device, write_cts))
MCFG_RS232_DSR_HANDLER(DEVWRITELINE("i8251line", i8251_device, write_dsr))
// XXX /RTS, /DTR, PC5 and PC6 are wired to baud rate generator.
MCFG_DEVICE_ADD("line_clock", CLOCK, 9600*16) // 8251 is set to /16 on the clock input
MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(ksm_state, write_line_clock))
// serial connection to MS7004 keyboard
// D41 - serial connection to MS7004 keyboard
MCFG_DEVICE_ADD( "i8251kbd", I8251, 0)
MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("pic8259", pic8259_device, ir1_w))
MCFG_I8251_RTS_HANDLER(WRITELINE(ksm_state, write_brga))
MCFG_I8251_DTR_HANDLER(WRITELINE(ksm_state, write_brgb))
MCFG_DEVICE_ADD("ms7004", MS7004, 0)
MCFG_MS7004_TX_HANDLER(DEVWRITELINE("i8251kbd", i8251_device, write_rxd))