mirror of
https://github.com/holub/mame
synced 2025-04-16 13:34:55 +03:00
rc759: wip. initial version of the intel 82730 text coprocessor, and
added more meat to the driver. currently dies testing the cassette.
This commit is contained in:
parent
48990c4ae4
commit
caa26040c7
@ -368,6 +368,18 @@ if (VIDEOS["I8244"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/emu/video/i82730.h,VIDEOS["I82730"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (VIDEOS["I82730"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/emu/video/i82730.c",
|
||||
MAME_DIR .. "src/emu/video/i82730.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/emu/video/i8275.h,VIDEOS["I8275"] = true
|
||||
|
@ -287,6 +287,7 @@ VIDEOS["HUC6261"] = true
|
||||
VIDEOS["HUC6270"] = true
|
||||
VIDEOS["HUC6272"] = true
|
||||
VIDEOS["I8244"] = true
|
||||
VIDEOS["I82730"] = true
|
||||
VIDEOS["I8275"] = true
|
||||
--VIDEOS+= M50458"] = true
|
||||
--VIDEOS+= MB90082"] = true
|
||||
|
527
src/emu/video/i82730.c
Normal file
527
src/emu/video/i82730.c
Normal file
@ -0,0 +1,527 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Dirk Best
|
||||
/***************************************************************************
|
||||
|
||||
Intel 82730
|
||||
|
||||
Text Coprocessor
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "i82730.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
#define VERBOSE 1
|
||||
#define VERBOSE_COMMANDS 1
|
||||
#define VERBOSE_DATASTREAM 0
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
const device_type I82730 = &device_creator<i82730_device>;
|
||||
|
||||
const char *i82730_device::m_command_names[] =
|
||||
{
|
||||
/* 00 */ "NOP",
|
||||
/* 01 */ "START DISPLAY",
|
||||
/* 02 */ "START VIRTUAL DISPLAY",
|
||||
/* 03 */ "STOP DISPLAY",
|
||||
/* 04 */ "MODE SET",
|
||||
/* 05 */ "LOAD CBP",
|
||||
/* 06 */ "LOAD INTMASK",
|
||||
/* 07 */ "LPEN ENABLE",
|
||||
/* 08 */ "READ STATUS",
|
||||
/* 09 */ "LD CUR POS",
|
||||
/* 0a */ "SELF TEST",
|
||||
/* 0b */ "TEST ROW BUFFER"
|
||||
};
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// i82730_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
i82730_device::i82730_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, I82730, "I82730", tag, owner, clock, "i82730", __FILE__),
|
||||
device_video_interface(mconfig, *this),
|
||||
m_sint_handler(*this),
|
||||
m_cpu_tag(NULL), m_program(NULL),
|
||||
m_row_timer(NULL),
|
||||
m_initialized(false), m_mode_set(false),
|
||||
m_ca(0),
|
||||
m_sysbus(0x00), m_ibp(0x0000), m_cbp(0x0000), m_intmask(0xffff), m_status(0x0000),
|
||||
m_list_switch(0), m_auto_line_feed(0), m_max_dma_count(0),
|
||||
m_lptr(0), m_sptr(0),
|
||||
m_dma_burst_space(0), m_dma_burst_length(0),
|
||||
m_hfldstrt(0), m_margin(0), m_lpr(0), m_field_attribute_mask(0), m_vsyncstp(0), m_vfldstrt(0), m_vfldstp(0),
|
||||
m_frame_int_count(0),
|
||||
m_row_index(0)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_cpu_tag - set cpu we are attached to
|
||||
//-------------------------------------------------
|
||||
|
||||
void i82730_device::set_cpu_tag(device_t &device, device_t *owner, const char *tag)
|
||||
{
|
||||
i82730_device &dev = dynamic_cast<i82730_device &>(device);
|
||||
dev.m_cpu_tag = tag;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void i82730_device::device_start()
|
||||
{
|
||||
// register bitmap
|
||||
m_screen->register_screen_bitmap(m_bitmap);
|
||||
|
||||
// resolve callbacks
|
||||
m_sint_handler.resolve_safe();
|
||||
|
||||
// bind delegates
|
||||
m_update_row_cb.bind_relative_to(*owner());
|
||||
|
||||
// allocate row timer
|
||||
m_row_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(i82730_device::row_update), this));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void i82730_device::device_reset()
|
||||
{
|
||||
cpu_device *cpu = m_owner->subdevice<cpu_device>(m_cpu_tag);
|
||||
m_program = &cpu->space(AS_PROGRAM);
|
||||
|
||||
m_initialized = false;
|
||||
m_mode_set = false;
|
||||
|
||||
m_ca = 0;
|
||||
m_status = 0x0000;
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MEMORY ACCESS
|
||||
//**************************************************************************
|
||||
|
||||
UINT8 i82730_device::read_byte(offs_t address)
|
||||
{
|
||||
return m_program->read_byte(address);
|
||||
}
|
||||
|
||||
UINT16 i82730_device::read_word(offs_t address)
|
||||
{
|
||||
UINT16 data = 0xffff;
|
||||
|
||||
if (sysbus_16bit() && !(address & 1))
|
||||
{
|
||||
data = m_program->read_word(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = m_program->read_byte(address);
|
||||
data |= m_program->read_byte(address + 1) << 8;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void i82730_device::write_byte(offs_t address, UINT8 data)
|
||||
{
|
||||
m_program->write_byte(address, data);
|
||||
}
|
||||
|
||||
void i82730_device::write_word(offs_t address, UINT16 data)
|
||||
{
|
||||
if (sysbus_16bit() && !(address & 1))
|
||||
{
|
||||
m_program->write_word(address, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_program->write_byte(address, data & 0xff);
|
||||
m_program->write_byte(address + 1, (data >> 8) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// IMPLEMENTATION
|
||||
//**************************************************************************
|
||||
|
||||
void i82730_device::update_interrupts()
|
||||
{
|
||||
UINT16 code = m_status & ~m_intmask & ~(VDIP | DIP);
|
||||
write_word(m_cbp + 20, code);
|
||||
|
||||
if (code)
|
||||
m_sint_handler(1);
|
||||
}
|
||||
|
||||
void i82730_device::mode_set()
|
||||
{
|
||||
UINT32 mptr = (read_word(m_cbp + 32) << 16) | read_word(m_cbp + 30);
|
||||
UINT16 tmp;
|
||||
|
||||
tmp = read_word(mptr);
|
||||
m_dma_burst_space = tmp & 0x7f;
|
||||
m_dma_burst_length = (tmp >> 8) & 0x7f;
|
||||
|
||||
tmp = read_word(mptr + 2);
|
||||
UINT8 hsyncstp = tmp & 0xff;
|
||||
UINT8 line_length = (tmp >> 8) & 0xff;
|
||||
|
||||
tmp = read_word(mptr + 4);
|
||||
UINT8 hfldstp = tmp & 0xff;
|
||||
m_hfldstrt = (tmp >> 8) & 0xff;
|
||||
|
||||
tmp = read_word(mptr + 6);
|
||||
UINT8 hbrdstp = tmp & 0xff;
|
||||
UINT8 hbrdstrt = (tmp >> 8) & 0xff;
|
||||
|
||||
tmp = read_word(mptr + 8);
|
||||
m_margin = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 10);
|
||||
m_lpr = tmp & 0x1f;
|
||||
|
||||
tmp = read_word(mptr + 24);
|
||||
m_field_attribute_mask = tmp & 0x7fff;
|
||||
|
||||
tmp = read_word(mptr + 26);
|
||||
UINT16 frame_length = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 28);
|
||||
m_vsyncstp = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 30);
|
||||
m_vfldstrt = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 32);
|
||||
m_vfldstp = tmp & 0x7ff;
|
||||
|
||||
tmp = read_word(mptr + 38);
|
||||
m_frame_int_count = tmp & 0x0f;
|
||||
|
||||
// setup screen mode
|
||||
rectangle visarea(hbrdstrt * 16, hbrdstp * 16 - 1, m_vsyncstp, m_vfldstp + m_margin + 1 + m_lpr - 1);
|
||||
attoseconds_t period = HZ_TO_ATTOSECONDS(clock() * 16) * line_length * 16 * frame_length;
|
||||
m_screen->configure(line_length * 16, frame_length, visarea, period);
|
||||
|
||||
// start display is now valid
|
||||
m_mode_set = true;
|
||||
|
||||
// adjust timer for the new mode
|
||||
m_row_timer->adjust(m_screen->time_until_pos(0));
|
||||
|
||||
// output some debug info
|
||||
if (VERBOSE)
|
||||
{
|
||||
logerror("%s('%s'): ---- setting mode ----\n", shortname(), basetag());
|
||||
logerror("%s('%s'): dma burst length %02x, space %02x\n", shortname(), basetag(), m_dma_burst_length, m_dma_burst_space);
|
||||
logerror("%s('%s'): margin %02x, lpr %02x\n", shortname(), basetag(), m_margin, m_lpr);
|
||||
logerror("%s('%s'): hsyncstp: %02x, line_length: %02x, hfldstrt: %02x, hbrdstart: %02x, hfldstop: %02x, hbrdstop: %02x\n",
|
||||
shortname(), basetag(), hsyncstp, line_length, m_hfldstrt, hbrdstrt, hfldstp, hbrdstp);
|
||||
logerror("%s('%s'): frame_length %04x, vsyncstp: %04x, vfldstrt: %04x, vfldstp: %04x\n",
|
||||
shortname(), basetag(), frame_length, m_vsyncstp, m_vfldstrt, m_vfldstp);
|
||||
}
|
||||
}
|
||||
|
||||
void i82730_device::execute_command()
|
||||
{
|
||||
UINT8 command = read_byte(m_cbp + 1);
|
||||
UINT16 tmp;
|
||||
|
||||
if (VERBOSE_COMMANDS && command < ARRAY_LENGTH(m_command_names))
|
||||
logerror("%s('%s'): executing command: %s [cbp = %08x]\n", shortname(), basetag(), m_command_names[command], m_cbp);
|
||||
|
||||
tmp = read_word(m_cbp + 2);
|
||||
m_list_switch = BIT(tmp, 6);
|
||||
m_auto_line_feed = BIT(tmp, 7);
|
||||
|
||||
tmp = read_word(m_cbp + 4);
|
||||
m_max_dma_count = tmp & 0xff;
|
||||
|
||||
switch (command)
|
||||
{
|
||||
// NOP
|
||||
case 0x00:
|
||||
break;
|
||||
|
||||
// START DISPLAY
|
||||
case 0x01:
|
||||
if (m_mode_set)
|
||||
m_status = (m_status & ~VDIP) | DIP;
|
||||
break;
|
||||
|
||||
// START VIRTUAL DISPLAY
|
||||
case 0x02:
|
||||
if (m_mode_set)
|
||||
m_status = VDIP | (m_status & ~DIP);
|
||||
break;
|
||||
|
||||
// STOP DISPLAY
|
||||
case 0x03:
|
||||
m_status &= ~(VDIP | DIP);
|
||||
break;
|
||||
|
||||
// MODE SET
|
||||
case 0x04:
|
||||
mode_set();
|
||||
break;
|
||||
|
||||
// LOAD CBP
|
||||
case 0x05:
|
||||
m_cbp = (read_word(m_cbp + 16) << 16) | read_word(m_cbp + 14);
|
||||
execute_command();
|
||||
break;
|
||||
|
||||
// LOAD INTMASK
|
||||
case 0x06:
|
||||
m_intmask = read_word(m_cbp + 22);
|
||||
if (VERBOSE_COMMANDS)
|
||||
logerror("%s('%s'): intmask now %04x\n", shortname(), basetag(), m_intmask);
|
||||
break;
|
||||
|
||||
// LPEN ENABLE
|
||||
case 0x07:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), m_command_names[command]);
|
||||
break;
|
||||
|
||||
// READ STATUS
|
||||
case 0x08:
|
||||
write_word(m_cbp + 18, m_status);
|
||||
m_status &= (VDIP | DIP);
|
||||
break;
|
||||
|
||||
// LD CUR POS
|
||||
case 0x09:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), m_command_names[command]);
|
||||
break;
|
||||
|
||||
// SELF TEST
|
||||
case 0x0a:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), m_command_names[command]);
|
||||
break;
|
||||
|
||||
// TEST ROW BUFFER
|
||||
case 0x0b:
|
||||
fatalerror("%s('%s'): Unimplemented command %s\n", shortname(), basetag(), m_command_names[command]);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (VERBOSE_COMMANDS)
|
||||
logerror("%s('%s'): executing command: (reserved) [cbp = %08x]\n", shortname(), basetag(), m_cbp);
|
||||
m_status |= RCC;
|
||||
update_interrupts();
|
||||
break;
|
||||
}
|
||||
|
||||
// clear busy
|
||||
write_word(m_cbp, read_word(m_cbp) & 0xff00);
|
||||
}
|
||||
|
||||
void i82730_device::load_row()
|
||||
{
|
||||
bool finished = false;
|
||||
|
||||
m_row[m_row_index].count = 0;
|
||||
|
||||
while (!finished)
|
||||
{
|
||||
UINT16 data = read_word(m_sptr);
|
||||
m_sptr += 2;
|
||||
|
||||
if (BIT(data, 15))
|
||||
{
|
||||
switch (data >> 8)
|
||||
{
|
||||
case 0x8e:
|
||||
m_field_attribute_mask = read_word(m_sptr) & 0x7fff;
|
||||
m_sptr += 2;
|
||||
|
||||
if (VERBOSE_DATASTREAM)
|
||||
logerror("%s('%s'): SET FIELD ATTRIB to %04x\n", shortname(), basetag(), m_field_attribute_mask);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("%s('%s'): Unimplemented datastream command %02x\n", shortname(), basetag(), data >> 8);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// maximum row size is 200
|
||||
if (m_row[m_row_index].count < m_max_dma_count && m_row[m_row_index].count < 200)
|
||||
{
|
||||
m_row[m_row_index].data[m_row[m_row_index].count++] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
// move to next string?
|
||||
if (m_auto_line_feed == 0)
|
||||
{
|
||||
m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr);
|
||||
m_lptr += 4;
|
||||
}
|
||||
#endif
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_sptr -= 2;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( i82730_device::row_update )
|
||||
{
|
||||
int y = m_screen->vpos();
|
||||
|
||||
if (y == 0)
|
||||
{
|
||||
// clear interrupt status flags
|
||||
m_status &= (VDIP | DIP);
|
||||
|
||||
// clear field attribute mask
|
||||
m_field_attribute_mask = 0;
|
||||
|
||||
// get listbase
|
||||
if (m_list_switch)
|
||||
m_lptr = (read_word(m_cbp + 8) << 16) | read_word(m_cbp + 6);
|
||||
else
|
||||
m_lptr = (read_word(m_cbp + 12) << 16) | read_word(m_cbp + 10);
|
||||
|
||||
m_sptr = (read_word(m_lptr + 2) << 16) | read_word(m_lptr);
|
||||
m_lptr += 4;
|
||||
|
||||
// fetch initial row
|
||||
m_row_index = 0;
|
||||
load_row();
|
||||
}
|
||||
else if (y >= m_vsyncstp && y < m_vfldstrt)
|
||||
{
|
||||
// blank (top border)
|
||||
}
|
||||
else if (y >= m_vfldstrt && y < m_vfldstp)
|
||||
{
|
||||
UINT8 lc = (y - m_vfldstrt) % (m_lpr + 1);
|
||||
|
||||
// call driver
|
||||
m_update_row_cb(m_bitmap, m_row[m_row_index].data, lc, y - m_vsyncstp, m_row[m_row_index].count);
|
||||
|
||||
// swap buffers at end of row
|
||||
if (lc == m_lpr)
|
||||
{
|
||||
m_row_index ^= 1;
|
||||
load_row();
|
||||
}
|
||||
}
|
||||
else if (y >= m_vfldstp && y < m_vfldstp + m_margin + 1)
|
||||
{
|
||||
// margin
|
||||
}
|
||||
else if (y >= m_vfldstp + m_margin + 1 && y < m_vfldstp + m_margin + 1 + m_lpr + 1)
|
||||
{
|
||||
UINT8 lc = (y - (m_vfldstp + m_margin + 1)) % (m_lpr + 1);
|
||||
|
||||
m_sptr = (read_word(m_cbp + 36) << 16) | read_word(m_cbp + 34);
|
||||
load_row();
|
||||
|
||||
// call driver
|
||||
m_update_row_cb(m_bitmap, m_row[m_row_index].data, lc, y - m_vsyncstp, m_row[m_row_index].count);
|
||||
}
|
||||
else if (y == m_vfldstp + m_margin + 1 + m_lpr + 1)
|
||||
{
|
||||
// todo: check ca
|
||||
|
||||
// frame interrupt?
|
||||
if ((m_screen->frame_number() % m_frame_int_count) == 0)
|
||||
m_status |= EONF;
|
||||
|
||||
// check interrupts
|
||||
update_interrupts();
|
||||
}
|
||||
else
|
||||
{
|
||||
// vblank
|
||||
}
|
||||
|
||||
m_row_timer->adjust(m_screen->time_until_pos((y + 1) % m_screen->height()));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( i82730_device::ca_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("%s('%s'): ca_w %d\n", shortname(), basetag(), state);
|
||||
|
||||
// falling edge
|
||||
if (m_ca == 1 && state == 0)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
// get system bus width
|
||||
m_sysbus = m_program->read_byte(0xfffffff6);
|
||||
|
||||
// get intermediate block pointer
|
||||
m_ibp = (read_word(0xfffffffe) << 16) | read_word(0xfffffffc);
|
||||
|
||||
// get system configuration byte
|
||||
UINT8 scb = read_byte(m_ibp + 6);
|
||||
|
||||
// clear busy
|
||||
write_word(m_ibp, read_word(m_ibp) & 0xff00);
|
||||
|
||||
// done
|
||||
m_initialized = true;
|
||||
|
||||
// output some debug info
|
||||
if (VERBOSE)
|
||||
{
|
||||
logerror("%s('%s'): ---- initializing ----\n", shortname(), basetag());
|
||||
logerror("%s('%s'): %s system bus\n", shortname(), basetag(), sysbus_16bit() ? "16-bit" : "8-bit");
|
||||
logerror("%s('%s'): intermediate block pointer: %08x\n", shortname(), basetag(), m_ibp);
|
||||
logerror("%s('%s'): addrbus: %s, clno: %d, clpos: %d, mode: %s, dtw16: %s, srdy: %s\n", shortname(), basetag(),
|
||||
BIT(scb, 0) ? "32-bit" : "16-bit", (scb >> 1) & 0x03, (scb >> 3) & 0x03,
|
||||
BIT(scb, 5) ? "master" : "slave", BIT(scb, 6) ? "16-bit" : "8-bit", BIT(scb, 7) ? "synchronous" : "asynchronous");
|
||||
}
|
||||
}
|
||||
|
||||
// fetch command block pointer
|
||||
m_cbp = (read_word(m_ibp + 4) << 16) | read_word(m_ibp + 2);
|
||||
|
||||
// and execute command
|
||||
execute_command();
|
||||
}
|
||||
|
||||
m_ca = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( i82730_device::irst_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("%s('%s'): irst_w %d\n", shortname(), basetag(), state);
|
||||
|
||||
m_sint_handler(0);
|
||||
}
|
||||
|
||||
UINT32 i82730_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
copybitmap(bitmap, m_bitmap, 0, 0, m_hfldstrt * 16, 0, cliprect);
|
||||
return 0;
|
||||
}
|
157
src/emu/video/i82730.h
Normal file
157
src/emu/video/i82730.h
Normal file
@ -0,0 +1,157 @@
|
||||
// license:GPL-2.0+
|
||||
// copyright-holders:Dirk Best
|
||||
/***************************************************************************
|
||||
|
||||
Intel 82730
|
||||
|
||||
Text Coprocessor
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __I82730_H__
|
||||
#define __I82730_H__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_I82730_ADD(_tag, _cpu_tag, _clock) \
|
||||
MCFG_DEVICE_ADD(_tag, I82730, _clock) \
|
||||
i82730_device::set_cpu_tag(*device, owner, _cpu_tag);
|
||||
|
||||
#define MCFG_I82730_SINT_HANDLER(_devcb) \
|
||||
devcb = &i82730_device::set_sint_handler(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_I82730_UPDATE_ROW_CB(_class, _method) \
|
||||
i82730_device::set_update_row_callback(*device, i82730_update_row_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
typedef device_delegate<void (bitmap_rgb32 &bitmap, UINT16 *data, UINT8 lc, UINT16 y, int x_count)> i82730_update_row_delegate;
|
||||
|
||||
#define I82730_UPDATE_ROW(name) \
|
||||
void name(bitmap_rgb32 &bitmap, UINT16 *data, UINT8 lc, UINT16 y, int x_count)
|
||||
|
||||
|
||||
// ======================> i82730_device
|
||||
|
||||
class i82730_device : public device_t, public device_video_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
i82730_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// callbacks
|
||||
template<class _Object> static devcb_base &set_sint_handler(device_t &device, _Object object)
|
||||
{ return downcast<i82730_device &>(device).m_sint_handler.set_callback(object); }
|
||||
|
||||
// inline configuration
|
||||
static void set_cpu_tag(device_t &device, device_t *owner, const char *tag);
|
||||
static void set_update_row_callback(device_t &device, i82730_update_row_delegate callback) { downcast<i82730_device &>(device).m_update_row_cb = callback; }
|
||||
|
||||
UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(ca_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(irst_w);
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
private:
|
||||
// status
|
||||
enum
|
||||
{
|
||||
DUR = 0x001, // data underrun
|
||||
LPU = 0x002, // light pen update
|
||||
DBOR = 0x004, // data buffer overrun
|
||||
EONF = 0x008, // end of n frames
|
||||
FDE = 0x010, // frame data error
|
||||
RCC = 0x020, // reserved channel command executed
|
||||
RDC = 0x040, // reserved data stream command executed
|
||||
DIP = 0x080, // display in progress
|
||||
VDIP = 0x100 // virtual display in progress
|
||||
};
|
||||
|
||||
static const char* m_command_names[];
|
||||
|
||||
bool sysbus_16bit() { return BIT(m_sysbus, 0); }
|
||||
|
||||
UINT8 read_byte(offs_t address);
|
||||
UINT16 read_word(offs_t address);
|
||||
void write_byte(offs_t address, UINT8 data);
|
||||
void write_word(offs_t address, UINT16 data);
|
||||
|
||||
void update_interrupts();
|
||||
void mode_set();
|
||||
void execute_command();
|
||||
void load_row();
|
||||
|
||||
TIMER_CALLBACK_MEMBER(row_update);
|
||||
|
||||
devcb_write_line m_sint_handler;
|
||||
i82730_update_row_delegate m_update_row_cb;
|
||||
|
||||
const char *m_cpu_tag;
|
||||
address_space *m_program;
|
||||
|
||||
emu_timer *m_row_timer;
|
||||
|
||||
bitmap_rgb32 m_bitmap;
|
||||
|
||||
bool m_initialized;
|
||||
bool m_mode_set;
|
||||
|
||||
int m_ca;
|
||||
|
||||
// internal registers
|
||||
UINT8 m_sysbus;
|
||||
UINT32 m_ibp;
|
||||
UINT32 m_cbp;
|
||||
UINT16 m_intmask;
|
||||
UINT16 m_status;
|
||||
|
||||
int m_list_switch;
|
||||
int m_auto_line_feed;
|
||||
UINT8 m_max_dma_count;
|
||||
|
||||
UINT32 m_lptr;
|
||||
UINT32 m_sptr;
|
||||
|
||||
int m_dma_burst_space;
|
||||
int m_dma_burst_length;
|
||||
|
||||
// display parameters
|
||||
int m_hfldstrt;
|
||||
int m_margin;
|
||||
int m_lpr;
|
||||
UINT16 m_field_attribute_mask;
|
||||
int m_vsyncstp;
|
||||
int m_vfldstrt;
|
||||
int m_vfldstp;
|
||||
|
||||
int m_frame_int_count;
|
||||
|
||||
// row buffers
|
||||
struct row_buffer
|
||||
{
|
||||
UINT16 data[200];
|
||||
int count;
|
||||
};
|
||||
|
||||
row_buffer m_row[2];
|
||||
int m_row_index;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type I82730;
|
||||
|
||||
#endif // __I82730_H__
|
@ -2,14 +2,9 @@
|
||||
// copyright-holders:Dirk Best
|
||||
/***************************************************************************
|
||||
|
||||
Regnecentralen RC759
|
||||
Regnecentralen RC759 Piccoline
|
||||
|
||||
TODO:
|
||||
- Emulate the Intel 82730 CRT controller and figure out the rest
|
||||
- Connect iSBX bus
|
||||
- (much later) move floppy/external printer to the slot interface
|
||||
|
||||
Status: Hangs waiting for an answer from the 82730
|
||||
Status: Error 32 (cassette data error)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -17,10 +12,17 @@
|
||||
#include "cpu/i86/i186.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/mm58167.h"
|
||||
#include "machine/pic8259.h"
|
||||
#include "machine/i8255.h"
|
||||
#include "video/i82730.h"
|
||||
#include "sound/speaker.h"
|
||||
#include "sound/sn76496.h"
|
||||
#include "machine/keyboard.h"
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "imagedev/cassette.h"
|
||||
#include "bus/isbx/isbx.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -34,19 +36,31 @@ public:
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_pic(*this, "pic"),
|
||||
m_nvram(*this, "nvram"),
|
||||
m_ppi(*this, "ppi"),
|
||||
m_txt(*this, "txt"),
|
||||
m_cas(*this, "cas"),
|
||||
m_isbx(*this, "isbx"),
|
||||
m_speaker(*this, "speaker"),
|
||||
m_snd(*this, "snd"),
|
||||
m_rtc(*this, "rtc"),
|
||||
m_centronics(*this, "centronics"),
|
||||
m_fdc(*this, "fdc"),
|
||||
m_floppy0(*this, "fdc:0"),
|
||||
m_floppy1(*this, "fdc:1"),
|
||||
m_vram(*this, "vram"),
|
||||
m_cas_enabled(0),
|
||||
m_config(*this, "config"),
|
||||
m_cas_enabled(0), m_cas_data(0),
|
||||
m_drq_source(0),
|
||||
m_nvram_bank(0),
|
||||
m_gfx_mode(0),
|
||||
m_keyboard_enable(0)
|
||||
m_keyboard_enable(0), m_keyboard_key(0x00),
|
||||
m_centronics_strobe(0), m_centronics_init(0), m_centronics_select_in(0), m_centronics_busy(0),
|
||||
m_centronics_ack(0), m_centronics_fault(0), m_centronics_perror(0), m_centronics_select(0),
|
||||
m_centronics_data(0xff)
|
||||
{ }
|
||||
|
||||
DECLARE_WRITE8_MEMBER(keyb_put);
|
||||
DECLARE_READ8_MEMBER(keyboard_r);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(floppy_control_w);
|
||||
@ -58,9 +72,27 @@ public:
|
||||
DECLARE_READ8_MEMBER(ppi_portb_r);
|
||||
DECLARE_WRITE8_MEMBER(ppi_portc_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(centronics_busy_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(centronics_ack_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(centronics_fault_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(centronics_perror_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(centronics_select_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(centronics_data_r);
|
||||
DECLARE_WRITE8_MEMBER(centronics_data_w);
|
||||
DECLARE_READ8_MEMBER(centronics_control_r);
|
||||
DECLARE_WRITE8_MEMBER(centronics_control_w);
|
||||
|
||||
I82730_UPDATE_ROW(txt_update_row);
|
||||
DECLARE_WRITE16_MEMBER(txt_ca_w);
|
||||
DECLARE_WRITE16_MEMBER(txt_irst_w);
|
||||
DECLARE_READ8_MEMBER(palette_r);
|
||||
DECLARE_WRITE8_MEMBER(palette_w);
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(i186_timer0_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(i186_timer1_w);
|
||||
|
||||
void nvram_init(nvram_device &nvram, void *data, size_t size);
|
||||
DECLARE_READ8_MEMBER(nvram_r);
|
||||
DECLARE_WRITE8_MEMBER(nvram_w);
|
||||
DECLARE_READ8_MEMBER(rtc_r);
|
||||
@ -75,18 +107,40 @@ protected:
|
||||
private:
|
||||
required_device<i80186_cpu_device> m_maincpu;
|
||||
required_device<pic8259_device> m_pic;
|
||||
required_device<nvram_device> m_nvram;
|
||||
required_device<i8255_device> m_ppi;
|
||||
required_device<i82730_device> m_txt;
|
||||
required_device<cassette_image_device> m_cas;
|
||||
required_device<isbx_slot_device> m_isbx;
|
||||
required_device<speaker_sound_device> m_speaker;
|
||||
required_device<sn76489a_device> m_snd;
|
||||
required_device<mm58167_device> m_rtc;
|
||||
required_device<centronics_device> m_centronics;
|
||||
required_device<wd2797_t> m_fdc;
|
||||
required_device<floppy_connector> m_floppy0;
|
||||
required_device<floppy_connector> m_floppy1;
|
||||
required_shared_ptr<UINT16> m_vram;
|
||||
required_ioport m_config;
|
||||
|
||||
std::vector<UINT8> m_nvram_mem;
|
||||
|
||||
int m_cas_enabled;
|
||||
int m_cas_data;
|
||||
int m_drq_source;
|
||||
int m_nvram_bank;
|
||||
int m_gfx_mode;
|
||||
int m_keyboard_enable;
|
||||
UINT8 m_keyboard_key;
|
||||
|
||||
int m_centronics_strobe;
|
||||
int m_centronics_init;
|
||||
int m_centronics_select_in;
|
||||
int m_centronics_busy;
|
||||
int m_centronics_ack;
|
||||
int m_centronics_fault;
|
||||
int m_centronics_perror;
|
||||
int m_centronics_select;
|
||||
UINT8 m_centronics_data;
|
||||
};
|
||||
|
||||
|
||||
@ -94,24 +148,35 @@ private:
|
||||
// I/O
|
||||
//**************************************************************************
|
||||
|
||||
// pic ir1 keyboard
|
||||
WRITE8_MEMBER( rc759_state::keyb_put )
|
||||
{
|
||||
m_keyboard_key = data;
|
||||
m_pic->ir1_w(1);
|
||||
}
|
||||
|
||||
READ8_MEMBER( rc759_state::keyboard_r )
|
||||
{
|
||||
logerror("keyboard_r\n");
|
||||
return 0xff;
|
||||
|
||||
m_pic->ir1_w(0);
|
||||
|
||||
if (m_keyboard_enable)
|
||||
return m_keyboard_key;
|
||||
else
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
READ8_MEMBER( rc759_state::ppi_porta_r )
|
||||
{
|
||||
UINT8 data = 0;
|
||||
|
||||
data |= m_cas->input() > 0 ? 1 : 0;
|
||||
data |= 1 << 1; // 0 = isbx module installed
|
||||
data |= 0 << 2; // option0 from isbx
|
||||
data |= 0 << 3; // option1 from isbx
|
||||
data |= m_cas_enabled ? m_cas_data : (m_cas->input() > 0 ? 1 : 0);
|
||||
data |= m_isbx->mpst_r() << 1;
|
||||
data |= m_isbx->opt0_r() << 2;
|
||||
data |= m_isbx->opt1_r() << 3;
|
||||
data |= 1 << 4; // mem ident0
|
||||
data |= 1 << 5; // mem ident1 (both 1 = 256k installed)
|
||||
data |= 0 << 6; // dpc connect (0 = external floppy/printer installed)
|
||||
data |= 1 << 6; // dpc connect (0 = external floppy/printer installed)
|
||||
data |= 1 << 7; // not used
|
||||
|
||||
return data;
|
||||
@ -122,27 +187,102 @@ READ8_MEMBER( rc759_state::ppi_portb_r )
|
||||
UINT8 data = 0;
|
||||
|
||||
data |= 1 << 0; // 0 = micronet controller installed
|
||||
data |= 0 << 1; // rtc type, 0 = cdp1879
|
||||
data |= 1 << 2; // sound generator detect
|
||||
data |= 1 << 1; // rtc type, mm58167/cdp1879
|
||||
data |= m_snd->ready_r() << 2;
|
||||
data |= 1 << 3; // not used
|
||||
data |= 1 << 4; // not used
|
||||
data |= 0 << 5; // 0 = color monitor, 1 = monochrome
|
||||
data |= 1 << 6; // 0 = 15khz, 1 = 22khz monitor
|
||||
data |= 1 << 7; // not used
|
||||
data |= m_config->read(); // monitor type and frequency
|
||||
data |= 1 << 7; // 0 = enable remote hardware debug (using an isbx351 module)
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( rc759_state::ppi_portc_w )
|
||||
{
|
||||
logerror("ppi_portc_w: %02x\n", data);
|
||||
|
||||
m_cas_enabled = BIT(data, 0);
|
||||
m_cas->change_state(BIT(data, 1) ? CASSETTE_MOTOR_DISABLED : CASSETTE_MOTOR_ENABLED, CASSETTE_MASK_MOTOR);
|
||||
m_drq_source = (data >> 2) & 0x03;
|
||||
m_nvram_bank = (data >> 4) & 0x03;
|
||||
m_gfx_mode = BIT(data, 6);
|
||||
m_keyboard_enable = BIT(data, 7);
|
||||
|
||||
logerror("ppi_portc_w: cas_enabled: %d, cas_motor: %d, drq_source: %d, nvram_bank: %d, gfx_mode: %d, keyb_enable: %d\n",
|
||||
m_cas_enabled, BIT(data, 1), m_drq_source, m_nvram_bank, m_gfx_mode, m_keyboard_enable);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rc759_state::centronics_busy_w )
|
||||
{
|
||||
m_centronics_busy = state;
|
||||
m_pic->ir6_w(state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rc759_state::centronics_ack_w )
|
||||
{
|
||||
m_centronics_ack = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rc759_state::centronics_fault_w )
|
||||
{
|
||||
m_centronics_fault = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rc759_state::centronics_perror_w )
|
||||
{
|
||||
m_centronics_perror = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rc759_state::centronics_select_w )
|
||||
{
|
||||
m_centronics_select = state;
|
||||
}
|
||||
|
||||
READ8_MEMBER( rc759_state::centronics_data_r )
|
||||
{
|
||||
return m_centronics_data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( rc759_state::centronics_data_w )
|
||||
{
|
||||
m_centronics_data = data;
|
||||
|
||||
m_centronics->write_data0(BIT(data, 0));
|
||||
m_centronics->write_data1(BIT(data, 1));
|
||||
m_centronics->write_data2(BIT(data, 2));
|
||||
m_centronics->write_data3(BIT(data, 3));
|
||||
m_centronics->write_data4(BIT(data, 4));
|
||||
m_centronics->write_data5(BIT(data, 5));
|
||||
m_centronics->write_data6(BIT(data, 6));
|
||||
m_centronics->write_data7(BIT(data, 7));
|
||||
}
|
||||
|
||||
READ8_MEMBER( rc759_state::centronics_control_r )
|
||||
{
|
||||
UINT8 data = 0;
|
||||
|
||||
data |= m_centronics_busy << 0;
|
||||
data |= m_centronics_ack << 1;
|
||||
data |= m_centronics_fault << 2;
|
||||
data |= m_centronics_perror << 3;
|
||||
data |= m_centronics_select << 4;
|
||||
data |= !m_centronics_strobe << 5;
|
||||
data |= !m_centronics_init << 6;
|
||||
data |= !m_centronics_select_in << 7;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( rc759_state::centronics_control_w )
|
||||
{
|
||||
logerror("centronics_control_w: %02x\n", data);
|
||||
|
||||
m_centronics_strobe = BIT(data, 0);
|
||||
m_centronics_init = BIT(data, 2);
|
||||
m_centronics_select_in = BIT(data, 4);
|
||||
|
||||
m_centronics->write_strobe(m_centronics_strobe);
|
||||
m_centronics->write_autofd(BIT(data, 1));
|
||||
m_centronics->write_init(m_centronics_init);
|
||||
m_centronics->write_select_in(m_centronics_select_in);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( rc759_state::floppy_control_w )
|
||||
@ -187,6 +327,41 @@ WRITE8_MEMBER( rc759_state::floppy_release_w )
|
||||
// VIDEO EMULATION
|
||||
//**************************************************************************
|
||||
|
||||
I82730_UPDATE_ROW( rc759_state::txt_update_row )
|
||||
{
|
||||
for (int i = 0; i < x_count; i++)
|
||||
{
|
||||
UINT16 gfx = m_vram[(data[i] & 0x3ff) << 4 | lc];
|
||||
|
||||
// pretty crude detection if char sizes have been initialized, need something better
|
||||
if ((gfx & 0xff) == 0)
|
||||
continue;
|
||||
|
||||
// figure out char width
|
||||
int width;
|
||||
for (width = 0; width < 16; width++)
|
||||
if (BIT(gfx, width) == 0)
|
||||
break;
|
||||
|
||||
width = 15 - width;
|
||||
|
||||
for (int p = 0; p < width; p++)
|
||||
bitmap.pix32(y, i * width + p) = BIT(gfx, 15 - p) ? rgb_t::white : rgb_t::black;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( rc759_state::txt_ca_w )
|
||||
{
|
||||
m_txt->ca_w(1);
|
||||
m_txt->ca_w(0);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER( rc759_state::txt_irst_w )
|
||||
{
|
||||
m_txt->irst_w(1);
|
||||
m_txt->irst_w(0);
|
||||
}
|
||||
|
||||
READ8_MEMBER( rc759_state::palette_r )
|
||||
{
|
||||
logerror("palette_r(%02x)\n", offset);
|
||||
@ -200,10 +375,9 @@ WRITE8_MEMBER( rc759_state::palette_w )
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACHINE EMULATION
|
||||
// SOUND/RTC
|
||||
//**************************************************************************
|
||||
|
||||
// pic ir3 rtc
|
||||
READ8_MEMBER( rc759_state::rtc_r )
|
||||
{
|
||||
logerror("rtc_r(%02x)\n", offset);
|
||||
@ -215,16 +389,54 @@ WRITE8_MEMBER( rc759_state::rtc_w )
|
||||
logerror("rtc_w(%02x): %02x\n", offset, data);
|
||||
}
|
||||
|
||||
// 256x4 nvram is bank-switched using the ppi port c, bit 4 and 5
|
||||
|
||||
//**************************************************************************
|
||||
// MACHINE EMULATION
|
||||
//**************************************************************************
|
||||
|
||||
WRITE_LINE_MEMBER( rc759_state::i186_timer0_w )
|
||||
{
|
||||
if (m_cas_enabled)
|
||||
{
|
||||
m_cas_data = state;
|
||||
m_cas->output(state ? -1.0 : 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( rc759_state::i186_timer1_w )
|
||||
{
|
||||
m_speaker->level_w(state);
|
||||
}
|
||||
|
||||
// 256x4 nvram is bank-switched using ppi port c, bit 4 and 5
|
||||
void rc759_state::nvram_init(nvram_device &nvram, void *data, size_t size)
|
||||
{
|
||||
memset(data, 0x00, size);
|
||||
memset(data, 0xaa, 1);
|
||||
}
|
||||
|
||||
READ8_MEMBER( rc759_state::nvram_r )
|
||||
{
|
||||
logerror("nvram_r(%02x)\n", offset);
|
||||
return 0xff;
|
||||
offs_t addr = (m_nvram_bank << 6) | offset;
|
||||
|
||||
logerror("nvram_r(%02x)\n", addr);
|
||||
|
||||
if (addr & 1)
|
||||
return (m_nvram_mem[addr >> 1] & 0xf0) >> 4;
|
||||
else
|
||||
return (m_nvram_mem[addr >> 1] & 0x0f) >> 0;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( rc759_state::nvram_w )
|
||||
{
|
||||
logerror("nvram_w(%02x): %02x\n", offset, data);
|
||||
offs_t addr = (m_nvram_bank << 6) | offset;
|
||||
|
||||
logerror("nvram_w(%02x): %02x\n", addr, data);
|
||||
|
||||
if (addr & 1)
|
||||
m_nvram_mem[addr >> 1] = ((data << 4) & 0xf0) | (m_nvram_mem[addr >> 1] & 0x0f);
|
||||
else
|
||||
m_nvram_mem[addr >> 1] = (m_nvram_mem[addr >> 1] & 0xf0) | (data & 0x0f);
|
||||
}
|
||||
|
||||
READ8_MEMBER( rc759_state::irq_callback )
|
||||
@ -234,6 +446,8 @@ READ8_MEMBER( rc759_state::irq_callback )
|
||||
|
||||
void rc759_state::machine_start()
|
||||
{
|
||||
m_nvram_mem.resize(256 / 2);
|
||||
m_nvram->set_base(&m_nvram_mem[0], 256 / 2);
|
||||
}
|
||||
|
||||
void rc759_state::machine_reset()
|
||||
@ -253,33 +467,50 @@ ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( rc759_io, AS_IO, 16, rc759_state )
|
||||
ADDRESS_MAP_UNMAP_HIGH
|
||||
AM_RANGE(0x000, 0x003) AM_DEVREADWRITE8("pic", pic8259_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x000, 0x003) AM_MIRROR(0x0c) AM_DEVREADWRITE8("pic", pic8259_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x020, 0x021) AM_READ8(keyboard_r, 0x00ff)
|
||||
AM_RANGE(0x050, 0x05f) AM_READWRITE8(rtc_r, rtc_w, 0x00ff) // and sound
|
||||
// AM_RANGE(0x060, 0x06f) AM_WRITE8(crt_control_w, 0x00ff)
|
||||
AM_RANGE(0x070, 0x077) AM_DEVREADWRITE8("ppi", i8255_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x056, 0x057) AM_NOP // in reality, access to sound and rtc is a bit more involved
|
||||
AM_RANGE(0x05a, 0x05b) AM_DEVWRITE8("snd", sn76489a_device, write, 0x00ff)
|
||||
AM_RANGE(0x05c, 0x05d) AM_READWRITE8(rtc_r, rtc_w, 0x00ff)
|
||||
// AM_RANGE(0x060, 0x06f) AM_WRITE8(crt_control_w, 0x00ff)
|
||||
AM_RANGE(0x070, 0x077) AM_MIRROR(0x08) AM_DEVREADWRITE8("ppi", i8255_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x080, 0x0ff) AM_READWRITE8(nvram_r, nvram_w, 0x00ff)
|
||||
// AM_RANGE(0x100, 0x101) net
|
||||
AM_RANGE(0x180, 0x1bf) AM_READWRITE8(palette_r, palette_w, 0x00ff)
|
||||
// AM_RANGE(0x230, 0x231) crt reset
|
||||
// AM_RANGE(0x240, 0x241) crt ch. att.
|
||||
// AM_RANGE(0x250, 0x251) local printer data (centronics)
|
||||
// AM_RANGE(0x260, 0x261) local printer control (centronics)
|
||||
AM_RANGE(0x230, 0x231) AM_WRITE(txt_irst_w)
|
||||
AM_RANGE(0x240, 0x241) AM_WRITE(txt_ca_w)
|
||||
AM_RANGE(0x250, 0x251) AM_READWRITE8(centronics_data_r, centronics_data_w, 0x00ff)
|
||||
AM_RANGE(0x260, 0x261) AM_READWRITE8(centronics_control_r, centronics_control_w, 0x00ff)
|
||||
AM_RANGE(0x280, 0x287) AM_DEVREADWRITE8("fdc", wd2797_t, read, write, 0x00ff)
|
||||
AM_RANGE(0x288, 0x289) AM_WRITE8(floppy_control_w, 0x00ff)
|
||||
// AM_RANGE(0x28a, 0x28b) external printer data
|
||||
// AM_RANGE(0x28d, 0x28d) external printer control
|
||||
AM_RANGE(0x28e, 0x28f) AM_READWRITE8(floppy_ack_r, floppy_reserve_w, 0x00ff)
|
||||
AM_RANGE(0x290, 0x291) AM_WRITE8(floppy_release_w, 0x00ff)
|
||||
// AM_RANGE(0x292, 0x293) AM_READWRITE8(printer_ack_r, printer_reserve_w, 0x00ff)
|
||||
// AM_RANGE(0x294, 0x295) AM_WRITE8(printer_release_w, 0x00ff)
|
||||
// AM_RANGE(0x300, 0x30f) isbx1
|
||||
// AM_RANGE(0x310, 0x31f) isbx2
|
||||
// AM_RANGE(0x320, 0x321) isbx dma ack
|
||||
// AM_RANGE(0x330, 0x331) isbx tc
|
||||
// AM_RANGE(0x292, 0x293) AM_READWRITE8(printer_ack_r, printer_reserve_w, 0x00ff)
|
||||
// AM_RANGE(0x294, 0x295) AM_WRITE8(printer_release_w, 0x00ff)
|
||||
AM_RANGE(0x300, 0x30f) AM_DEVREADWRITE8("isbx", isbx_slot_device, mcs0_r, mcs0_w, 0x00ff)
|
||||
AM_RANGE(0x310, 0x31f) AM_DEVREADWRITE8("isbx", isbx_slot_device, mcs1_r, mcs1_w, 0x00ff)
|
||||
// AM_RANGE(0x320, 0x321) isbx dma ack
|
||||
// AM_RANGE(0x330, 0x331) isbx tc
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INPUTS
|
||||
//**************************************************************************
|
||||
|
||||
static INPUT_PORTS_START( rc759 )
|
||||
PORT_START("config")
|
||||
PORT_CONFNAME(0x20, 0x00, "Monitor Type")
|
||||
PORT_CONFSETTING(0x00, "Color")
|
||||
PORT_CONFSETTING(0x20, "Monochrome")
|
||||
PORT_CONFNAME(0x40, 0x00, "Monitor Frequency")
|
||||
PORT_CONFSETTING(0x00, "15 kHz")
|
||||
PORT_CONFSETTING(0x40, "22 kHz")
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MACHINE DRIVERS
|
||||
//**************************************************************************
|
||||
@ -293,28 +524,72 @@ static MACHINE_CONFIG_START( rc759, rc759_state )
|
||||
MCFG_CPU_PROGRAM_MAP(rc759_map)
|
||||
MCFG_CPU_IO_MAP(rc759_io)
|
||||
MCFG_80186_IRQ_SLAVE_ACK(READ8(rc759_state, irq_callback))
|
||||
MCFG_80186_TMROUT0_HANDLER(WRITELINE(rc759_state, i186_timer0_w))
|
||||
MCFG_80186_TMROUT1_HANDLER(WRITELINE(rc759_state, i186_timer1_w))
|
||||
|
||||
// interrupt controller
|
||||
MCFG_PIC8259_ADD("pic", DEVWRITELINE("maincpu", i80186_cpu_device, int0_w), VCC, NULL)
|
||||
|
||||
// nvram
|
||||
MCFG_NVRAM_ADD_CUSTOM_DRIVER("nvram", rc759_state, nvram_init)
|
||||
|
||||
// ppi
|
||||
MCFG_DEVICE_ADD("ppi", I8255, 0)
|
||||
MCFG_I8255_IN_PORTA_CB(READ8(rc759_state, ppi_porta_r))
|
||||
MCFG_I8255_IN_PORTB_CB(READ8(rc759_state, ppi_portb_r))
|
||||
MCFG_I8255_OUT_PORTC_CB(WRITE8(rc759_state, ppi_portc_w))
|
||||
|
||||
// floppy disk controller
|
||||
MCFG_WD2797_ADD("fdc", 1000000)
|
||||
MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("pic", pic8259_device, ir0_w))
|
||||
MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, drq1_w))
|
||||
// rtc
|
||||
MCFG_DEVICE_ADD("rtc", MM58167, XTAL_32_768kHz)
|
||||
MCFG_MM58167_IRQ_CALLBACK(DEVWRITELINE("pic", pic8259_device, ir3_w))
|
||||
|
||||
// floppy drives
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:0", rc759_floppies, "hd", floppy_image_device::default_floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:1", rc759_floppies, "hd", floppy_image_device::default_floppy_formats)
|
||||
// video
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_RAW_PARAMS(1250000 * 16, 896, 96, 816, 377, 4, 364) // 22 kHz setting
|
||||
MCFG_SCREEN_UPDATE_DEVICE("txt", i82730_device, screen_update)
|
||||
|
||||
MCFG_I82730_ADD("txt", "maincpu", 1250000)
|
||||
MCFG_VIDEO_SET_SCREEN("screen")
|
||||
MCFG_I82730_UPDATE_ROW_CB(rc759_state, txt_update_row)
|
||||
MCFG_I82730_SINT_HANDLER(DEVWRITELINE("pic", pic8259_device, ir4_w))
|
||||
|
||||
// keyboard
|
||||
MCFG_DEVICE_ADD("keyb", GENERIC_KEYBOARD, 0)
|
||||
MCFG_GENERIC_KEYBOARD_CB(WRITE8(rc759_state, keyb_put))
|
||||
|
||||
// cassette
|
||||
MCFG_CASSETTE_ADD("cas")
|
||||
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_PLAY | CASSETTE_MOTOR_DISABLED | CASSETTE_SPEAKER_MUTED)
|
||||
|
||||
// sound
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50)
|
||||
MCFG_SOUND_ADD("snd", SN76489A, XTAL_20MHz / 10)
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
|
||||
// internal centronics
|
||||
MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer")
|
||||
MCFG_CENTRONICS_BUSY_HANDLER(WRITELINE(rc759_state, centronics_busy_w))
|
||||
MCFG_CENTRONICS_ACK_HANDLER(WRITELINE(rc759_state, centronics_ack_w))
|
||||
MCFG_CENTRONICS_FAULT_HANDLER(WRITELINE(rc759_state, centronics_fault_w))
|
||||
MCFG_CENTRONICS_PERROR_HANDLER(WRITELINE(rc759_state, centronics_perror_w))
|
||||
MCFG_CENTRONICS_SELECT_HANDLER(WRITELINE(rc759_state, centronics_select_w))
|
||||
|
||||
// isbx slot
|
||||
MCFG_ISBX_SLOT_ADD("isbx", 0, isbx_cards, NULL)
|
||||
MCFG_ISBX_SLOT_MINTR0_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, int1_w))
|
||||
MCFG_ISBX_SLOT_MINTR1_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, int3_w))
|
||||
MCFG_ISBX_SLOT_MDRQT_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, drq0_w))
|
||||
|
||||
// floppy disk controller
|
||||
MCFG_WD2797_ADD("fdc", 1000000)
|
||||
// MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("pic", pic8259_device, ir0_w))
|
||||
// MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, drq1_w))
|
||||
|
||||
// floppy drives
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:0", rc759_floppies, "hd", floppy_image_device::default_floppy_formats)
|
||||
MCFG_FLOPPY_DRIVE_ADD("fdc:1", rc759_floppies, "hd", floppy_image_device::default_floppy_formats)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
@ -339,4 +614,4 @@ ROM_END
|
||||
// SYSTEM DRIVERS
|
||||
//**************************************************************************
|
||||
|
||||
COMP( 1984, rc759, 0, 0, rc759, 0, driver_device, 0, "Regnecentralen", "RC759", GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||
COMP( 1984, rc759, 0, 0, rc759, rc759, driver_device, 0, "Regnecentralen", "RC759 Piccoline", GAME_NOT_WORKING | GAME_NO_SOUND )
|
||||
|
Loading…
Reference in New Issue
Block a user