t4426 cart: added 14411 BRG, 6850 acia as a second rs232 port and fixed banking

This commit is contained in:
Joakim Larsson Edstrom 2017-09-26 01:06:33 +02:00
parent 995a86d58b
commit 08884304c8

View File

@ -42,26 +42,20 @@
#include "emu.h"
#include "cococart.h"
#include "machine/6850acia.h"
#include "bus/rs232/rs232.h"
#include "machine/mc14411.h"
#include "machine/6821pia.h"
//#define LOG_GENERAL (1U << 0)
#define LOG_SETUP (1U << 1)
#define LOG_PIA (1U << 2)
#define LOG_GENERAL 0x01
#define LOG_SETUP 0x02
#define LOG_PRINTF 0x04
#define LOG_PIA 0x08
//#define VERBOSE (LOG_PIA | LOG_GENERAL | LOG_SETUP)
//#define LOG_OUTPUT_FUNC std::cout
#include "logmacro.h"
#define VERBOSE 0 //(LOG_PIA | LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
#define LOGPIA(...) LOGMASK(LOG_PIA, __VA_ARGS__)
#if VERBOSE & LOG_PRINTF
#define logerror printf
#endif
#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)
#define LOGPIA(...) LOGMASKED(LOG_PIA, __VA_ARGS__)
#ifdef _MSC_VER
#define FUNCNAME __func__
@ -73,10 +67,15 @@
CONSTANTS
***************************************************************************/
#define UART_TAG "acia"
#define PIA_TAG "pia"
#define CARTSLOT_TAG "t4426"
#define CART_AUTOSTART_TAG "cart_autostart"
#define UART_TAG "acia"
#define SERIAL_TAG "ser2" // Labled "Ser.I/O2 RC 232C" on the back of the case
#define BRG_TAG "brg"
#define SERIAL_BRF "serial_brf"
#define SERIAL_BAUD "serial_baud"
#define PIA_TAG "pia"
#define CARTSLOT_TAG "t4426"
#define CARTBANK_TAG "t4426_banks"
#define CART_AUTOSTART_TAG "cart_autostart"
//**************************************************************************
// TYPE DEFINITIONS
@ -84,8 +83,6 @@
namespace
{
// ======================> coco_t4426_device
class coco_t4426_device :
public device_t,
public device_cococart_interface
@ -102,6 +99,17 @@ namespace
virtual uint8_t* get_cart_base() override;
DECLARE_WRITE8_MEMBER(pia_A_w);
// Clocks TODO: Validate on PCB what lines are used
void write_acia_clocks(int id, int state);
DECLARE_WRITE_LINE_MEMBER (write_f1_clock){ write_acia_clocks(mc14411_device::TIMER_F1, state); }
DECLARE_WRITE_LINE_MEMBER (write_f3_clock){ write_acia_clocks(mc14411_device::TIMER_F3, state); }
DECLARE_WRITE_LINE_MEMBER (write_f5_clock){ write_acia_clocks(mc14411_device::TIMER_F5, state); }
DECLARE_WRITE_LINE_MEMBER (write_f7_clock){ write_acia_clocks(mc14411_device::TIMER_F7, state); }
DECLARE_WRITE_LINE_MEMBER (write_f8_clock){ write_acia_clocks(mc14411_device::TIMER_F8, state); }
DECLARE_WRITE_LINE_MEMBER (write_f9_clock){ write_acia_clocks(mc14411_device::TIMER_F9, state); }
DECLARE_WRITE_LINE_MEMBER (write_f11_clock){ write_acia_clocks(mc14411_device::TIMER_F11, state); }
DECLARE_WRITE_LINE_MEMBER (write_f13_clock){ write_acia_clocks(mc14411_device::TIMER_F13, state); }
DECLARE_WRITE_LINE_MEMBER (write_f15_clock){ write_acia_clocks(mc14411_device::TIMER_F15, state); }
protected:
coco_t4426_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@ -121,6 +129,11 @@ namespace
// internal state
required_device<acia6850_device> m_uart;
required_device<pia6821_device> m_pia;
required_device<mc14411_device> m_brg;
required_ioport m_serial_baud;
void set_bank();
};
};
@ -130,33 +143,50 @@ namespace
***************************************************************************/
MACHINE_CONFIG_MEMBER(coco_t4426_device::device_add_mconfig)
MCFG_DEVICE_ADD(UART_TAG, ACIA6850, 0) // TODO: Figure out address mapping for ACIA
MCFG_DEVICE_ADD(PIA_TAG, PIA6821, 0)
MCFG_PIA_WRITEPA_HANDLER(WRITE8(coco_t4426_device, pia_A_w))
MCFG_DEVICE_ADD(UART_TAG, ACIA6850, 0) // TODO: Figure out address mapping for ACIA
MCFG_ACIA6850_TXD_HANDLER (DEVWRITELINE (SERIAL_TAG, rs232_port_device, write_txd))
MCFG_ACIA6850_RTS_HANDLER (DEVWRITELINE (SERIAL_TAG, rs232_port_device, write_rts))
MCFG_RS232_PORT_ADD (SERIAL_TAG, default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER (DEVWRITELINE (UART_TAG, acia6850_device, write_rxd))
MCFG_RS232_CTS_HANDLER (DEVWRITELINE (UART_TAG, acia6850_device, write_cts))
/* Bit Rate Generator */
MCFG_MC14411_ADD (BRG_TAG, XTAL_1_8432MHz)
MCFG_MC14411_F1_CB(WRITELINE (coco_t4426_device, write_f1_clock))
MCFG_MC14411_F3_CB(WRITELINE (coco_t4426_device, write_f3_clock))
MCFG_MC14411_F5_CB(WRITELINE (coco_t4426_device, write_f5_clock))
MCFG_MC14411_F7_CB(WRITELINE (coco_t4426_device, write_f7_clock))
MCFG_MC14411_F8_CB(WRITELINE (coco_t4426_device, write_f8_clock))
MCFG_MC14411_F9_CB(WRITELINE (coco_t4426_device, write_f9_clock))
MCFG_MC14411_F11_CB(WRITELINE (coco_t4426_device, write_f11_clock))
MCFG_MC14411_F13_CB(WRITELINE (coco_t4426_device, write_f13_clock))
MCFG_MC14411_F15_CB(WRITELINE (coco_t4426_device, write_f15_clock))
MACHINE_CONFIG_END
ROM_START( coco_t4426 )
ROM_REGION(0x1a000, CARTSLOT_TAG, ROMREGION_ERASE00)
// 8 banked ROM:s TODO: Add the banking and the other ROM:s
ROM_LOAD("tercoED4426-0-8549-5.3.bin", 0x00000, 0x2000, CRC(45665428) SHA1(ff49a79275772c4c4ab1ae29db662c9b10a744a7))
ROM_LOAD("tercoED4426-1-8549-5.3.bin", 0x03000, 0x2000, CRC(44baba33) SHA1(01cee1b208c158e598e7ecd2189b5e0ffa7f3ab9))
ROM_LOAD("tercoPD4426-2-8632-6.4.bin", 0x06000, 0x2000, CRC(258e443a) SHA1(9d8901f3e70ae4f8526dde1b5208b22f066f801f))
ROM_LOAD("tercoPD4426-3-8638-6.4.bin", 0x09000, 0x2000, CRC(640d1de4) SHA1(5ae7427cb5729fd3920361855d954ea1f97f6ae5))
ROM_LOAD("tercoCA4426-4-8549-3.4.bin", 0x0c000, 0x2000, CRC(df18397b) SHA1(2f9de210c039619c649be223c37a4eff873fa600))
ROM_LOAD("tercoCA4426-5-8549-3.4.bin", 0x0f000, 0x2000, CRC(3fcdf92e) SHA1(ec1589f8d62701ca3faf2a85a57ab2e1f61d2137))
ROM_LOAD("tercoCA4426-6-8549-3.4.bin", 0x13000, 0x2000, CRC(27652ccf) SHA1(529a6f736666ae6660483e547d076725606b1c1d))
ROM_LOAD("tercoCA4426-7-8549-3.4.bin", 0x16000, 0x2000, CRC(f6640569) SHA1(03f70dcc5f7ab60cd908427d45ebd85b6f464b93))
// Part of this region is filled by set_bank
ROM_REGION(0x8000, CARTSLOT_TAG, ROMREGION_ERASE00)
// Main cartridge ROM
ROM_LOAD("tercoPMOS4426-8549-4.31.bin", 0x2000, 0x1000, CRC(bc65c45c) SHA1(e50cfd1d61e29fe05eb795d8bf6303e7b91ed8e5))
// Interleaved copies for the fixed ROM for banking to work (nw yet though)
ROM_RELOAD(0x05000,0x1000)
ROM_RELOAD(0x08000,0x1000)
ROM_RELOAD(0x0b000,0x1000)
ROM_RELOAD(0x0e000,0x1000)
ROM_RELOAD(0x12000,0x1000)
ROM_RELOAD(0x15000,0x1000)
ROM_RELOAD(0x18000,0x1000)
ROM_LOAD("tercoPMOS4426-8549-4.31.bin", 0x6000, 0x1000, CRC(bc65c45c) SHA1(e50cfd1d61e29fe05eb795d8bf6303e7b91ed8e5))
ROM_RELOAD(0x07000,0x1000) // Mirrored
// this region is loaded from separate ROM images
ROM_REGION(0x1a000, CARTBANK_TAG, ROMREGION_ERASE00)
// 8 banked ROM:s
ROM_LOAD("tercoED4426-0-8549-5.3.bin", 0x0000, 0x2000, CRC(45665428) SHA1(ff49a79275772c4c4ab1ae29db662c9b10a744a7))
ROM_LOAD("tercoED4426-1-8549-5.3.bin", 0x2000, 0x2000, CRC(44baba33) SHA1(01cee1b208c158e598e7ecd2189b5e0ffa7f3ab9))
ROM_LOAD("tercoPD4426-2-8632-6.4.bin", 0x4000, 0x2000, CRC(258e443a) SHA1(9d8901f3e70ae4f8526dde1b5208b22f066f801f))
ROM_LOAD("tercoPD4426-3-8638-6.4.bin", 0x6000, 0x2000, CRC(640d1de4) SHA1(5ae7427cb5729fd3920361855d954ea1f97f6ae5))
ROM_LOAD("tercoCA4426-4-8549-3.4.bin", 0x8000, 0x2000, CRC(df18397b) SHA1(2f9de210c039619c649be223c37a4eff873fa600))
ROM_LOAD("tercoCA4426-5-8549-3.4.bin", 0xa000, 0x2000, CRC(3fcdf92e) SHA1(ec1589f8d62701ca3faf2a85a57ab2e1f61d2137))
ROM_LOAD("tercoCA4426-6-8549-3.4.bin", 0xc000, 0x2000, CRC(27652ccf) SHA1(529a6f736666ae6660483e547d076725606b1c1d))
ROM_LOAD("tercoCA4426-7-8549-3.4.bin", 0xe000, 0x2000, CRC(f6640569) SHA1(03f70dcc5f7ab60cd908427d45ebd85b6f464b93))
ROM_END
//-------------------------------------------------
@ -168,6 +198,21 @@ static INPUT_PORTS_START( coco_cart_autostart )
PORT_CONFNAME( 0x01, 0x01, "Cart Auto-Start" )
PORT_CONFSETTING( 0x00, DEF_STR( Off ))
PORT_CONFSETTING( 0x01, DEF_STR( On ))
PORT_START(SERIAL_BAUD)
PORT_CONFNAME(0x0F , 0x00 , "Ser. I/O2 RC 232C - Baud Rate") // Typo on real hardware!
PORT_CONFSETTING(mc14411_device::TIMER_F1, "9600") // RSA=RSB=1: X1
PORT_CONFSETTING(mc14411_device::TIMER_F2, "7200")
PORT_CONFSETTING(mc14411_device::TIMER_F3, "4800")
PORT_CONFSETTING(mc14411_device::TIMER_F4, "3600")
PORT_CONFSETTING(mc14411_device::TIMER_F5, "2400")
PORT_CONFSETTING(mc14411_device::TIMER_F6, "1800")
PORT_CONFSETTING(mc14411_device::TIMER_F7, "1200")
PORT_CONFSETTING(mc14411_device::TIMER_F8, "600")
PORT_CONFSETTING(mc14411_device::TIMER_F9, "300")
PORT_CONFSETTING(mc14411_device::TIMER_F10, "200")
PORT_CONFSETTING(mc14411_device::TIMER_F11, "150")
PORT_CONFSETTING(mc14411_device::TIMER_F13, "110")
INPUT_PORTS_END
//**************************************************************************
@ -192,6 +237,8 @@ coco_t4426_device::coco_t4426_device(const machine_config &mconfig, device_type
, m_autostart(*this, CART_AUTOSTART_TAG)
, m_uart(*this, UART_TAG)
, m_pia(*this, PIA_TAG)
, m_brg(*this, BRG_TAG)
, m_serial_baud(*this, SERIAL_BAUD)
{
}
@ -240,11 +287,34 @@ void coco_t4426_device::device_reset()
LOG("%s()\n", FUNCNAME );
auto cart_line = line_value::Q;
set_line_value(line::CART, cart_line);
set_bank();
// Set up the BRG divider statically to X1
m_brg->rsa_w( ASSERT_LINE );
m_brg->rsb_w( ASSERT_LINE );
// Disable all configured timers, only enabling the used ones
m_brg->timer_disable_all();
m_brg->timer_enable((mc14411_device::timer_id) m_serial_baud->read(), true);
}
/*----------------------------------------------------
* Serial port clock sources driven by the selected
* output of the MC14411
----------------------------------------------------*/
void coco_t4426_device::write_acia_clocks(int id, int state)
{
if (id == m_serial_baud->read())
{
m_uart->write_txc(state);
m_uart->write_rxc(state);
}
}
/*-------------------------------------------------
scs_read
The 4426 cartridge PIA is located at ff44-ff47
scs_read custom devices
PIA is located at ff40-ff47
ACIA is located at ff48-ff4F
-------------------------------------------------*/
READ8_MEMBER(coco_t4426_device::scs_read)
@ -253,16 +323,33 @@ READ8_MEMBER(coco_t4426_device::scs_read)
LOG("%s", FUNCNAME);
if ((offset >= 0x04) && (offset <= 0x07))
result = m_pia->read(space, offset - 0x04);
if ((offset >= 0x00) && (offset <= 0x07))
{
LOG(" PIA");
result = m_pia->read(space, offset & 3);
LOG(" - Offs:%04x Data:%02x\n", offset - 0x04, result);
}
else if ((offset >= 0x08) && (offset <= 0x0f))
{
LOG(" ACIA");
if (offset & 1)
result = m_uart->status_r(space, offset & 1);
else
result = m_uart->data_r(space, offset & 1);
LOG(" - Offs:%04x Data:%02x\n", offset - 0x04, result);
}
else
{
LOG(" Unknown Device! Offs:%04x\n", offset);
}
LOG(" - Offs:%04x Data:%02x\n", offset, result);
return result;
}
/*-------------------------------------------------
scs_write
The 4426 cartridge PIA is located at ff44-ff47
scs_write - custom devices
PIA is located at ff40-ff47
ACIA is located at ff48-ff4F
-------------------------------------------------*/
WRITE8_MEMBER(coco_t4426_device::scs_write)
@ -270,8 +357,24 @@ WRITE8_MEMBER(coco_t4426_device::scs_write)
LOG("%s(%02x)\n", FUNCNAME, data);
LOGSETUP(" * Offs:%02x <- %02x\n", offset, data);
if ((offset >= 0x04) && (offset <= 0x07))
m_pia->write(space, offset - 0x04, data);
if ((offset >= 0x00) && (offset <= 0x07))
{
LOG(" PIA ");
m_pia->write(space, offset & 3, data);
}
else if ((offset >= 0x08) && (offset <= 0x0f))
{
LOG(" ACIA");
if (offset & 1)
m_uart->control_w(space, offset & 1, data);
else
m_uart->data_w(space, offset & 1, data);
LOG(" - Offs:%04x Data:%02x\n", offset & 1, data);
}
else
{
LOG(" Unknown device");
}
}
/*----------------------------------------------------
@ -295,7 +398,35 @@ WRITE8_MEMBER( coco_t4426_device::pia_A_w )
{
LOGPIA("%s(%02x)\n", FUNCNAME, data);
m_select = data;
cart_base_changed();
set_bank();
//cart_base_changed();
}
void coco_t4426_device::set_bank()
{
uint8_t *cartbase = memregion(CARTSLOT_TAG)->base();
uint8_t *bankbase = memregion(CARTBANK_TAG)->base();
switch (m_select)
{
case 0:
case ROM0:memcpy(cartbase + 0x4000, bankbase + 0x0000, 0x2000); break;
case ROM1:memcpy(cartbase + 0x4000, bankbase + 0x2000, 0x2000); break;
case ROM2:memcpy(cartbase + 0x4000, bankbase + 0x4000, 0x2000); break;
case ROM3:memcpy(cartbase + 0x4000, bankbase + 0x6000, 0x2000); break;
case ROM4:memcpy(cartbase + 0x4000, bankbase + 0x8000, 0x2000); break;
case ROM5:memcpy(cartbase + 0x4000, bankbase + 0xa000, 0x2000); break;
case ROM6:memcpy(cartbase + 0x4000, bankbase + 0xc000, 0x2000); break;
case ROM7:memcpy(cartbase + 0x4000, bankbase + 0xe000, 0x2000); break;
}
#if 0 // Print the beginning of the selected ROM bank, seems to be correct but is not mapped in correctly via coco12.cpp m_sam->read yet
printf("%02x\n", m_select);
for (int i = 0; i < 48; i++) printf("%02x ", *((uint8_t *)(cartbase + 0x4000 + i)));
printf("\n");
for (int i = 0; i < 48; i++) printf("'%c'", *((uint8_t *)(cartbase + 0x4000 + i)));
printf("\n");
#endif
}
/*-------------------------------------------------
@ -305,28 +436,5 @@ WRITE8_MEMBER( coco_t4426_device::pia_A_w )
uint8_t* coco_t4426_device::get_cart_base()
{
LOG("%s - m_select %02x -> %02x\n", FUNCNAME, m_select, ~m_select & 0xff );
uint8_t *base = memregion(CARTSLOT_TAG)->base();
switch (m_select)
{
case 0:
case ROM0: base = (uint8_t *) (base + 0x00000); break;
case ROM1: base = (uint8_t *) (base + 0x03000); break;
case ROM2: base = (uint8_t *) (base + 0x06000); break;
case ROM3: base = (uint8_t *) (base + 0x09000); break;
case ROM4: base = (uint8_t *) (base + 0x0c000); break;
case ROM5: base = (uint8_t *) (base + 0x0f000); break;
case ROM6: base = (uint8_t *) (base + 0x13000); break;
case ROM7: base = (uint8_t *) (base + 0x16000); break;
}
#if 0 // Print the beginning of the selected ROM bank, seems to be correct but is not mapped in correctly via coco12.cpp m_sam->read yet
printf("\n");
for (int i = 0; i < 48; i++) printf("%02x ", *((uint8_t *)(base + i)));
printf("\n");
for (int i = 0; i < 48; i++) printf("'%c'", *((uint8_t *)(base + i)));
printf("\n");
#endif
return base;
return memregion(CARTSLOT_TAG)->base() + 0x4000;
}