From 92c614cfe5d50fd03c6fc19f63eb793f27f84f61 Mon Sep 17 00:00:00 2001 From: Joakim Larsson Edstrom Date: Fri, 22 Nov 2019 00:07:37 +0100 Subject: [PATCH] mda.cpp, eis_hgb107x: Ericsson High resolution Monochrome Graphics Board 1070 split out in its own file as being an oddity --- scripts/src/bus.lua | 2 + src/devices/bus/isa/eis_hgb107x.cpp | 603 ++++++++++++++++++++++++++++ src/devices/bus/isa/eis_hgb107x.h | 112 ++++++ src/devices/bus/isa/isa_cards.cpp | 1 + src/devices/bus/isa/mda.cpp | 519 ------------------------ src/devices/bus/isa/mda.h | 84 ---- src/mame/drivers/eispc.cpp | 2 +- 7 files changed, 719 insertions(+), 604 deletions(-) create mode 100644 src/devices/bus/isa/eis_hgb107x.cpp create mode 100644 src/devices/bus/isa/eis_hgb107x.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 8a7ef8bc2cc..79369295eee 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1463,6 +1463,8 @@ if (BUSES["ISA"]~=null) then MAME_DIR .. "src/devices/bus/isa/eis_sad8852.h", MAME_DIR .. "src/devices/bus/isa/eis_twib.cpp", MAME_DIR .. "src/devices/bus/isa/eis_twib.h", + MAME_DIR .. "src/devices/bus/isa/eis_hgb107x.cpp", + MAME_DIR .. "src/devices/bus/isa/eis_hgb107x.h", MAME_DIR .. "src/devices/bus/isa/lbaenhancer.cpp", MAME_DIR .. "src/devices/bus/isa/lbaenhancer.h", MAME_DIR .. "src/devices/bus/isa/np600.cpp", diff --git a/src/devices/bus/isa/eis_hgb107x.cpp b/src/devices/bus/isa/eis_hgb107x.cpp new file mode 100644 index 00000000000..3503802811a --- /dev/null +++ b/src/devices/bus/isa/eis_hgb107x.cpp @@ -0,0 +1,603 @@ +// license:BSD-3-Clause +// copyright-holders: Joakim Larsson Edström +/***************************************************************************** + + Ericsson PC Monochrome HR Graphics Board 1070 + +******************************************************************************/ + +/* PCB layouts and assembly years from online pictures and physical unit. + Ericsson - marked SPVT02 8301 60 53-10, assembled in 1985 indicated by chip dates + +--------------------------------------------------------------------------------------+ ___ + | IC1 IC2 IC3 IC4 IC5 +-IC15--EPROM-+ IC6 IC7 IC8 S1 || + | |8363 65 14-80| || + | IC9 IC10 IC11 IC12 IC13 IC14|CG 50821 A64 |+------------------++-IC24 EPROM--+ || + | +-------------+| CRTC HD46505SP-1 ||10-40VP | || + | IC16 IC17 IC18 IC19 IC20 IC21 IC22 | IC23 HD68A45SP ||402 28 A19 | J4|| not + | +------------------++-------------+ || mounted + | IC25 IC26 IC27 IC28 IC29 IC30 IC31 IC32 IC33 IC34 || + | O-|__ + | IC35 IC36 IC37 IC38 IC39 IC40 IC41 IC42 IC43 IC44 || | + | ||DB15 + | IC45 IC46 IC47 IC48 IC49 IC50 IC51 IC52 IC53 IC54 || | + | ||__| + | IC55 IC56 IC57 IC58 IC59 IC60 IC61 IC62 IC63 IC64 O-| + | J1A || + | IC65 IC66 IC67 IC68 IC69 IC70 IC71 IC72 +--------------------------------------------+| + +-----------------------------------------+ ||||||||| ||||||||||||||||||||||||| | + I85565 A85571 (labels) | + | + + IC's (from photos) + ------------------------------------------------------------------------------ + IC1 74F109 IC26 74F86 IC51 TMS4416-15NL 4 x 16Kbits DRAM + IC2 74LS393 IC27 74LS08 IC52 74ALS574 + IC3 74F64 IC28 74F153 IC53 74LS138 + IC4 74ALS299 IC29 74LS174 IC54 74F86 + IC5 74LS375 IC30 74LS374 IC55 74F109 + IC6 74LS151 IC31 74LS374 IC56 74F32 + IC7 74LS153 IC32 74ALS574 IC57 74F109 + IC8 74LS389? IC33 74LS08 IC58 74F00? + IC9 74F02 IC34 74LS245 IC59 74LS244 + IC10 74ALS109 IC35 74F10? IC60 TMS4416-15NL 4 x 16Kbits DRAM + IC11 Crystal 17.040MHz IC36 74LS02 IC61 TMS4416-15NL 4 x 16Kbits DRAM + IC12 74F64 IC37 74LS00 IC62 74ALS574 + IC13 74ALS299 IC38 74F374 IC63 74LS138 + IC14 PAL? 10-70ART40101 IC39 74LS125 IC64 74LS245 + IC15 EPROM 8363 65 14-80 CG 50821 A64 IC40 74LS244 IC65 74LS00 + IC16 Crystal 19.170MHz IC41 74LS244 IC66 74LS02 + IC17 74LS10 IC42 74LS574 IC67 74LS51 + IC18 74F08 IC43 74LS32 IC68 74LS04 + IC19 74ALS574 IC44 MC10124 - TTL to MECL converter IC69 74LS153 + IC20 74LS299 IC45 74LS109 IC70 74LS109 + IC21 74LS273 IC46 74LS00 IC71 74LS138 + IC22 74ALS574 IC47 74F194 IC72 74LS139 + IC23 CRTC HD46505SP,HD68A45SP IC48 74F04 + IC24 EPROM 2764, 10-40 VP 402 28 A19 IC49 74LS174 + IC25 74ALS109 IC50 TMS4416-15NL 4 x 16Kbits DRAM + + General description + ------------------- + The PCB has a 2 bit DIP switch S1 and a DB15 non standard video connector. There is also an unsoldered J4 connector + above the DB15 but no hole prepared for a connector in the plate. Above the J4 connector there is a two pin PCB connector + that probably receives the power for the monitor for the DB15 from the PSU. + + Just below IC65 and IC66 there are two labels saying "I 85565" and "A E85571" respectively + + Video cable, card DB15 <---> monitor DB25 + --------------------------------------------------- + Ericsson 2 +VS 4 Ericsson + Monochrome 3 VS return 2 Monochrome HR + HR Graphics 10 +VS 17 Monitors 3111 (Amber) or + Board 1070 11 VS return 15 3712/3715 (Black & White) + 4 VSYNC 6 + 12 VSYNC 19 + 5 HSYNC 7 + 13 HSYNC 20 + 6 High intensity 8 + 14 High intensity 21 + 7 Video 9 + 15 Video 22 + 8 GND 11 + + This board is normaly used with an Ericsson monitor due to the non standard connector. + Trivia: https://www.pinterest.se/pin/203084264425177097/ + */ + +#include "emu.h" +#include "eis_hgb107x.h" + +#include "screen.h" + +#define LOG_READ (1U << 1) +#define LOG_SETUP (1U << 2) +#define LOG_ROW (1U << 3) +#define LOG_MODE (1U << 4) +#define LOG_CHRG (1U << 5) +#define LOG_STAT (1U << 6) + +//#define VERBOSE (LOG_MODE|LOG_SETUP|LOG_ROW) +//#define LOG_OUTPUT_STREAM std::cout + +#include "logmacro.h" + +#define LOGR(...) LOGMASKED(LOG_READ, __VA_ARGS__) +#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) +#define LOGROW(...) LOGMASKED(LOG_ROW, __VA_ARGS__) +#define LOGMODE(...) LOGMASKED(LOG_MODE, __VA_ARGS__) +#define LOGCHRG(...) LOGMASKED(LOG_CHRG, __VA_ARGS__) +#define LOGSTAT(...) LOGMASKED(LOG_STAT, __VA_ARGS__) + +#ifdef _MSC_VER +#define FUNCNAME __func__ +#else +#define FUNCNAME __PRETTY_FUNCTION__ +#endif + +#define MC6845_NAME "mc6845" + +enum +{ + MDA_TEXT_INTEN = 0, + MDA_TEXT_BLINK, + MDA_LOWRES_TEXT_INTEN, + MDA_LOWRES_TEXT_BLINK +}; + +#define EPC_MDA_SCREEN "epc_mda_screen" // TODO: use a device finder reference instead + +ROM_START( epc ) + ROM_REGION(0x2000,"chargen", 0) + ROM_LOAD("8363_65_14_80_cg_50821_a64.bin", 0x00000, 0x2000, CRC(be709786) SHA1(38ab26224bbe66bbe2bb2ccac29b41cbf78bdbf8)) + //ROM_LOAD("10_40_vp_402_28_ic_24_a19.bin", 0x00000, 0x2000, CRC(2aa53b92) SHA1(87051a037249eb631d7d2191bc0e925125c60f39)) +ROM_END + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** +DEFINE_DEVICE_TYPE(ISA8_EPC_MDA, isa8_epc_mda_device, "isa_epc_mda", "Ericsson PC Monochrome HR Graphics Board 1070") + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- +/* There are two crystals on the board: 19.170Mhz and 17.040MHz TODO: verify use */ +/* Text modes uses 720x400 base resolution and the Graphics modes 320/640x200/400 */ +/* This matches the difference between the crystals so we assume this for now */ +void isa8_epc_mda_device::device_add_mconfig(machine_config &config) +{ + screen_device &screen(SCREEN(config, EPC_MDA_SCREEN, SCREEN_TYPE_RASTER)); + screen.set_raw(XTAL(19'170'000) / 4, 720, 0, 720, 400, 0, 400); + screen.set_screen_update(MC6845_NAME, FUNC(mc6845_device::screen_update)); + + HD6845S(config, m_crtc, XTAL(19'170'000) / 16); // clock and divider are guesswork + m_crtc->set_screen(EPC_MDA_SCREEN); + m_crtc->set_show_border_area(false); + m_crtc->set_char_width(8); + + m_crtc->set_update_row_callback(FUNC(isa8_epc_mda_device::crtc_update_row)); + m_crtc->out_hsync_callback().set(FUNC(isa8_epc_mda_device::hsync_changed)); + m_crtc->out_vsync_callback().set(FUNC(isa8_epc_mda_device::vsync_changed)); +} + +//------------------------------------------------- +// rom_region - device-specific ROM region +//------------------------------------------------- +const tiny_rom_entry *isa8_epc_mda_device::device_rom_region() const +{ + return ROM_NAME( epc ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// isa8_epc_mda_device - constructor +//------------------------------------------------- +isa8_epc_mda_device::isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + isa8_epc_mda_device(mconfig, ISA8_EPC_MDA, tag, owner, clock) +{ +} + +isa8_epc_mda_device::isa8_epc_mda_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, type, tag, owner, clock), + device_isa8_card_interface(mconfig, *this), + m_crtc(*this, MC6845_NAME), + m_soft_chr_gen(nullptr), + m_s1(*this, "S1"), + m_color_mode(0), + m_mode_control2(0), + m_screen(*this, EPC_MDA_SCREEN), + m_io_monitor(*this, "MONITOR"), + m_chargen(*this, "chargen"), + m_installed(false), + m_framecnt(0), + m_mode_control(0), + m_update_row_type(-1), + m_chr_gen(nullptr), + m_vsync(0), + m_hsync(0), + m_pixel(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void isa8_epc_mda_device::device_start() +{ + /* Palette for use with the Ericsson Amber Monochrome HR CRT monitor 3111, P3 phospor 602nm 255,183, 0 */ + m_3111_pal[0] = rgb_t( 0, 0, 0); // black + m_3111_pal[1] = rgb_t( 143, 103, 0); // dim + m_3111_pal[2] = rgb_t( 191, 137, 0); // normal + m_3111_pal[3] = rgb_t( 255, 183, 0); // bright + + /* Palette for use with the Ericsson B&W Monochrome HR CRT monitor 3712/3715 */ + m_371x_pal[0] = rgb_t( 0, 0, 0); // black + m_371x_pal[1] = rgb_t( 143, 143, 143); // dim + m_371x_pal[2] = rgb_t( 191, 191, 191); // normal + m_371x_pal[3] = rgb_t( 255, 255, 255); // bright + + /* Init a default palette */ + m_pal = &m_3111_pal; // In case screen starts rendering before device_reset where we read the settings + m_videoram.resize(0x8000); + set_isa_device(); + m_installed = false; + m_hd6845s = subdevice(MC6845_NAME); +} + +void isa8_epc_mda_device::device_reset() +{ + m_framecnt = 0; + m_mode_control = 0; + m_vsync = 0; + m_hsync = 0; + m_pixel = 0; + + m_color_mode = m_s1->read(); + LOGSETUP("%s: m_color_mode:%02x\n", FUNCNAME, m_color_mode); + m_pal = (m_io_monitor-> read() & 1) == 1 ? &m_371x_pal : &m_3111_pal; + m_vmode = 0; + + if (m_installed == false) + { + m_isa->install_device(0x3b0, 0x3bf, read8_delegate(*this, FUNC(isa8_epc_mda_device::io_read)), write8_delegate(*this, FUNC(isa8_epc_mda_device::io_write))); + m_isa->install_bank(0xb0000, 0xb7fff, "bank_epc", &m_videoram[0]); // Monochrome emulation mode VRAM address + + // This check allows a color monitor adapter to be installed at this address range if color emulation is disabled + if (m_color_mode & 1) + { + m_isa->install_device(0x3d0, 0x3df, read8_delegate(*this, FUNC(isa8_epc_mda_device::io_read)), write8_delegate(*this, FUNC(isa8_epc_mda_device::io_write))); + m_isa->install_bank(0xb8000, 0xbffff, "bank_epc", &m_videoram[0]); // Color emulation mode VRAM address, but same 32KB areas as there are only this amount on the board + } + m_installed = true; + } +} + +/* + * Register Address table from the manual + * Ericsson name MDA mode CGA mode Standard name + *------------------------------------------------------------------------------- + * 6845 Address Registers 0x3b4 0x3d4 wo CRT Index reg + * 6845 Data Registers 0x3b5 0x3d5 wo CRT Data reg + * Mode Register 1 0x3b8 0x3d8 rw MDA/CGA mode reg (bit 0,1 & 4 incompatible) + * Mode Register 2 0x3bf 0x3df rw CRT/CPU page reg (incompatible w PCjr only) + * Status Register 0x3ba 0x3da r CGA/MDA status reg (incompatible) + * w EGA/VGA feature ccontrol reg (not used by this board) + */ +WRITE8_MEMBER(isa8_epc_mda_device::io_write ) +{ + LOG("%s: %04x <- %02x\n", FUNCNAME, offset, data); + switch( offset ) + { + case 0x04: + //LOGSETUP(" - HD6845S address write\n"); + m_hd6845s->address_w( data ); + break; + case 0x05: + //LOGSETUP(" - HD6845S register write\n"); + m_hd6845s->register_w( data ); + break; + case 0x08: // Mode 1 reg + LOGMODE(" - Mode register 1 write: %02x\n", data); + LOGMODE(" MSB attribute: %s\n", (data & 0x20) == 0 ? "intensity" : "blink"); + LOGMODE(" Horizontal px: %s\n", (data & 0x10) == 0 ? "320/LR" : "640/HR"); + LOGMODE(" Video : %s\n", (data & 0x08) == 0 ? "Disabled" : "Enabled"); + LOGMODE(" Mode : %s\n", (data & 0x02) == 0 ? "Text" : "Graphics"); + LOGMODE(" Text columns : %d\n", (data & 0x01) == 0 ? 40 : 80); + m_mode_control = data; + m_vmode &= ~(VM_GRAPH | VM_COLS80 | VM_HOR640); + m_vmode |= ((m_mode_control & 0x01) ? VM_COLS80 : 0); + m_vmode |= ((m_mode_control & 0x02) ? VM_GRAPH : 0); + m_vmode |= ((m_mode_control & 0x10) ? VM_HOR640 : 0); + m_update_row_type = ((data & 0x20) == 0 ? MDA_LOWRES_TEXT_INTEN : MDA_LOWRES_TEXT_BLINK); + { + rectangle rect(0, get_xres() - 1, 0, get_yres() -1); + m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50)); + } + LOGMODE("Video Mode:%02x\n\n", m_vmode); + break; + case 0x0f: // Mode 2 reg + LOGMODE(" - Mode register 2 write: %02x\n", data); + LOGMODE(" Vertical px : %s\n", (data & MR2_VER400) == 0 ? "200" : "400"); + LOGMODE(" Character set: %s\n", (data & MR2_CHRSET) == 0 ? "0" : "1"); + LOGMODE(" Emulated : %s\n", (data & MR2_COLEMU) == 0 ? "Color" : "Monochrome"); + m_mode_control2 = data; + m_vmode &= ~(VM_MONO | VM_VER400); + m_vmode |= ((m_mode_control2 & 0x04) ? VM_MONO : 0); + m_vmode |= ((m_mode_control2 & 0x80) ? VM_VER400 : 0); + { + rectangle rect(0, get_xres() - 1, 0, get_yres() -1); + m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50)); + } + LOGMODE("Video Mode:%02x\n\n", m_vmode); + break; + default: + LOG("EPC MDA: io_write at wrong offset:%02x\n", offset); + } +} + +READ8_MEMBER( isa8_epc_mda_device::io_read ) +{ + LOG("%s: %04x <- ???\n", FUNCNAME, offset); + int data = 0xff; + switch( offset ) + { + case 0x04: + LOGR(" - hd6845s address read\n"); + break; + case 0x05: + LOGR(" - hd6845s register read\n"); + data = m_hd6845s->register_r(); + break; + case 0x08: // Mode 1 reg + data = m_mode_control; + LOGMODE(" - Mode register 1 read: %02x\n", data); + break; + case 0x0a: // Status reg: b7-6=00 board ID; b3 vert retrace; b0 horiz retrace; b5,4,2,1 unused + data = (m_vsync != 0 ? 0x08 : 0x00) | (m_hsync != 0 ? 0x01 : 0x00); + LOGSTAT(" - Status register read: %02x\n", data); + break; + case 0x0f: // Mode 2 reg + data = m_mode_control2; + LOGMODE(" - Mode register 2 read: %02x\n", data); + break; + default: + LOG("EPC MDA: io_read at wrong offset:%02x\n", offset); + logerror("EPC MDA: io_read at wrong offset:%02x\n", offset); + } + LOG(" !!!: %04x <- %02x\n", offset, data); + return data; +} + +WRITE_LINE_MEMBER( isa8_epc_mda_device::hsync_changed ) +{ + m_hsync = state ? 1 : 0; +} + + +WRITE_LINE_MEMBER( isa8_epc_mda_device::vsync_changed ) +{ + m_vsync = state ? 0x80 : 0; + if ( state ) + { + m_framecnt++; + } +} + + +/* + * rW MDA mode control register (see #P138) + */ +WRITE8_MEMBER( isa8_epc_mda_device::mode_control_w ) +{ + m_mode_control = data; + + switch( m_mode_control & 0x2a ) + { + case 0x08: + m_update_row_type = MDA_TEXT_INTEN; + break; + case 0x28: + m_update_row_type = MDA_TEXT_BLINK; + break; + default: + m_update_row_type = -1; + } +} + + +/* R- CRT status register (see #P139) + * (EGA/VGA) input status 1 register + * 7 HGC vertical sync in progress + * 6-4 adapter 000 hercules + * 001 hercules+ + * 101 hercules InColor + * else unknown + * 3 pixel stream (0 black, 1 white) + * 2-1 reserved + * 0 horizontal drive enable + */ +READ8_MEMBER( isa8_epc_mda_device::status_r ) +{ + // Faking pixel stream here + m_pixel++; + + return 0xF0 | (m_pixel & 0x08) | m_hsync; +} + +inline int isa8_epc_mda_device::get_xres() +{ + return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_HOR640) ? 640 : 320 ) : 720; +} + +inline int isa8_epc_mda_device::get_yres() +{ + return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_VER400) ? 400 : 200 ) : 400; +} + +MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row) +{ + uint32_t *p = &bitmap.pix32(y); + uint16_t chr_base = ra; + int i; + + // Get som debug data from a couple of rows now and then + if ( y < (16 * 0 + 0x20) && (m_framecnt & 0xff) == 0 ) + { + LOGROW("%11.6f %s\n - y:%d chr_base:%d ra:%d ma:%d x_count:%d\n", machine().time().as_double(), FUNCNAME, + y, y % 16, ra, ma, x_count); + } + + // Video Off handling + if ((m_mode_control & MR1_VIDEO) == 0) + { + for (int i = 0; i < get_xres(); i++) + { + bitmap.pix32(y, i) = rgb_t::black(); + } + } + + // Graphic modes using only pixeldata, soft fonts are 8x8 or 8x16 but this is transparant to the code + else if ((m_vmode & VM_GRAPH) != 0) + { + logerror("EPC MDA: graphic modes not supported yet\n"); + } + + // Text modes using one of two 9x16 fonts in character rom + else + { + // Adjust row pointer if in monochrome text mode as we insert two scanlines per row of characters (see below) + if (m_vmode & VM_MONO) + { + p = &bitmap.pix32((y / 14) * 16 + y % 14); + } + + // Loop over each character in a row + for ( i = 0; i < x_count; i++ ) + { + uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; + uint8_t chr = m_videoram[ offset ]; + uint8_t attr = m_videoram[ offset + 1 ]; + uint8_t data = m_chargen[ ((m_mode_control2 & MR2_CHRSET) ? 0x1000 : 0) + chr_base + chr * 16]; + + // Default to light text on dark background + uint8_t fg = 2; + uint8_t bg = 0; + + if (y == 0 && i == 0) LOGCHRG(" - Offset: %04x Chr: '%c'[%02x] Attr: %02x Chr_base: %04x\n", offset, chr, chr, attr, chr_base); + + // Prepare some special monochrome emulation cases + if ( m_vmode & VM_MONO) + { + // Handle invisible characters + if ( (attr & (ATTR_FOREG | ATTR_BACKG)) == 0 ) + { + data = 0x00; + } + // Handle reversed characters + else if ( (attr & (ATTR_BACKG)) == ATTR_BACKG ) + { + fg = 0; + bg = 2; + } + } + else // prepare some special color emulation cases + { + // Handle invisible characters + if ( (attr & (ATTR_FOREG)) == ((attr & ATTR_BACKG) >> 4)) + { + data = 0x00; + } + // Handle reversed characters + else if ( (attr & ATTR_BACKG) == ATTR_BACKG || + (attr & ATTR_FOREG) == 0 ) + { + fg = 0; + bg = 2; + } + } + + // Handle intense foreground + if ((attr & ATTR_INTEN) != 0 && fg == 2) + { + fg = 3; + } + + // Handle intense background if blinking is disabled + if ((m_mode_control & MR1_BLINK) == 0 && + (attr & ATTR_BLINK) != 0 && bg == 2) + { + bg = 3; + } + + // Handle cursor and blinks + if ( i == (cursor_x)) + { + if ( m_framecnt & 0x08 ) + { + data = 0xFF; + } + } + else + { + if ( (m_mode_control & MR1_BLINK) && + ( attr & ATTR_BLINK ) && ( m_framecnt & 0x10 ) ) + { + data = 0x00; + } + } + + *p = (*m_pal)[( data & 0x80 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x40 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x20 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x10 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x08 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x04 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x02 ) ? fg : bg]; p++; + *p = (*m_pal)[( data & 0x01 ) ? fg : bg]; p++; + if (chr >= 0xc0 && chr <= 0xdf) + *p = (*m_pal)[( data & 0x01 ) ? fg : bg]; // 9th pixel col is a copy of col 8 + else + *p = (*m_pal)[bg]; // 9th pixel col is just background + p++; + + // Insert two extra scanlines in monochrome text mode to get 400 lines and support underline, needs verification on actual hardware. + // The technical manual says that the character box is 9x16 pixels in 80x25 character mode which equals 720x400 resolution but the + // CRTC calls back for only 350 lines. Assumption is that there is hardware adding these lines and that handles underlining. In color + // emulation text mode all 400 lines are called for in 80x25 and this mode does not support underlining according to the technical manual + if ( ra == 13 && (m_vmode & VM_MONO) ) + { + uint16_t row = ra + (y / 14) * 16; // Calculate correct row number including the extra 2 lines per each row of characters + for ( int j = 0; j < 9; j++) + { + if (chr >= 0xb3 && chr <= 0xdf) // Handle the meta graphics characters + { + bitmap.pix32(row + 1, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; + bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; + } + else + { + // Handle underline + bitmap.pix32(row + 1, j + i * 9) =(*m_pal)[( attr & ATTR_FOREG ) == ATTR_ULINE ? fg : bg]; + bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[bg]; + } + } + } + } + } +} + +//-------------------------------------------------------------------- +// Port definitions +//-------------------------------------------------------------------- +static INPUT_PORTS_START( epc_mda ) + PORT_START( "S1" ) + PORT_DIPNAME( 0x01, 0x00, "Color emulation") PORT_DIPLOCATION("S1:1") + PORT_DIPSETTING( 0x00, "Disabled" ) + PORT_DIPSETTING( 0x01, "Enabled" ) + PORT_DIPUNUSED_DIPLOC(0x02, 0x02, "S1:2") + + PORT_START( "MONITOR" ) + PORT_CONFNAME( 0x01, 0x00, "Ericsson Monochrome HR Monitors") PORT_CHANGED_MEMBER( DEVICE_SELF, isa8_epc_mda_device, monitor_changed, 0 ) + PORT_CONFSETTING( 0x00, "Amber 3111") + PORT_CONFSETTING( 0x01, "B&W 3712/3715") +INPUT_PORTS_END + +INPUT_CHANGED_MEMBER( isa8_epc_mda_device::monitor_changed ) +{ + if ((m_io_monitor->read() & 1) == 1) + { + m_pal = &m_371x_pal; + } + else + { + m_pal = &m_3111_pal; + } +} + +ioport_constructor isa8_epc_mda_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( epc_mda ); +} diff --git a/src/devices/bus/isa/eis_hgb107x.h b/src/devices/bus/isa/eis_hgb107x.h new file mode 100644 index 00000000000..711f385278f --- /dev/null +++ b/src/devices/bus/isa/eis_hgb107x.h @@ -0,0 +1,112 @@ +// license:BSD-3-Clause +// copyright-holders: Joakim Larsson Edström +#ifndef MAME_BUS_ISA_EIS_HGB107X_H +#define MAME_BUS_ISA_EIS_HGB107X_H + +#pragma once + +#include "isa.h" +#include "video/mc6845.h" +#include "emupal.h" +#include "screen.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class isa8_epc_mda_device : public device_t, public device_isa8_card_interface +{ +public: + // construction/destruction + isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_READ8_MEMBER(io_read); + DECLARE_WRITE8_MEMBER(io_write); + DECLARE_READ8_MEMBER(status_r); + DECLARE_WRITE8_MEMBER(mode_control_w); + DECLARE_WRITE_LINE_MEMBER(hsync_changed); + DECLARE_WRITE_LINE_MEMBER(vsync_changed); + + /* Monitor */ + DECLARE_INPUT_CHANGED_MEMBER(monitor_changed); + +protected: + isa8_epc_mda_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual const tiny_rom_entry *device_rom_region() const override; + virtual ioport_constructor device_input_ports() const override; + +private: + inline int get_xres(); + inline int get_yres(); + + enum { + VM_COLS80 = 0x01, + VM_GRAPH = 0x02, + VM_HOR640 = 0x04, + VM_MONO = 0x08, + VM_VER400 = 0x10 + }; + + enum { + MR1_COLS80 = 0x01, + MR1_GRAPH = 0x02, + MR1_VIDEO = 0x08, + MR1_HOR640 = 0x10, + MR1_BLINK = 0x20 + }; + + enum { + MR2_COLEMU = 0x04, + MR2_CHRSET = 0x40, + MR2_VER400 = 0x80 + }; + + enum { + ATTR_BLINK = 0x80, + ATTR_BACKG = 0x70, + ATTR_INTEN = 0x08, + ATTR_FOREG = 0x07, + ATTR_ULINE = 0x01, + }; + + required_device m_crtc; + MC6845_UPDATE_ROW( crtc_update_row ); + + std::unique_ptr m_soft_chr_gen; + required_ioport m_s1; + uint8_t m_color_mode; + uint8_t m_mode_control2; + required_device m_screen; + required_ioport m_io_monitor; + required_region_ptr m_chargen; + + uint8_t m_vmode; + rgb_t (*m_pal)[4]; + rgb_t m_3111_pal[4]; + rgb_t m_371x_pal[4]; + bool m_installed; + hd6845s_device *m_hd6845s; +public: + int m_framecnt; + + uint8_t m_mode_control; + + int m_update_row_type; + uint8_t *m_chr_gen; + uint8_t m_vsync; + uint8_t m_hsync; + std::vector m_videoram; + uint8_t m_pixel; +}; + +// device type definition +DECLARE_DEVICE_TYPE(ISA8_EPC_MDA, isa8_epc_mda_device) + +#endif // MAME_BUS_ISA_EIS_HGB107X_H diff --git a/src/devices/bus/isa/isa_cards.cpp b/src/devices/bus/isa/isa_cards.cpp index 8724327c94d..17b42e105d9 100644 --- a/src/devices/bus/isa/isa_cards.cpp +++ b/src/devices/bus/isa/isa_cards.cpp @@ -22,6 +22,7 @@ #include "svga_tseng.h" #include "svga_trident.h" #include "num9rev.h" +#include "eis_hgb107x.h" // storage #include "fdc.h" diff --git a/src/devices/bus/isa/mda.cpp b/src/devices/bus/isa/mda.cpp index 8d487e3303b..4e0122d83fd 100644 --- a/src/devices/bus/isa/mda.cpp +++ b/src/devices/bus/isa/mda.cpp @@ -975,522 +975,3 @@ MC6845_UPDATE_ROW( isa8_ec1840_0002_device::crtc_update_row ) break; } } - -/***************************************************************************** - - Ericsson PC Monochrome HR Graphics Board 1070 - -******************************************************************************/ - -/* PCB layouts and assembly years from online pictures and physical unit. - Ericsson - marked SPVT02 8301 60 53-10, assembled in 1985 indicated by chip dates - +--------------------------------------------------------------------------------------+ ___ - | IC1 IC2 IC3 IC4 IC5 +-IC15--EPROM-+ IC6 IC7 IC8 S1 || - | |8363 65 14-80| || - | IC9 IC10 IC11 IC12 IC13 IC14|CG 50821 A64 |+------------------++-IC24 EPROM--+ || - | +-------------+| CRTC HD46505SP-1 ||10-40VP | || - | IC16 IC17 IC18 IC19 IC20 IC21 IC22 | IC23 HD68A45SP ||402 28 A19 | J4|| not - | +------------------++-------------+ || mounted - | IC25 IC26 IC27 IC28 IC29 IC30 IC31 IC32 IC33 IC34 || - | O-|__ - | IC35 IC36 IC37 IC38 IC39 IC40 IC41 IC42 IC43 IC44 || | - | ||DB15 - | IC45 IC46 IC47 IC48 IC49 IC50 IC51 IC52 IC53 IC54 || | - | ||__| - | IC55 IC56 IC57 IC58 IC59 IC60 IC61 IC62 IC63 IC64 O-| - | J1A || - | IC65 IC66 IC67 IC68 IC69 IC70 IC71 IC72 +--------------------------------------------+| - +-----------------------------------------+ ||||||||| ||||||||||||||||||||||||| | - I85565 A85571 (labels) | - | - - IC's (from photos) - ------------------------------------------------------------------------------ - IC1 74F109 IC26 74F86 IC51 TMS4416-15NL 4 x 16Kbits DRAM - IC2 74LS393 IC27 74LS08 IC52 74ALS574 - IC3 74F64 IC28 74F153 IC53 74LS138 - IC4 74ALS299 IC29 74LS174 IC54 74F86 - IC5 74LS375 IC30 74LS374 IC55 74F109 - IC6 74LS151 IC31 74LS374 IC56 74F32 - IC7 74LS153 IC32 74ALS574 IC57 74F109 - IC8 74LS389? IC33 74LS08 IC58 74F00? - IC9 74F02 IC34 74LS245 IC59 74LS244 - IC10 74ALS109 IC35 74F10? IC60 TMS4416-15NL 4 x 16Kbits DRAM - IC11 Crystal 17.040MHz IC36 74LS02 IC61 TMS4416-15NL 4 x 16Kbits DRAM - IC12 74F64 IC37 74LS00 IC62 74ALS574 - IC13 74ALS299 IC38 74F374 IC63 74LS138 - IC14 PAL? 10-70ART40101 IC39 74LS125 IC64 74LS245 - IC15 EPROM 8363 65 14-80 CG 50821 A64 IC40 74LS244 IC65 74LS00 - IC16 Crystal 19.170MHz IC41 74LS244 IC66 74LS02 - IC17 74LS10 IC42 74LS574 IC67 74LS51 - IC18 74F08 IC43 74LS32 IC68 74LS04 - IC19 74ALS574 IC44 MC10124 - TTL to MECL converter IC69 74LS153 - IC20 74LS299 IC45 74LS109 IC70 74LS109 - IC21 74LS273 IC46 74LS00 IC71 74LS138 - IC22 74ALS574 IC47 74F194 IC72 74LS139 - IC23 CRTC HD46505SP,HD68A45SP IC48 74F04 - IC24 EPROM 2764, 10-40 VP 402 28 A19 IC49 74LS174 - IC25 74ALS109 IC50 TMS4416-15NL 4 x 16Kbits DRAM - - General description - ------------------- - The PCB has a 2 bit DIP switch S1 and a DB15 non standard video connector. There is also an unsoldered J4 connector - above the DB15 but no hole prepared for a connector in the plate. Above the J4 connector there is a two pin PCB connector - that probably receives the power for the monitor for the DB15 from the PSU. - - Just below IC65 and IC66 there are two labels saying "I 85565" and "A E85571" respectively - - Video cable, card DB15 <---> monitor DB25 - --------------------------------------------------- - Ericsson 2 +VS 4 Ericsson - Monochrome 3 VS return 2 Monochrome HR - HR Graphics 10 +VS 17 Monitors 3111 (Amber) or - Board 1070 11 VS return 15 3712/3715 (Black & White) - 4 VSYNC 6 - 12 VSYNC 19 - 5 HSYNC 7 - 13 HSYNC 20 - 6 High intensity 8 - 14 High intensity 21 - 7 Video 9 - 15 Video 22 - 8 GND 11 - - This board is normaly used with an Ericsson monitor due to the non standard connector. - Trivia: https://www.pinterest.se/pin/203084264425177097/ - */ - -#define EPC_MDA_SCREEN "epc_mda_screen" // TODO: use a device finder reference instead - -ROM_START( epc ) - ROM_REGION(0x2000,"chargen", 0) - ROM_LOAD("8363_65_14_80_cg_50821_a64.bin", 0x00000, 0x2000, CRC(be709786) SHA1(38ab26224bbe66bbe2bb2ccac29b41cbf78bdbf8)) - //ROM_LOAD("10_40_vp_402_28_ic_24_a19.bin", 0x00000, 0x2000, CRC(2aa53b92) SHA1(87051a037249eb631d7d2191bc0e925125c60f39)) -ROM_END - -//************************************************************************** -// GLOBAL VARIABLES -//************************************************************************** -DEFINE_DEVICE_TYPE(ISA8_EPC_MDA, isa8_epc_mda_device, "isa_epc_mda", "Ericsson PC Monochrome HR Graphics Board 1070") - - -//------------------------------------------------- -// device_add_mconfig - add device configuration -//------------------------------------------------- -/* There are two crystals on the board: 19.170Mhz and 17.040MHz TODO: verify use */ -/* Text modes uses 720x400 base resolution and the Graphics modes 320/640x200/400 */ -/* This matches the difference between the crystals so we assume this for now */ -void isa8_epc_mda_device::device_add_mconfig(machine_config &config) -{ - screen_device &screen(SCREEN(config, EPC_MDA_SCREEN, SCREEN_TYPE_RASTER)); - screen.set_raw(XTAL(19'170'000) / 4, 720, 0, 720, 400, 0, 400); - //screen.set_screen_update(MC6845_NAME, FUNC(h46505_device::screen_update)); - screen.set_screen_update(MC6845_NAME, FUNC(mc6845_device::screen_update)); - - PALETTE(config, m_palette).set_entries(4); - - HD6845S(config, m_crtc, XTAL(19'170'000) / 16); // clock and divider are guesswork - m_crtc->set_screen(EPC_MDA_SCREEN); - m_crtc->set_show_border_area(false); - m_crtc->set_char_width(8); - - m_crtc->set_update_row_callback(FUNC(isa8_epc_mda_device::crtc_update_row)); - m_crtc->out_hsync_callback().set(FUNC(isa8_epc_mda_device::hsync_changed)); - m_crtc->out_vsync_callback().set(FUNC(isa8_epc_mda_device::vsync_changed)); - - //MCFG_GFXDECODE_ADD("gfxdecode", "palette", pcepc) -} - -//------------------------------------------------- -// rom_region - device-specific ROM region -//------------------------------------------------- - -const tiny_rom_entry *isa8_epc_mda_device::device_rom_region() const -{ - return ROM_NAME( epc ); -} - -//************************************************************************** -// LIVE DEVICE -//************************************************************************** - -//------------------------------------------------- -// isa8_epc_mda_device - constructor -//------------------------------------------------- - -isa8_epc_mda_device::isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - isa8_mda_device(mconfig, ISA8_EPC_MDA, tag, owner, clock), - m_soft_chr_gen(nullptr), - m_s1(*this, "S1"), - m_color_mode(0), - m_mode_control2(0), - m_screen(*this, EPC_MDA_SCREEN), - m_io_monitor(*this, "MONITOR"), - m_chargen(*this, "chargen"), - m_installed(false) -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void isa8_epc_mda_device::device_start() -{ - if (m_palette != nullptr && !m_palette->started()) - throw device_missing_dependencies(); - - /* Palette for use with the Ericsson Amber Monochrome HR CRT monitor 3111, P3 phospor 602nm 255,183, 0 */ - m_3111_pal[0] = rgb_t( 0, 0, 0); // black - m_3111_pal[1] = rgb_t( 143, 103, 0); // dim - m_3111_pal[2] = rgb_t( 191, 137, 0); // normal - m_3111_pal[3] = rgb_t( 255, 183, 0); // bright - - /* Palette for use with the Ericsson B&W Monochrome HR CRT monitor 3712/3715 */ - m_371x_pal[0] = rgb_t( 0, 0, 0); // black - m_371x_pal[1] = rgb_t( 143, 143, 143); // dim - m_371x_pal[2] = rgb_t( 191, 191, 191); // normal - m_371x_pal[3] = rgb_t( 255, 255, 255); // bright - - /* Init a default palette */ - m_pal = &m_3111_pal; // In case screen starts rendering before device_reset where we read the settings - - m_videoram.resize(0x8000); - set_isa_device(); - m_installed = false; - m_hd6845s = subdevice(MC6845_NAME); -} - -void isa8_epc_mda_device::device_reset() -{ - m_framecnt = 0; - m_mode_control = 0; - m_vsync = 0; - m_hsync = 0; - - m_color_mode = m_s1->read(); - LOGSETUP("%s: m_color_mode:%02x\n", FUNCNAME, m_color_mode); - m_pal = (m_io_monitor-> read() & 1) == 1 ? &m_371x_pal : &m_3111_pal; - m_vmode = 0; - - if (m_installed == false) - { - m_isa->install_device(0x3b0, 0x3bb, read8_delegate(*this, FUNC(isa8_epc_mda_device::io_read)), write8_delegate(*this, FUNC(isa8_epc_mda_device::io_write))); - // The Ericsson PC MDA card 1070 doesn't respond to the LPT device addresses 3bc-3be because - // the LPT device is on the main PCB, but requires 3bf for mode register 2 so need to create a hole here - needs verification on hw as docs are wrong - m_isa->install_device(0x3bf, 0x3bf, read8_delegate(*this, FUNC(isa8_epc_mda_device::io_read2)), write8_delegate(*this, FUNC(isa8_epc_mda_device::io_write2))); - m_isa->install_bank(0xb0000, 0xb7fff, "bank_epc", &m_videoram[0]); // Monochrome emulation mode VRAM address - - // This check allows a color monitor adapter to be installed at this address range if color emulation is disabled - if (m_color_mode & 1) - { - m_isa->install_device(0x3d0, 0x3df, read8_delegate(*this, FUNC(isa8_epc_mda_device::io_read)), write8_delegate(*this, FUNC(isa8_epc_mda_device::io_write))); - m_isa->install_bank(0xb8000, 0xbffff, "bank_epc", &m_videoram[0]); // Color emulation mode VRAM address, but same 32KB areas as there are only this amount on the board - } - m_installed = true; - } -} - -/* - * Register Address table from the manual - * Ericsson name MDA mode CGA mode Standard name - *------------------------------------------------------------------------------- - * 6845 Address Registers 0x3b4 0x3d4 wo CRT Index reg - * 6845 Data Registers 0x3b5 0x3d5 wo CRT Data reg - * Mode Register 1 0x3b8 0x3d8 rw MDA/CGA mode reg (bit 0,1 & 4 incompatible) - * Mode Register 2 0x3bf 0x3df rw CRT/CPU page reg (incompatible w PCjr only) - * Status Register 0x3ba 0x3da r CGA/MDA status reg (incompatible) - * w EGA/VGA feature ccontrol reg (not used by this board) - * - * NOTE: The LPT device resides on the Ericsson PC main board in the 3bc-3be address range - */ - -WRITE8_MEMBER(isa8_epc_mda_device::io_write2 ) -{ - io_write(space, offset + 0x0f, data); -} - -WRITE8_MEMBER(isa8_epc_mda_device::io_write ) -{ - LOG("%s: %04x <- %02x\n", FUNCNAME, offset, data); - switch( offset ) - { - case 0x04: - //LOGSETUP(" - HD6845S address write\n"); - m_hd6845s->address_w( data ); - break; - case 0x05: - //LOGSETUP(" - HD6845S register write\n"); - m_hd6845s->register_w( data ); - break; - case 0x08: // Mode 1 reg - LOGMODE(" - Mode register 1 write: %02x\n", data); - LOGMODE(" MSB attribute: %s\n", (data & 0x20) == 0 ? "intensity" : "blink"); - LOGMODE(" Horizontal px: %s\n", (data & 0x10) == 0 ? "320/LR" : "640/HR"); - LOGMODE(" Video : %s\n", (data & 0x08) == 0 ? "Disabled" : "Enabled"); - LOGMODE(" Mode : %s\n", (data & 0x02) == 0 ? "Text" : "Graphics"); - LOGMODE(" Text columns : %d\n", (data & 0x01) == 0 ? 40 : 80); - m_mode_control = data; - m_vmode &= ~(VM_GRAPH | VM_COLS80 | VM_HOR640); - m_vmode |= ((m_mode_control & 0x01) ? VM_COLS80 : 0); - m_vmode |= ((m_mode_control & 0x02) ? VM_GRAPH : 0); - m_vmode |= ((m_mode_control & 0x10) ? VM_HOR640 : 0); - m_update_row_type = ((data & 0x20) == 0 ? MDA_LOWRES_TEXT_INTEN : MDA_LOWRES_TEXT_BLINK); - { - rectangle rect(0, get_xres() - 1, 0, get_yres() -1); - m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50)); - } - LOGMODE("Video Mode:%02x\n\n", m_vmode); - break; - case 0x0f: // Mode 2 reg - LOGMODE(" - Mode register 2 write: %02x\n", data); - LOGMODE(" Vertical px : %s\n", (data & MR2_VER400) == 0 ? "200" : "400"); - LOGMODE(" Character set: %s\n", (data & MR2_CHRSET) == 0 ? "0" : "1"); - LOGMODE(" Emulated : %s\n", (data & MR2_COLEMU) == 0 ? "Color" : "Monochrome"); - m_mode_control2 = data; - m_vmode &= ~(VM_MONO | VM_VER400); - m_vmode |= ((m_mode_control2 & 0x04) ? VM_MONO : 0); - m_vmode |= ((m_mode_control2 & 0x80) ? VM_VER400 : 0); - { - rectangle rect(0, get_xres() - 1, 0, get_yres() -1); - m_screen->configure(get_xres(), get_yres(), rect, HZ_TO_ATTOSECONDS(50)); - } - LOGMODE("Video Mode:%02x\n\n", m_vmode); - break; - default: - LOG("EPC MDA: io_write at wrong offset:%02x\n", offset); - } -} - -READ8_MEMBER( isa8_epc_mda_device::io_read2 ) -{ - return io_read(space, offset + 0x0f); -} - -READ8_MEMBER( isa8_epc_mda_device::io_read ) -{ - LOG("%s: %04x <- ???\n", FUNCNAME, offset); - int data = 0xff; - switch( offset ) - { - case 0x04: - LOGR(" - hd6845s address read\n"); - break; - case 0x05: - LOGR(" - hd6845s register read\n"); - data = m_hd6845s->register_r(); - break; - case 0x08: // Mode 1 reg - data = m_mode_control; - LOGMODE(" - Mode register 1 read: %02x\n", data); - break; - case 0x0a: // Status reg: b7-6=00 board ID; b3 vert retrace; b0 horiz retrace; b5,4,2,1 unused - data = (m_vsync != 0 ? 0x08 : 0x00) | (m_hsync != 0 ? 0x01 : 0x00); - LOGSTAT(" - Status register read: %02x\n", data); - break; - case 0x0f: // Mode 2 reg - data = m_mode_control2; - LOGMODE(" - Mode register 2 read: %02x\n", data); - break; - default: - LOG("EPC MDA: io_read at wrong offset:%02x\n", offset); - logerror("EPC MDA: io_read at wrong offset:%02x\n", offset); - } - LOG(" !!!: %04x <- %02x\n", offset, data); - return data; -} - -inline int isa8_epc_mda_device::get_xres() -{ - return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_HOR640) ? 640 : 320 ) : 720; -} - -inline int isa8_epc_mda_device::get_yres() -{ - return (m_vmode & VM_GRAPH) ? ( (m_vmode & VM_VER400) ? 400 : 200 ) : 400; -} - -MC6845_UPDATE_ROW(isa8_epc_mda_device::crtc_update_row) -{ - uint32_t *p = &bitmap.pix32(y); - uint16_t chr_base = ra; - int i; - - // Get som debug data from a couple of rows now and then - if ( y < (16 * 0 + 0x20) && (m_framecnt & 0xff) == 0 ) - { - LOGROW("%11.6f %s\n - y:%d chr_base:%d ra:%d ma:%d x_count:%d\n", machine().time().as_double(), FUNCNAME, - y, y % 16, ra, ma, x_count); - } - - // Video Off handling - if ((m_mode_control & MR1_VIDEO) == 0) - { - for (int i = 0; i < get_xres(); i++) - { - bitmap.pix32(y, i) = rgb_t::black(); - } - } - - // Graphic modes using only pixeldata, soft fonts are 8x8 or 8x16 but this is transparant to the code - else if ((m_vmode & VM_GRAPH) != 0) - { - logerror("EPC MDA: graphic modes not supported yet\n"); - } - - // Text modes using one of two 9x16 fonts in character rom - else - { - // Adjust row pointer if in monochrome text mode as we insert two scanlines per row of characters (see below) - if (m_vmode & VM_MONO) - { - p = &bitmap.pix32((y / 14) * 16 + y % 14); - } - - // Loop over each character in a row - for ( i = 0; i < x_count; i++ ) - { - uint16_t offset = ( ( ma + i ) << 1 ) & 0x0FFF; - uint8_t chr = m_videoram[ offset ]; - uint8_t attr = m_videoram[ offset + 1 ]; - uint8_t data = m_chargen[ ((m_mode_control2 & MR2_CHRSET) ? 0x1000 : 0) + chr_base + chr * 16]; - - // Default to light text on dark background - uint8_t fg = 2; - uint8_t bg = 0; - - if (y == 0 && i == 0) LOGCHRG(" - Offset: %04x Chr: '%c'[%02x] Attr: %02x Chr_base: %04x\n", offset, chr, chr, attr, chr_base); - - // Prepare some special monochrome emulation cases - if ( m_vmode & VM_MONO) - { - // Handle invisible characters - if ( (attr & (ATTR_FOREG | ATTR_BACKG)) == 0 ) - { - data = 0x00; - } - // Handle reversed characters - else if ( (attr & (ATTR_BACKG)) == ATTR_BACKG ) - { - fg = 0; - bg = 2; - } - } - else // prepare some special color emulation cases - { - // Handle invisible characters - if ( (attr & (ATTR_FOREG)) == ((attr & ATTR_BACKG) >> 4)) - { - data = 0x00; - } - // Handle reversed characters - else if ( (attr & ATTR_BACKG) == ATTR_BACKG || - (attr & ATTR_FOREG) == 0 ) - { - fg = 0; - bg = 2; - } - } - - // Handle intense foreground - if ((attr & ATTR_INTEN) != 0 && fg == 2) - { - fg = 3; - } - - // Handle intense background if blinking is disabled - if ((m_mode_control & MR1_BLINK) == 0 && - (attr & ATTR_BLINK) != 0 && bg == 2) - { - bg = 3; - } - - // Handle cursor and blinks - if ( i == (cursor_x)) - { - if ( m_framecnt & 0x08 ) - { - data = 0xFF; - } - } - else - { - if ( (m_mode_control & MR1_BLINK) && - ( attr & ATTR_BLINK ) && ( m_framecnt & 0x10 ) ) - { - data = 0x00; - } - } - - *p = (*m_pal)[( data & 0x80 ) ? fg : bg]; p++; - *p = (*m_pal)[( data & 0x40 ) ? fg : bg]; p++; - *p = (*m_pal)[( data & 0x20 ) ? fg : bg]; p++; - *p = (*m_pal)[( data & 0x10 ) ? fg : bg]; p++; - *p = (*m_pal)[( data & 0x08 ) ? fg : bg]; p++; - *p = (*m_pal)[( data & 0x04 ) ? fg : bg]; p++; - *p = (*m_pal)[( data & 0x02 ) ? fg : bg]; p++; - *p = (*m_pal)[( data & 0x01 ) ? fg : bg]; p++; - if (chr >= 0xc0 && chr <= 0xdf) - *p = (*m_pal)[( data & 0x01 ) ? fg : bg]; // 9th pixel col is a copy of col 8 - else - *p = (*m_pal)[bg]; // 9th pixel col is just background - p++; - - // Insert two extra scanlines in monochrome text mode to get 400 lines and support underline, needs verification on actual hardware. - // The technical manual says that the character box is 9x16 pixels in 80x25 character mode which equals 720x400 resolution but the - // CRTC calls back for only 350 lines. Assumption is that there is hardware adding these lines and that handles underlining. In color - // emulation text mode all 400 lines are called for in 80x25 and this mode does not support underlining according to the technical manual - if ( ra == 13 && (m_vmode & VM_MONO) ) - { - uint16_t row = ra + (y / 14) * 16; // Calculate correct row number including the extra 2 lines per each row of characters - for ( int j = 0; j < 9; j++) - { - if (chr >= 0xb3 && chr <= 0xdf) // Handle the meta graphics characters - { - bitmap.pix32(row + 1, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; - bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[( data & (0x80 >> j) ) || (j == 8 && (data & 0x01)) ? fg : bg]; - } - else - { - // Handle underline - bitmap.pix32(row + 1, j + i * 9) =(*m_pal)[( attr & ATTR_FOREG ) == ATTR_ULINE ? fg : bg]; - bitmap.pix32(row + 2, j + i * 9) = (*m_pal)[bg]; - } - } - } - } - } -} - -//-------------------------------------------------------------------- -// Port definitions -//-------------------------------------------------------------------- -static INPUT_PORTS_START( epc_mda ) - PORT_START( "S1" ) - PORT_DIPNAME( 0x01, 0x00, "Color emulation") PORT_DIPLOCATION("S1:1") - PORT_DIPSETTING( 0x00, "Disabled" ) - PORT_DIPSETTING( 0x01, "Enabled" ) - PORT_DIPUNUSED_DIPLOC(0x02, 0x02, "S1:2") - - PORT_START( "MONITOR" ) - PORT_CONFNAME( 0x01, 0x00, "Ericsson Monochrome HR Monitors") PORT_CHANGED_MEMBER( DEVICE_SELF, isa8_epc_mda_device, monitor_changed, 0 ) - PORT_CONFSETTING( 0x00, "Amber 3111") - PORT_CONFSETTING( 0x01, "B&W 3712/3715") -INPUT_PORTS_END - -INPUT_CHANGED_MEMBER( isa8_epc_mda_device::monitor_changed ) -{ - if ((m_io_monitor->read() & 1) == 1) - { - m_pal = &m_371x_pal; - } - else - { - m_pal = &m_3111_pal; - } -} - -ioport_constructor isa8_epc_mda_device::device_input_ports() const -{ - return INPUT_PORTS_NAME( epc_mda ); -} diff --git a/src/devices/bus/isa/mda.h b/src/devices/bus/isa/mda.h index 4d361ff7969..66d60e0493a 100644 --- a/src/devices/bus/isa/mda.h +++ b/src/devices/bus/isa/mda.h @@ -138,88 +138,4 @@ private: // device type definition DECLARE_DEVICE_TYPE(ISA8_EC1840_0002, isa8_ec1840_0002_device) -// ======================> isa8_epc_mda_device - -class isa8_epc_mda_device : - public isa8_mda_device -{ -public: - // construction/destruction - isa8_epc_mda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - virtual DECLARE_READ8_MEMBER(io_read) override; - virtual DECLARE_WRITE8_MEMBER(io_write) override; - DECLARE_READ8_MEMBER(io_read2); - DECLARE_WRITE8_MEMBER(io_write2); - - /* Monitor */ - DECLARE_INPUT_CHANGED_MEMBER(monitor_changed); - -protected: - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; - - // optional information overrides - virtual void device_add_mconfig(machine_config &config) override; - virtual const tiny_rom_entry *device_rom_region() const override; - virtual ioport_constructor device_input_ports() const override; - -private: - inline int get_xres(); - inline int get_yres(); - //virtual DECLARE_WRITE8_MEMBER(mode_control_w) override; - - enum { - VM_COLS80 = 0x01, - VM_GRAPH = 0x02, - VM_HOR640 = 0x04, - VM_MONO = 0x08, - VM_VER400 = 0x10 - }; - - enum { - MR1_COLS80 = 0x01, - MR1_GRAPH = 0x02, - MR1_VIDEO = 0x08, - MR1_HOR640 = 0x10, - MR1_BLINK = 0x20 - }; - - enum { - MR2_COLEMU = 0x04, - MR2_CHRSET = 0x40, - MR2_VER400 = 0x80 - }; - - enum { - ATTR_BLINK = 0x80, - ATTR_BACKG = 0x70, - ATTR_INTEN = 0x08, - ATTR_FOREG = 0x07, - ATTR_ULINE = 0x01, - }; - virtual MC6845_UPDATE_ROW( crtc_update_row ) override; - //MC6845_UPDATE_ROW( mda_lowres_text_inten_update_row ); - //MC6845_UPDATE_ROW( mda_lowres_text_blink_update_row ); - - std::unique_ptr m_soft_chr_gen; - required_ioport m_s1; - uint8_t m_color_mode; - uint8_t m_mode_control2; - required_device m_screen; - required_ioport m_io_monitor; - required_region_ptr m_chargen; - - uint8_t m_vmode; - rgb_t (*m_pal)[4]; - rgb_t m_3111_pal[4]; - rgb_t m_371x_pal[4]; - bool m_installed; - hd6845s_device *m_hd6845s; -}; - -// device type definition -DECLARE_DEVICE_TYPE(ISA8_EPC_MDA, isa8_epc_mda_device) - #endif // MAME_BUS_ISA_MDA_H diff --git a/src/mame/drivers/eispc.cpp b/src/mame/drivers/eispc.cpp index 603b62e7d6e..a0eafdbcfcd 100644 --- a/src/mame/drivers/eispc.cpp +++ b/src/mame/drivers/eispc.cpp @@ -61,7 +61,7 @@ //#include "bus/isa/isa.h" //#include "bus/isa/isa_cards.h" #include "bus/isa/ega.h" -#include "bus/isa/mda.h" +#include "bus/isa/eis_hgb107x.h" #include "bus/isa/eis_twib.h" #include "machine/pc_lpt.h"