summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Sergey Svishchev <shattered@users.noreply.github.com>2017-09-08 04:54:40 +0300
committer Vas Crabb <cuavas@users.noreply.github.com>2017-09-08 11:54:40 +1000
commit0e6fa0a8acdf1288b4ded7e671bfcde196688926 (patch)
treef8d8dce01192867335afb8d3c84146d4ab7821c3
parent8e83d54af54053669b9938b0149c6ad97525d8c6 (diff)
cgc7900: attach keyboard and serial port, force cold boot (#2612)
-rw-r--r--src/mame/drivers/cgc7900.cpp221
-rw-r--r--src/mame/includes/cgc7900.h38
-rw-r--r--src/mame/video/cgc7900.cpp20
3 files changed, 231 insertions, 48 deletions
diff --git a/src/mame/drivers/cgc7900.cpp b/src/mame/drivers/cgc7900.cpp
index c96adab9e5d..d359a9fedb9 100644
--- a/src/mame/drivers/cgc7900.cpp
+++ b/src/mame/drivers/cgc7900.cpp
@@ -12,17 +12,18 @@
TODO:
- - does not boot
- - interrupts
- - vsync interrupt
- - map ROM to 000000-000007 at boot
+ . does not boot
+ . interrupts
+ . vsync interrupt
+ . map ROM to 000000-000007 at boot
+ - NVRAM (= battery backed SRAM) at 0xE40xxx
- floppy
- bitmap display
- Z mode read/write
- color status write
- bitmap roll
- overlay roll
- - keyboard
+ . keyboard
- joystick
- light pen
- memory parity
@@ -33,12 +34,30 @@
- HVG
- OMTI Series 10 SCSI controller (8" Winchester HD)
+ docs:
+
+ bitsavers://pdf/chromatics/
+ http://z80cpu.eu/mirrors/oldcomputers.dyndns.org/public/pub/manuals/omti10a.pdf
+
+ how to:
+
+ C-u @ -- enter Terminal
+ C-u F -- use serial port from Terminal (null_modem has to be set up 9600, 7E1)
+ C-u M -- enter Monitor
+ C-u T -- enter Thaw (setup utility)
+ C-u d -- boot DOS
+ C-u Q 1 -- display clock
+
+ See User's Manual appendix A for more control sequences.
*/
#include "emu.h"
#include "includes/cgc7900.h"
#include "speaker.h"
+#define VERBOSE 1
+#include "logmacro.h"
+
/***************************************************************************
@@ -62,18 +81,25 @@
#define INT_BINT1 0x4000
#define INT_RS232_RXRDY 0x8000
-//static const int INT_LEVEL[] = { 5, 4, 5, 4, 4, 5, 4, 5, 5, 4, 5, 4, 4, 5, 4, 5 };
-
/***************************************************************************
READ/WRITE HANDLERS
***************************************************************************/
+void cgc7900_state::kbd_put(u8 data)
+{
+ kbd_ready = true;
+ kbd_data = data;
+ irq_encoder(7, ASSERT_LINE);
+}
+
/*-------------------------------------------------
keyboard_r - keyboard data read
-------------------------------------------------*/
READ16_MEMBER( cgc7900_state::keyboard_r )
{
+ u16 data;
+
/*
bit description
@@ -97,7 +123,23 @@ READ16_MEMBER( cgc7900_state::keyboard_r )
*/
- return 0;
+ if (kbd_ready)
+ {
+ data = kbd_data | kbd_mods;
+ kbd_ready = false;
+ irq_encoder(7, CLEAR_LINE);
+ }
+ else
+ {
+ data = kbd_mods;
+ }
+
+ LOG("kbd == %04x\n", data);
+
+ if (kbd_mods)
+ kbd_mods = 0;
+
+ return data;
}
/*-------------------------------------------------
@@ -128,40 +170,82 @@ WRITE16_MEMBER( cgc7900_state::keyboard_w )
15
*/
+
+ LOG("kbd <- %04x\n", data);
}
/*-------------------------------------------------
interrupt_mask_w - interrupt mask write
-------------------------------------------------*/
+static const int int_levels[16] = { 5, 4, 5, 4, 4, 5, 4, 5, 5, 4, 5, 4, 4, 5, 4, 5 };
+static const int int_vectors[16] = {
+ 0x4b, 0x44, 0x4c, 0x43, 0x42, 0x4d, 0x45, 0x4a, 0x49, 0x46, 0x4e, 0x41, 0x40, 0x4f, 0x47, 0x48
+};
+
WRITE16_MEMBER( cgc7900_state::interrupt_mask_w )
{
/*
- bit description
-
- 0 real time clock
- 1 RS-449 Tx ready
- 2 BINT 2
- 3 RS-232 Tx ready
- 4 disk
- 5 BINT 3
- 6 bezel keys
- 7 keyboard
- 8 RS-449 Rx ready
- 9 light pen
- 10 BINT 4
- 11 joystick
- 12 vertical retrace
- 13 BINT 5
- 14 BINT 1
- 15 RS-232 Rx ready
-
+ bit description vec level
+
+ 0 real time clock 4b 5
+ 1 RS-449 Tx ready 44 4
+ 2 BINT 2 4c 5
+ 3 RS-232 Tx ready 43 4
+ 4 disk 42 4
+ 5 BINT 3 4d 5
+ 6 bezel keys 45 4
+ 7 keyboard 4a 5
+ 8 RS-449 Rx ready 49 5
+ 9 light pen 46 4
+ 10 BINT 4 4e 5
+ 11 joystick 41 4
+ 12 vert. retrace 40 4
+ 13 BINT 5 4f 5
+ 14 BINT 1 47 4
+ 15 RS-232 Rx ready 48 5
+
+ default mask is 0x7e3f -- RS232 Rx, RS449 Rx, keyboard, bezel.
*/
+ if (m_int_mask != data)
+ {
+ u16 changed = m_int_mask ^ data;
+
+ LOG("i_mask: changed %04X -> %04X\n", m_int_mask, data);
+
+ for (int i = 0; i < 16; i++)
+ {
+ if (BIT(changed, i) && BIT(data, i))
+ {
+ LOG("i_mask: pin %d disabled, clearing irq\n", i);
+ irq_encoder(i, CLEAR_LINE);
+ }
+ if (BIT(changed, i) && !BIT(data, i))
+ {
+ LOG("i_mask: pin %d enabled, %s irq\n", i, BIT(m_int_active, i) ? "setting" : "clearing");
+ irq_encoder(i, BIT(m_int_active, i));
+ }
+ }
+ }
+
m_int_mask = data;
}
+void cgc7900_state::irq_encoder(int pin, int state)
+{
+ if (state == ASSERT_LINE)
+ m_int_active |= (1 << pin);
+ else
+ m_int_active &= ~(1 << pin);
+
+ if (!BIT(m_int_mask, pin))
+ {
+ m_maincpu->set_input_line_and_vector(int_levels[pin], state, int_vectors[pin]);
+ }
+}
+
/*-------------------------------------------------
disk_data_r - disk data read
-------------------------------------------------*/
@@ -219,6 +303,29 @@ WRITE16_MEMBER( cgc7900_state::disk_command_w )
{
}
+READ16_MEMBER(cgc7900_state::unmapped_r)
+{
+ return rand();
+}
+
+WRITE8_MEMBER(cgc7900_state::baud_write)
+{
+ m_dbrg->str_w(data >> 0);
+ m_dbrg->stt_w(data >> 4);
+}
+
+WRITE_LINE_MEMBER(cgc7900_state::write_rs232_clock)
+{
+ m_i8251_0->write_txc(state);
+ m_i8251_0->write_rxc(state);
+}
+
+WRITE_LINE_MEMBER(cgc7900_state::write_rs449_clock)
+{
+ m_i8251_1->write_txc(state);
+ m_i8251_1->write_rxc(state);
+}
+
/***************************************************************************
MEMORY MAPS
***************************************************************************/
@@ -229,9 +336,9 @@ WRITE16_MEMBER( cgc7900_state::disk_command_w )
static ADDRESS_MAP_START( cgc7900_mem, AS_PROGRAM, 16, cgc7900_state )
ADDRESS_MAP_UNMAP_HIGH
- AM_RANGE(0x000000, 0x000007) AM_ROM AM_REGION(M68000_TAG, 0)
- AM_RANGE(0x000008, 0x1fffff) AM_RAM AM_SHARE("chrom_ram")
+ AM_RANGE(0x000000, 0x1fffff) AM_RAM AM_SHARE("chrom_ram")
AM_RANGE(0x800000, 0x80ffff) AM_ROM AM_REGION(M68000_TAG, 0)
+ AM_RANGE(0x810000, 0x9fffff) AM_READ(unmapped_r)
AM_RANGE(0xa00000, 0xbfffff) AM_READWRITE(z_mode_r, z_mode_w)
AM_RANGE(0xc00000, 0xdfffff) AM_RAM AM_SHARE("plane_ram")
AM_RANGE(0xe00000, 0xe1ffff) AM_WRITE(color_status_w)
@@ -257,10 +364,10 @@ static ADDRESS_MAP_START( cgc7900_mem, AS_PROGRAM, 16, cgc7900_state )
// AM_RANGE(0xefc446, 0xefc447) HVG Load dY
// AM_RANGE(0xefc448, 0xefc449) HVG Load Pixel Color
// AM_RANGE(0xefc44a, 0xefc44b) HVG Load Trip
- AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE8(INS8251_0_TAG, i8251_device, data_r, data_w, 0xff00)
- AM_RANGE(0xff8002, 0xff8003) AM_DEVREADWRITE8(INS8251_0_TAG, i8251_device, status_r, control_w, 0xff00)
- AM_RANGE(0xff8040, 0xff8041) AM_DEVREADWRITE8(INS8251_1_TAG, i8251_device, data_r, data_w, 0xff00)
- AM_RANGE(0xff8042, 0xff8043) AM_DEVREADWRITE8(INS8251_1_TAG, i8251_device, status_r, control_w, 0xff00)
+ AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE8(INS8251_0_TAG, i8251_device, data_r, data_w, 0xff)
+ AM_RANGE(0xff8002, 0xff8003) AM_DEVREADWRITE8(INS8251_0_TAG, i8251_device, status_r, control_w, 0xff)
+ AM_RANGE(0xff8040, 0xff8041) AM_DEVREADWRITE8(INS8251_1_TAG, i8251_device, data_r, data_w, 0xff)
+ AM_RANGE(0xff8042, 0xff8043) AM_DEVREADWRITE8(INS8251_1_TAG, i8251_device, status_r, control_w, 0xff)
AM_RANGE(0xff8080, 0xff8081) AM_READWRITE(keyboard_r, keyboard_w)
// AM_RANGE(0xff80c6, 0xff80c7) Joystick X axis
// AM_RANGE(0xff80ca, 0xff80cb) Joystick Y axis
@@ -268,8 +375,8 @@ static ADDRESS_MAP_START( cgc7900_mem, AS_PROGRAM, 16, cgc7900_state )
AM_RANGE(0xff8100, 0xff8101) AM_READWRITE(disk_data_r, disk_data_w)
AM_RANGE(0xff8120, 0xff8121) AM_READWRITE(disk_status_r, disk_command_w)
AM_RANGE(0xff8140, 0xff8141) AM_READ_PORT("BEZEL")
-// AM_RANGE(0xff8180, 0xff8181) AM_DEVWRITE8(K1135A_TAG, k1135a_w, 0xff00) Baud rate generator
-// AM_RANGE(0xff81c0, 0xff81ff) AM_DEVREADWRITE8(MM58167_TAG, mm58167_r, mm58167_w, 0xff00)
+ AM_RANGE(0xff8180, 0xff8181) AM_WRITE8(baud_write, 0xff00)
+ AM_RANGE(0xff81c0, 0xff81ff) AM_DEVREADWRITE8(MM58167_TAG, mm58167_device, read, write, 0xff)
AM_RANGE(0xff8200, 0xff8201) AM_WRITE(interrupt_mask_w)
// AM_RANGE(0xff8240, 0xff8241) Light Pen enable
// AM_RANGE(0xff8242, 0xff8243) Light Pen X value
@@ -280,6 +387,7 @@ static ADDRESS_MAP_START( cgc7900_mem, AS_PROGRAM, 16, cgc7900_state )
AM_RANGE(0xff83c0, 0xff83c1) AM_DEVWRITE8(AY8910_TAG, ay8910_device, address_w, 0xff00)
AM_RANGE(0xff83c2, 0xff83c3) AM_DEVREAD8(AY8910_TAG, ay8910_device, data_r, 0xff00)
AM_RANGE(0xff83c4, 0xff83c5) AM_DEVWRITE8(AY8910_TAG, ay8910_device, data_w, 0xff00)
+ // DDMA option board
// AM_RANGE(0xff8500, 0xff8501) Disk DMA Command Register
// AM_RANGE(0xff8502, 0xff8503) Disk DMA Address Register
// AM_RANGE(0xff8507, 0xff8507) Disk DMA Control/Status Register
@@ -345,6 +453,19 @@ void cgc7900_state::machine_start()
void cgc7900_state::machine_reset()
{
+ uint8_t *user1 = memregion(M68000_TAG)->base();
+
+ memcpy((uint8_t *)m_chrom_ram.target(), user1, 8); // not really what happens but...
+
+ m_maincpu->reset();
+
+ kbd_mods = 0x300; // forces cold boot -- initializes SRAM contents
+ kbd_data = 0;
+ kbd_ready = false;
+
+ m_i8251_0->write_cts(0);
+
+ m_int_active = 0;
}
/***************************************************************************
@@ -383,11 +504,37 @@ static MACHINE_CONFIG_START( cgc7900 )
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
/* devices */
+ MCFG_DEVICE_ADD("keyboard", GENERIC_KEYBOARD, 0)
+ MCFG_GENERIC_KEYBOARD_CB(PUT(cgc7900_state, kbd_put))
+
+ MCFG_DEVICE_ADD(MM58167_TAG, MM58167, XTAL_32_768kHz)
+ MCFG_MM58167_IRQ_CALLBACK(WRITELINE(cgc7900_state, irq<0x0>))
+
+ MCFG_DEVICE_ADD(K1135A_TAG, COM8116, XTAL_5_0688MHz)
+ MCFG_COM8116_FR_HANDLER(WRITELINE(cgc7900_state, write_rs232_clock))
+ MCFG_COM8116_FT_HANDLER(WRITELINE(cgc7900_state, write_rs449_clock))
+
MCFG_DEVICE_ADD(INS8251_0_TAG, I8251, 0)
- // rs232
+ MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd))
+ MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr))
+ MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts))
+ MCFG_I8251_RXRDY_HANDLER(WRITELINE(cgc7900_state, irq<0xf>))
+ MCFG_I8251_TXRDY_HANDLER(WRITELINE(cgc7900_state, irq<0x3>))
+
+ MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "null_modem")
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(INS8251_0_TAG, i8251_device, write_rxd))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE(INS8251_0_TAG, i8251_device, write_dsr))
MCFG_DEVICE_ADD(INS8251_1_TAG, I8251, 0)
- // rs449
+ MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs449", rs232_port_device, write_txd))
+ MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs449", rs232_port_device, write_dtr))
+ MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs449", rs232_port_device, write_rts))
+ MCFG_I8251_RXRDY_HANDLER(WRITELINE(cgc7900_state, irq<0x8>))
+ MCFG_I8251_TXRDY_HANDLER(WRITELINE(cgc7900_state, irq<0x1>))
+
+ MCFG_RS232_PORT_ADD("rs449", default_rs232_devices, nullptr)
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(INS8251_1_TAG, i8251_device, write_rxd))
+ MCFG_RS232_DSR_HANDLER(DEVWRITELINE(INS8251_1_TAG, i8251_device, write_dsr))
MACHINE_CONFIG_END
/***************************************************************************
diff --git a/src/mame/includes/cgc7900.h b/src/mame/includes/cgc7900.h
index 03a72078403..2ed507909e3 100644
--- a/src/mame/includes/cgc7900.h
+++ b/src/mame/includes/cgc7900.h
@@ -2,16 +2,22 @@
// copyright-holders:Curt Coder
#pragma once
-#ifndef __CGC7900__
-#define __CGC7900__
+#ifndef MAME_INCLUDES_CGC7900_H
+#define MAME_INCLUDES_CGC7900_H
+#include "bus/rs232/rs232.h"
#include "cpu/m68000/m68000.h"
#include "cpu/mcs48/mcs48.h"
#include "machine/ram.h"
#include "machine/i8251.h"
+#include "machine/com8116.h"
+#include "machine/mm58167.h"
+#include "machine/keyboard.h"
#include "sound/ay8910.h"
+#include "screen.h"
+
#define M68000_TAG "uh8"
#define INS8251_0_TAG "uc10"
#define INS8251_1_TAG "uc8"
@@ -29,6 +35,7 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, M68000_TAG),
m_palette(*this, "palette"),
+ m_screen(*this, "screen"),
m_char_rom(*this, "gfx1"),
m_chrom_ram(*this, "chrom_ram"),
m_plane_ram(*this, "plane_ram"),
@@ -43,11 +50,15 @@ public:
m_plane_switch(*this, "plane_switch"),
m_color_status_fg(*this, "color_status_fg"),
m_color_status_bg(*this, "color_status_bg"),
- m_roll_overlay(*this, "roll_overlay")
+ m_roll_overlay(*this, "roll_overlay"),
+ m_i8251_0(*this, INS8251_0_TAG),
+ m_i8251_1(*this, INS8251_1_TAG),
+ m_dbrg(*this, K1135A_TAG)
{ }
required_device<cpu_device> m_maincpu;
required_device<palette_device> m_palette;
+ required_device<screen_device> m_screen;
required_memory_region m_char_rom;
required_shared_ptr<uint16_t> m_chrom_ram;
required_shared_ptr<uint16_t> m_plane_ram;
@@ -63,6 +74,9 @@ public:
required_shared_ptr<uint16_t> m_color_status_fg;
required_shared_ptr<uint16_t> m_color_status_bg;
required_shared_ptr<uint16_t> m_roll_overlay;
+ required_device<i8251_device> m_i8251_0;
+ required_device<i8251_device> m_i8251_1;
+ required_device<com8116_device> m_dbrg;
virtual void machine_start() override;
virtual void machine_reset() override;
@@ -81,19 +95,35 @@ public:
DECLARE_WRITE16_MEMBER( z_mode_w );
DECLARE_WRITE16_MEMBER( color_status_w );
DECLARE_READ16_MEMBER( sync_r );
+ DECLARE_READ16_MEMBER( unmapped_r );
+
+ template <unsigned N> DECLARE_WRITE_LINE_MEMBER(irq) { irq_encoder(N, state); }
+
+ DECLARE_WRITE8_MEMBER(baud_write);
+ DECLARE_WRITE_LINE_MEMBER(write_rs232_clock);
+ DECLARE_WRITE_LINE_MEMBER(write_rs449_clock);
void update_clut();
void draw_bitmap(screen_device *screen, bitmap_rgb32 &bitmap);
void draw_overlay(screen_device *screen, bitmap_rgb32 &bitmap);
/* interrupt state */
- uint16_t m_int_mask;
+ uint16_t m_int_mask, m_int_active;
/* video state */
rgb_t m_clut[256];
int m_blink;
TIMER_DEVICE_CALLBACK_MEMBER(blink_tick);
+
+ void kbd_put(u8 data);
+
+private:
+ u16 kbd_mods;
+ u8 kbd_data;
+ bool kbd_ready;
+
+ void irq_encoder(int pin, int state);
};
/*----------- defined in video/cgc7900.c -----------*/
diff --git a/src/mame/video/cgc7900.cpp b/src/mame/video/cgc7900.cpp
index 2068d535b63..3f07d9bae9c 100644
--- a/src/mame/video/cgc7900.cpp
+++ b/src/mame/video/cgc7900.cpp
@@ -22,8 +22,8 @@
#define OVERLAY_DATA (cell & 0xff) /* ASCII or Plot Dot character */
#define IMAGE_SELECT BIT(m_roll_overlay[0], 13)
-#define OVERLAY_CURSOR_BLINK BIT(m_roll_overlay[0], 12)
-#define OVERLAY_CHARACTER_BLINK BIT(m_roll_overlay[0], 11)
+#define OVERLAY_CURSOR_BLINK BIT(m_roll_overlay[0], 14)
+#define OVERLAY_CHARACTER_BLINK BIT(m_roll_overlay[0], 15)
PALETTE_INIT_MEMBER(cgc7900_state, cgc7900)
{
@@ -72,6 +72,8 @@ WRITE16_MEMBER( cgc7900_state::color_status_w )
READ16_MEMBER( cgc7900_state::sync_r )
{
+ u16 data = 0xffff;
+
/*
bit signal description
@@ -95,7 +97,10 @@ READ16_MEMBER( cgc7900_state::sync_r )
*/
- return 0xffff;
+ if (m_screen->vblank()) data &= 1;
+ if (m_screen->hblank()) data &= 4;
+
+ return data;
}
/***************************************************************************
@@ -135,7 +140,7 @@ void cgc7900_state::draw_bitmap(screen_device *screen, bitmap_rgb32 &bitmap)
void cgc7900_state::draw_overlay(screen_device *screen, bitmap_rgb32 &bitmap)
{
const pen_t *pen = m_palette->pens();
- for (int y = 0; y < 768; y++)
+ for (int y = 0; y < 48 * 8; y++)
{
int sy = y / 8;
int line = y % 8;
@@ -159,13 +164,13 @@ void cgc7900_state::draw_overlay(screen_device *screen, bitmap_rgb32 &bitmap)
}
else
{
- if (BIT(data, x) && (!OVERLAY_CHARACTER_BLINK || m_blink))
+ if (!BIT(data, x) || (OVERLAY_BLK && OVERLAY_CHARACTER_BLINK && !m_blink))
{
- if (OVERLAY_VF) bitmap.pix32(y, (sx * 8) + x) = pen[fg];
+ if (OVERLAY_VB) bitmap.pix32(y, (sx * 8) + x) = pen[bg];
}
else
{
- if (OVERLAY_VB) bitmap.pix32(y, (sx * 8) + x) = pen[bg];
+ if (OVERLAY_VF) bitmap.pix32(y, (sx * 8) + x) = pen[fg];
}
}
}
@@ -229,6 +234,7 @@ MACHINE_CONFIG_START( cgc7900_video )
MCFG_SCREEN_UPDATE_DRIVER(cgc7900_state, screen_update)
MCFG_SCREEN_SIZE(1024, 768)
MCFG_SCREEN_VISIBLE_AREA(0, 1024-1, 0, 768-1)
+ MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(cgc7900_state, irq<0xc>))
MCFG_GFXDECODE_ADD("gfxdecode", "palette", cgc7900)
MCFG_PALETTE_ADD("palette", 8)