// license:BSD-3-Clause // copyright-holders:Curt Coder /***************************************************************************** * * video/abc802.c * ****************************************************************************/ #include "includes/abc80x.h" //------------------------------------------------- // MC6845_UPDATE_ROW( abc802_update_row ) //------------------------------------------------- MC6845_UPDATE_ROW( abc802_state::abc802_update_row ) { /* PAL16R4 equation: IF (VCC) *OS = FC + RF / RC *RG: = HS / *RG + *ATE / *RG + ATD / *RG + LL / *RG + AT1 / *RG + AT0 / ATE + *ATD + *LL + *AT1 + *AT0 *RI: = *RI + *INV / *RI + LL / *INV + *LL *RF: = HS / *RF + *ATE / *RF + ATD / *RF + LL / *RF + AT1 / *RF + AT0 / ATE + *ATD + *LL + *AT1 + AT0 *RC: = HS / *RC + *ATE / *RC + *ATD / *RC + LL / *RC + *ATI / *RC + AT0 / ATE + *LL + *AT1 + *AT0 IF (VCC) *O0 = *CUR + *AT0 / *CUR + ATE *O1 = *CUR + *AT1 / *CUR + ATE + = AND / = OR * = Inverted ATD Attribute data ATE Attribute enable AT0,AT1 Attribute address CUR Cursor FC FLSH clock HS Horizontal sync INV Inverted signal input LL Load when Low OEL Output Enable when Low RC Row clear RF Row flash RG Row graphic RI Row inverted */ const pen_t *pen = m_palette->pens(); int rf = 0, rc = 0, rg = 0; y += vbp; for (int column = 0; column < x_count; column++) { UINT8 code = m_char_ram[(ma + column) & 0x7ff]; UINT16 address = code << 4; UINT8 ra_latch = ra; UINT8 data; int ri = (code & ABC802_INV) ? 1 : 0; if (column == cursor_x) { ra_latch = 0x0f; } if ((m_flshclk && rf) || rc) { ra_latch = 0x0e; } if (rg) { address |= 0x800; } data = m_char_rom->base()[(address + ra_latch) & 0xfff]; if (data & ABC802_ATE) { int attr = data & 0x03; int value = (data & ABC802_ATD) ? 1 : 0; switch (attr) { case 0x00: // Row Graphic rg = value; break; case 0x01: // Row Flash rf = value; break; case 0x02: // Row Clear rc = value; break; case 0x03: // undefined break; } } else { data <<= 2; if (m_80_40_mux) { for (int bit = 0; bit < ABC800_CHAR_WIDTH; bit++) { int x = hbp + ((column + 3) * ABC800_CHAR_WIDTH) + bit; int color = (BIT(data, 7) ^ ri) && de; bitmap.pix32(y, x) = pen[color]; data <<= 1; } } else { for (int bit = 0; bit < ABC800_CHAR_WIDTH; bit++) { int x = hbp + ((column + 3) * ABC800_CHAR_WIDTH) + (bit << 1); int color = (BIT(data, 7) ^ ri) && de; bitmap.pix32(y, x) = pen[color]; bitmap.pix32(y, x + 1) = pen[color]; data <<= 1; } column++; } } } } //------------------------------------------------- // vs_w - vertical sync write //------------------------------------------------- WRITE_LINE_MEMBER( abc802_state::vs_w ) { if (!state) { // flash clock if (m_flshclk_ctr & 0x20) { m_flshclk = !m_flshclk; m_flshclk_ctr = 0; } else { m_flshclk_ctr++; } } // signal _DEW to DART m_dart->rib_w(!state); } void abc802_state::video_start() { // register for state saving save_item(NAME(m_flshclk_ctr)); save_item(NAME(m_flshclk)); save_item(NAME(m_80_40_mux)); } //------------------------------------------------- // SCREEN_UPDATE( abc802 ) //------------------------------------------------- UINT32 abc802_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { // draw text m_crtc->screen_update(screen, bitmap, cliprect); return 0; } //------------------------------------------------- // MACHINE_CONFIG_FRAGMENT( abc802_video ) //------------------------------------------------- MACHINE_CONFIG_FRAGMENT( abc802_video ) MCFG_MC6845_ADD(MC6845_TAG, MC6845, SCREEN_TAG, ABC800_CCLK) MCFG_MC6845_SHOW_BORDER_AREA(true) MCFG_MC6845_CHAR_WIDTH(ABC800_CHAR_WIDTH) MCFG_MC6845_UPDATE_ROW_CB(abc802_state, abc802_update_row) MCFG_MC6845_OUT_VSYNC_CB(WRITELINE(abc802_state, vs_w)) MCFG_SCREEN_ADD(SCREEN_TAG, RASTER) MCFG_SCREEN_UPDATE_DRIVER(abc802_state, screen_update) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) MCFG_SCREEN_SIZE(768, 312) MCFG_SCREEN_VISIBLE_AREA(0,768-1, 0, 312-1) MCFG_PALETTE_ADD_MONOCHROME_AMBER("palette") MACHINE_CONFIG_END