Add skeleton CRT9028 device (nw)

This commit is contained in:
AJR 2019-02-03 13:12:12 -05:00
parent 3cc0f27d89
commit 44f375b47d
6 changed files with 377 additions and 17 deletions

View File

@ -113,6 +113,18 @@ if (VIDEOS["CRT9021"]~=null) then
}
end
--------------------------------------------------
--
--@src/devices/video/crt9028.h,VIDEOS["CRT9028"] = true
--------------------------------------------------
if (VIDEOS["CRT9028"]~=null) then
files {
MAME_DIR .. "src/devices/video/crt9028.cpp",
MAME_DIR .. "src/devices/video/crt9028.h",
}
end
--------------------------------------------------
--
--@src/devices/video/crt9212.h,VIDEOS["CRT9212"] = true

View File

@ -285,6 +285,7 @@ VIDEOS["BUFSPRITE"] = true
VIDEOS["CESBLIT"] = true
--VIDEOS["CRT9007"] = true
--VIDEOS["CRT9021"] = true
--VIDEOS["CRT9028"] = true
--VIDEOS["CRT9212"] = true
VIDEOS["CRTC_EGA"] = true
--VIDEOS["DL1416"] = true

View File

@ -297,6 +297,7 @@ VIDEOS["CDP1862"] = true
--VIDEOS["CESBLIT"] = true
VIDEOS["CRT9007"] = true
VIDEOS["CRT9021"] = true
VIDEOS["CRT9028"] = true
VIDEOS["CRT9212"] = true
VIDEOS["CRTC_EGA"] = true
VIDEOS["DL1416"] = true

View File

@ -0,0 +1,220 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Standard Microsystems CRT9028/9128 Video Terminal Logic Controller
The CRT 9028 and CRT 9128 are single-chip terminal-oriented video
processors. The two differ from each other in their bus protocol
for accessing the address, data and status registers: the 9028 has
separate RD and WR strobes for an 8051 or similar microcontroller,
while the 9128 replaces these with DS and R/W inputs that are more
Z8-oriented. A separate address/data bus connects to a 2Kx8 static
RAM or similar as display memory.
The internal 128-character set is mask-programmed, as are all
screen timings, with alternate vertical timings to allow operation
at either 60 Hz or 50 Hz. Mask parameters also determine the
polarity of the sync signals, the positioning of the underline
attribute and cursor and the dot patterns used for 6-segment wide
(block) graphics and 4-segment thin (line) graphics.
TODO: implement timing and display functions
**********************************************************************/
#include "emu.h"
#include "video/crt9028.h"
#include "screen.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(CRT9028_000, crt9028_000_device, "crt9028_000", "CRT9028-000 VTLC")
//**************************************************************************
// DEVICE IMPLEMENTATION
//**************************************************************************
//-------------------------------------------------
// crt9028_device - constructor
//-------------------------------------------------
crt9028_device::crt9028_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock,
int dots_per_char, int chars_per_row, int horiz_blanking, int hsync_delay, int hsync_width, bool hsync_active,
int char_rows, int scans_per_char, bool vsync_active,
int vert_blanking, int vsync_delay, bool vsync_width,
int alt_vert_blanking, int alt_vsync_delay, bool alt_vsync_width,
int csync_delay, int csync_width, int underline,
u16 wide_gfx_seg1_4, u16 wide_gfx_seg2_5, u16 wide_gfx_seg3_6, u8 wide_gfx_pattern,
u16 thin_gfx_seg1, u16 thin_gfx_seg2, u16 thin_gfx_seg3, u16 thin_gfx_seg4,
u8 thin_gfx_dots1, u8 thin_gfx_dots2, u8 thin_gfx_dots3, u8 thin_gfx_dots4)
: device_t(mconfig, type, tag, owner, clock)
, device_memory_interface(mconfig, *this)
, device_video_interface(mconfig, *this)
, m_space_config("charram", ENDIANNESS_LITTLE, 8, 11, 0)
, m_charset(*this, "charset")
, m_hsync_callback(*this)
, m_vsync_callback(*this)
, m_dots_per_char(dots_per_char)
, m_chars_per_row(chars_per_row)
, m_horiz_blanking(horiz_blanking)
, m_hsync_delay(hsync_delay)
, m_hsync_width(hsync_width)
, m_hsync_active(hsync_active)
, m_char_rows(char_rows)
, m_scans_per_char(scans_per_char)
, m_vsync_active(vsync_active)
, m_vert_blanking{vert_blanking, alt_vert_blanking}
, m_vsync_delay{vsync_delay, alt_vsync_delay}
, m_vsync_width{vsync_width, alt_vsync_width}
, m_csync_delay(csync_delay)
, m_csync_width(csync_width)
, m_underline(underline)
, m_wide_gfx_seg{wide_gfx_seg1_4, wide_gfx_seg2_5, wide_gfx_seg3_6}
, m_wide_gfx_pattern(wide_gfx_pattern)
, m_thin_gfx_seg{thin_gfx_seg1, thin_gfx_seg2, thin_gfx_seg3, thin_gfx_seg4}
, m_thin_gfx_dots{thin_gfx_dots1, thin_gfx_dots2, thin_gfx_dots3, thin_gfx_dots4}
{
// Mostly unused now
(void)m_hsync_delay;
(void)m_hsync_width;
(void)m_hsync_active;
(void)m_vsync_active;
(void)m_vsync_delay;
(void)m_vsync_width;
(void)m_csync_delay;
(void)m_csync_width;
(void)m_underline;
(void)m_wide_gfx_seg;
(void)m_wide_gfx_pattern;
(void)m_thin_gfx_seg;
(void)m_thin_gfx_dots;
}
//-------------------------------------------------
// crt9028_000_device - constructor
//-------------------------------------------------
crt9028_000_device::crt9028_000_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: crt9028_device(mconfig, CRT9028_000, tag, owner, clock,
7, 80, 20, 4, 8, false,
24, 10, false,
20, 4, 8,
72, 30, 10,
2, 8, 9,
0x3c0, 0x038, 0x007, 0x0f,
0x3e0, 0x020, 0x03f, 0x020,
0x10, 0xff, 0x10, 0xff)
{
}
//-------------------------------------------------
// device_config_complete - finalise device
// configuration
//-------------------------------------------------
void crt9028_device::device_config_complete()
{
if (!has_screen())
return;
if (screen().refresh_attoseconds() == 0)
{
int visible_scan_lines = m_char_rows * m_scans_per_char;
screen().set_raw(clock(), m_dots_per_char * (m_chars_per_row + m_horiz_blanking), 0, m_dots_per_char * m_chars_per_row,
visible_scan_lines + m_vert_blanking[0], 0, visible_scan_lines);
}
if (!screen().has_screen_update())
screen().set_screen_update(screen_update_rgb32_delegate(FUNC(crt9028_device::screen_update), this));
}
//-------------------------------------------------
// memory_space_config - return the configuration
// for the address spaces
//-------------------------------------------------
device_memory_interface::space_config_vector crt9028_device::memory_space_config() const
{
return space_config_vector{std::make_pair(0, &m_space_config)};
}
//-------------------------------------------------
// device_resolve_objects - resolve objects that
// may be needed for other devices to set
// initial conditions at start time
//-------------------------------------------------
void crt9028_device::device_resolve_objects()
{
m_hsync_callback.resolve_safe();
m_vsync_callback.resolve_safe();
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void crt9028_device::device_start()
{
m_space = &space(0);
}
//-------------------------------------------------
// screen_update - screen update method
//-------------------------------------------------
u32 crt9028_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
return 0;
}
//-------------------------------------------------
// read - read from data or status register
//-------------------------------------------------
u8 crt9028_device::read(offs_t offset)
{
return 0xff;
}
//-------------------------------------------------
// write - write to data or address register
//-------------------------------------------------
void crt9028_device::write(offs_t offset, u8 data)
{
logerror("%s: Writing %02X to %s register\n", machine().describe_context(), data, BIT(offset, 0) ? "address" : "data");
}
//**************************************************************************
// INTERNAL ROM
//**************************************************************************
ROM_START(crt9028_000)
ROM_REGION(0x400, "charset", 0)
ROM_LOAD("crt9028_000.bin", 0x000, 0x400, NO_DUMP)
ROM_END
//-------------------------------------------------
// rom_region - return a pointer to the implicit
// rom region description for this device
//-------------------------------------------------
const tiny_rom_entry *crt9028_000_device::device_rom_region() const
{
return ROM_NAME(crt9028_000);
}

127
src/devices/video/crt9028.h Normal file
View File

@ -0,0 +1,127 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Standard Microsystems CRT9028/9128 Video Terminal Logic Controller
***********************************************************************
_____ _____
DA8 1 |* \__/ | 40 DA7
DA9 2 | | 39 DA6
DA10 3 | | 38 DA5
GND 4 | | 37 DA4
XTAL2 5 | | 36 DA3
XTAL1 6 | | 35 DA2
/VIDEO 7 | | 34 DA1
INTOUT 8 | | 33 DA0
/DWR 9 | | 32 DB7
DD0 10 | CRT 9028 | 31 DB6
DD1 11 | CRT 9128 | 30 DB5
DD2 12 | | 29 DB4
DD3 13 | | 28 DB3
DD4 14 | | 27 DB2
DD5 15 | | 26 DB1
DD6 16 | | 25 DB0
DD7 17 | | 24 A/D
HSYNC 18 | | 23 /RD or /DS
VSYNC 19 | | 22 /WR or R/W
CSYNC 20 |______________| 21 VCC
**********************************************************************/
#ifndef MAME_VIDEO_CRT9028_H
#define MAME_VIDEO_CRT9028_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> crt9028_device
class crt9028_device : public device_t, public device_memory_interface, public device_video_interface
{
public:
// device configuration
auto hsync_callback() { return m_hsync_callback.bind(); }
auto vsync_callback() { return m_hsync_callback.bind(); }
// read/write handlers
u8 read(offs_t offset);
void write(offs_t offset, u8 data);
// screen update method
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
protected:
// base type constructor
crt9028_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock,
int dots_per_char, int chars_per_row, int horiz_blanking, int hsync_delay, int hsync_width, bool hsync_active,
int char_rows, int scans_per_char, bool vsync_active,
int vert_blanking, int vsync_delay, bool vsync_width,
int alt_vert_blanking, int alt_vsync_delay, bool alt_vsync_width,
int csync_delay, int csync_width, int underline,
u16 wide_gfx_seg1_4, u16 wide_gfx_seg2_5, u16 wide_gfx_seg3_6, u8 wide_gfx_pattern,
u16 thin_gfx_seg1, u16 thin_gfx_seg2, u16 thin_gfx_seg3, u16 thin_gfx_seg4,
u8 thin_gfx_dots1, u8 thin_gfx_dots2, u8 thin_gfx_dots3, u8 thin_gfx_dots4);
// device-specific overrides
virtual void device_config_complete() override;
virtual void device_resolve_objects() override;
virtual void device_start() override;
// device_memory_interface overrides
virtual space_config_vector memory_space_config() const override;
private:
// address space for display memory
const address_space_config m_space_config;
address_space *m_space;
// internal character set
required_region_ptr<u8> m_charset;
// timing callbacks
devcb_write_line m_hsync_callback;
devcb_write_line m_vsync_callback;
// mask parameters
const int m_dots_per_char;
const int m_chars_per_row;
const int m_horiz_blanking;
const int m_hsync_delay;
const int m_hsync_width;
const bool m_hsync_active;
const int m_char_rows;
const int m_scans_per_char;
const bool m_vsync_active;
const int m_vert_blanking[2];
const int m_vsync_delay[2];
const int m_vsync_width[2];
const int m_csync_delay;
const int m_csync_width;
const int m_underline;
const u16 m_wide_gfx_seg[3];
const u8 m_wide_gfx_pattern;
const u16 m_thin_gfx_seg[4];
const u8 m_thin_gfx_dots[4];
};
// ======================> crt9028_000_device
class crt9028_000_device : public crt9028_device
{
public:
// device constructor
crt9028_000_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
// device-specific overrides
virtual const tiny_rom_entry *device_rom_region() const;
};
// device type declarations
DECLARE_DEVICE_TYPE(CRT9028_000, crt9028_000_device)
#endif // MAME_VIDEO_CRT9028_H

View File

@ -19,7 +19,7 @@
#include "bus/rs232/rs232.h"
#include "machine/eepromser.h"
#include "sound/spkrdev.h"
//#include "video/crt9028.h"
#include "video/crt9028.h"
#include "screen.h"
#include "speaker.h"
@ -29,6 +29,7 @@ public:
cardinal_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_eeprom(*this, "eeprom")
, m_vtlc(*this, "vtlc")
, m_speaker(*this, "speaker")
, m_rs232(*this, "rs232")
, m_address_select(false)
@ -41,8 +42,6 @@ protected:
virtual void machine_start() override;
private:
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
u8 p1_r();
void p1_w(u8 data);
@ -51,9 +50,10 @@ private:
void prog_map(address_map &map);
void ext_map(address_map &map);
void ram_map(address_map &map);
required_device<eeprom_serial_93cxx_device> m_eeprom;
//required_device<crt9028_device> m_vtlc;
required_device<crt9028_device> m_vtlc;
required_device<speaker_sound_device> m_speaker;
required_device<rs232_port_device> m_rs232;
@ -66,11 +66,6 @@ void cardinal_state::machine_start()
save_item(NAME(m_address_select));
}
u32 cardinal_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
return 0;
}
u8 cardinal_state::p1_r()
{
return 0x9f | (m_eeprom->do_read() << 5) | (0 /*m_rs232->cts_r()*/ << 6);
@ -90,12 +85,12 @@ void cardinal_state::p1_w(u8 data)
u8 cardinal_state::vtlc_r()
{
return 0xff;
return m_vtlc->read(m_address_select);
}
void cardinal_state::vtlc_w(u8 data)
{
logerror("%s: Writing %02X to CRT9028 %s register\n", machine().describe_context(), data, m_address_select ? "address" : "data");
m_vtlc->write(m_address_select, data);
}
void cardinal_state::prog_map(address_map &map)
@ -108,6 +103,11 @@ void cardinal_state::ext_map(address_map &map)
map(0, 0).mirror(0xffff).rw(FUNC(cardinal_state::vtlc_r), FUNC(cardinal_state::vtlc_w));
}
void cardinal_state::ram_map(address_map &map)
{
map(0x000, 0x7ff).ram();
}
static INPUT_PORTS_START(cardinal)
PORT_START("P3")
@ -133,13 +133,12 @@ void cardinal_state::cardinal(machine_config &config)
EEPROM_93C06_16BIT(config, m_eeprom);
//CRT9028_000(config, m_vtlc, 10.92_MHz_XTAL);
//m_vtlc->set_screen("screen");
//m_vtlc->vsync_callback().set_inputline("maincpu", MCS51_INT0_LINE);
CRT9028_000(config, m_vtlc, 10.92_MHz_XTAL);
m_vtlc->set_screen("screen");
m_vtlc->set_addrmap(0, &cardinal_state::ram_map);
m_vtlc->vsync_callback().set_inputline("maincpu", MCS51_INT0_LINE).invert();
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_raw(10.92_MHz_XTAL, 700, 0, 560, 260, 0, 240);
screen.set_screen_update(FUNC(cardinal_state::screen_update));
SCREEN(config, "screen", SCREEN_TYPE_RASTER);
SPEAKER(config, "mono").front_center();
SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.05);