mirror of
https://github.com/holub/mame
synced 2025-06-23 12:58:37 +03:00
-cmi01a: Checkpoint so Phil can have a look, nw
This commit is contained in:
parent
2a71385020
commit
cbbde1da74
@ -14,9 +14,77 @@
|
||||
|
||||
#define MASTER_OSCILLATOR XTAL(34'291'712)
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(CMI01A_CHANNEL_CARD, cmi01a_device, "cmi_01a", "Fairlight CMI-01A Channel Card")
|
||||
|
||||
|
||||
const uint8_t cmi01a_device::s_7497_rate_table[64][64] =
|
||||
{
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1},
|
||||
{1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,1},
|
||||
{1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1},
|
||||
{1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1},
|
||||
{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1},
|
||||
{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
|
||||
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}
|
||||
};
|
||||
|
||||
cmi01a_device::cmi01a_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, CMI01A_CHANNEL_CARD, tag, owner, clock)
|
||||
, device_sound_interface(mconfig, *this)
|
||||
@ -33,20 +101,26 @@ void cmi01a_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
PIA6821(config, m_pia[0], 0); // pia_cmi01a_1_config
|
||||
m_pia[0]->readcb1_handler().set(FUNC(cmi01a_device::tri_r));
|
||||
m_pia[0]->readpa_handler().set(FUNC(cmi01a_device::ws_dir_r));
|
||||
m_pia[0]->writepa_handler().set(FUNC(cmi01a_device::ws_dir_w));
|
||||
m_pia[0]->writepb_handler().set(FUNC(cmi01a_device::rp_w));
|
||||
m_pia[0]->ca2_handler().set(FUNC(cmi01a_device::pia_0_ca2_w));
|
||||
m_pia[0]->ca2_handler().set(FUNC(cmi01a_device::load_w));
|
||||
m_pia[0]->cb2_handler().set(FUNC(cmi01a_device::pia_0_cb2_w));
|
||||
m_pia[0]->irqa_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<0>));
|
||||
m_pia[0]->irqb_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<1>));
|
||||
//if (m_channel == 5) m_pia[0]->enable_logging();
|
||||
|
||||
PIA6821(config, m_pia[1], 0); // pia_cmi01a_2_config
|
||||
m_pia[1]->readca1_handler().set(FUNC(cmi01a_device::zx_r));
|
||||
m_pia[1]->readca2_handler().set(FUNC(cmi01a_device::eosi_r));
|
||||
m_pia[1]->readcb1_handler().set(FUNC(cmi01a_device::eosi_r));
|
||||
m_pia[1]->readpa_handler().set(FUNC(cmi01a_device::pia_1_a_r));
|
||||
m_pia[1]->writepa_handler().set(FUNC(cmi01a_device::pia_1_a_w));
|
||||
m_pia[1]->writepb_handler().set(FUNC(cmi01a_device::pia_1_b_w));
|
||||
m_pia[1]->ca2_handler().set(FUNC(cmi01a_device::eload_w));
|
||||
m_pia[1]->cb2_handler().set(FUNC(cmi01a_device::wpe_w));
|
||||
m_pia[1]->irqa_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<2>));
|
||||
m_pia[1]->irqb_handler().set(m_irq_merger, FUNC(input_merger_device::in_w<3>));
|
||||
//if (m_channel == 5) m_pia[1]->enable_logging();
|
||||
|
||||
PTM6840(config, m_ptm, DERIVED_CLOCK(1, 1)); // ptm_cmi01a_config
|
||||
m_ptm->o1_callback().set(FUNC(cmi01a_device::ptm_o1));
|
||||
@ -60,25 +134,28 @@ void cmi01a_device::device_add_mconfig(machine_config &config)
|
||||
|
||||
void cmi01a_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
if ((m_status & CHANNEL_STATUS_RUN) && m_vol_latch)
|
||||
if (m_run)
|
||||
{
|
||||
int length = samples;
|
||||
int mask = (m_status & CHANNEL_STATUS_LOAD) ? 0x7fff : 0x7f;
|
||||
int mask = m_load ? 0x7fff : 0x7f;
|
||||
int addr = m_segment_cnt;
|
||||
|
||||
uint8_t *wave_ptr = &m_wave_ram[m_segment_cnt & 0x3fff];
|
||||
stream_sample_t *buf = outputs[0];
|
||||
|
||||
while (length--)
|
||||
while (samples--)
|
||||
{
|
||||
*buf++ = wave_ptr[addr++ & 0x3fff] << 6;
|
||||
const uint8_t sample8 = wave_ptr[addr++ & 0x3fff];
|
||||
int32_t sample = (int32_t)(int8_t)(sample8 ^ 0x80) * m_env * m_vol_latch;
|
||||
if (m_channel == 5) printf("%08x:%02x:%02x:%02x", (uint32_t)sample, sample8, m_env, m_vol_latch);
|
||||
*buf++ = (int16_t)(sample >> 8);
|
||||
}
|
||||
if (m_channel == 5) printf("\n");
|
||||
|
||||
m_segment_cnt = (m_segment_cnt & ~mask) | addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(outputs[0], 0, samples);
|
||||
memset(outputs[0], 0, samples * sizeof(stream_sample_t));
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,6 +170,7 @@ void cmi01a_device::device_start()
|
||||
|
||||
m_zx_timer = timer_alloc(TIMER_ZX);
|
||||
m_eosi_timer = timer_alloc(TIMER_EOSI);
|
||||
m_bcas_timer = timer_alloc(TIMER_BCAS);
|
||||
|
||||
m_zx_timer->adjust(attotime::never);
|
||||
m_eosi_timer->adjust(attotime::never);
|
||||
@ -100,6 +178,8 @@ void cmi01a_device::device_start()
|
||||
m_stream = stream_alloc(0, 1, 44100);
|
||||
|
||||
m_ptm->set_external_clocks(clock() / 8, clock() / 4, clock() / 4);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void cmi01a_device::device_reset()
|
||||
@ -110,66 +190,151 @@ void cmi01a_device::device_reset()
|
||||
|
||||
m_segment_cnt = 0;
|
||||
m_new_addr = 0;
|
||||
m_env_dir_ctrl = 0;
|
||||
m_vol_latch = 0;
|
||||
m_flt_latch = 0;
|
||||
m_rp = 0;
|
||||
m_ws = 0;
|
||||
m_dir = 0;
|
||||
m_env = 0;
|
||||
m_pia0_cb2_state = 1;
|
||||
m_bcas_q1_ticks = 2;
|
||||
m_bcas_q1 = 0;
|
||||
m_bcas_q2_ticks = 4;
|
||||
m_bcas_q2 = 0;
|
||||
m_zx_flag = 0;
|
||||
|
||||
m_freq = 0.0;
|
||||
m_status = 0;
|
||||
|
||||
m_ptm_o1 = 0;
|
||||
m_ptm_o2 = 0;
|
||||
m_ptm_o3 = 0;
|
||||
|
||||
m_load = true;
|
||||
m_run = false;
|
||||
m_gzx = true;
|
||||
m_nwpe = true;
|
||||
m_tri = true;
|
||||
m_pia1_ca2 = false;
|
||||
|
||||
m_eclk = false;
|
||||
m_env_clk = false;
|
||||
m_ediv_out = true;
|
||||
m_ediv_rate = 3;
|
||||
m_ediv_count = 0;
|
||||
|
||||
m_pitch = 0;
|
||||
m_octave = 0;
|
||||
|
||||
m_zx_timer->adjust(attotime::never);
|
||||
m_eosi_timer->adjust(attotime::never);
|
||||
//m_bcas_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock()));
|
||||
m_bcas_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( cmi01a_device::pia_0_ca2_w )
|
||||
void cmi01a_device::pulse_zcint()
|
||||
{
|
||||
m_status &= ~CHANNEL_STATUS_LOAD;
|
||||
m_pia[0]->ca1_w(0);
|
||||
m_pia[0]->ca1_w(1);
|
||||
|
||||
if (!state)
|
||||
pulse_gzx();
|
||||
}
|
||||
|
||||
void cmi01a_device::pulse_gzx()
|
||||
{
|
||||
if (!m_pia1_ca2)
|
||||
{
|
||||
m_status |= CHANNEL_STATUS_LOAD;
|
||||
|
||||
m_segment_cnt = 0x4000 | ((m_pia[0]->a_output() & 0x7f) << 7);
|
||||
m_new_addr = 1;
|
||||
m_pia[1]->cb1_w(1);
|
||||
return;
|
||||
}
|
||||
|
||||
reset_waveform_segment();
|
||||
m_env = m_rp;
|
||||
m_env_dir = m_dir;
|
||||
}
|
||||
|
||||
void cmi01a_device::reset_waveform_segment()
|
||||
{
|
||||
m_segment_cnt &= 0x007f;
|
||||
m_segment_cnt = 0x4000 | (m_ws << 7);
|
||||
}
|
||||
|
||||
void cmi01a_device::load_w(int state)
|
||||
{
|
||||
const bool old_load = m_load;
|
||||
m_load = state ? false : true;
|
||||
|
||||
if (old_load != m_load)
|
||||
{
|
||||
check_segment_load();
|
||||
}
|
||||
}
|
||||
|
||||
void cmi01a_device::check_segment_load()
|
||||
{
|
||||
bool run_strobe = false;
|
||||
if (m_load != m_run)
|
||||
{
|
||||
run_strobe = true;
|
||||
m_segment_cnt &= ~0x7f;
|
||||
}
|
||||
|
||||
if (!run_strobe)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_nwpe)
|
||||
{
|
||||
reset_waveform_segment();
|
||||
}
|
||||
|
||||
if (m_channel == 5) LOG("CH%d beginning load with m_segment_cnt %04x\n", m_channel, m_segment_cnt);
|
||||
m_pia[1]->cb1_w(1);
|
||||
}
|
||||
|
||||
void cmi01a_device::pia_1_a_w(uint8_t data)
|
||||
{
|
||||
// top two
|
||||
m_pitch &= 0x0ff;
|
||||
m_pitch |= (data & 3) << 8;
|
||||
m_octave = (data >> 2) & 0x0f;
|
||||
}
|
||||
|
||||
uint8_t cmi01a_device::pia_1_a_r()
|
||||
{
|
||||
return ((m_pitch >> 8) & 3) | (m_octave << 2);
|
||||
}
|
||||
|
||||
void cmi01a_device::pia_1_b_w(uint8_t data)
|
||||
{
|
||||
m_pitch &= 0xf00;
|
||||
m_pitch |= data;
|
||||
}
|
||||
|
||||
void cmi01a_device::rp_w(uint8_t data)
|
||||
{
|
||||
m_rp = data;
|
||||
m_ediv_rate = ((m_rp >> 2) & 0x3c) | 0x03;
|
||||
if (m_channel == 5) LOG("CH%d: Initial ramp value: %02x, EDIV divider: %02x\n", m_channel, data, m_ediv_rate);
|
||||
}
|
||||
|
||||
void cmi01a_device::ws_dir_w(uint8_t data)
|
||||
{
|
||||
if (m_channel == 5) LOG("CH%d: WS/DIR write: %02x\n", m_channel, data);
|
||||
m_ws = data & 0x7f;
|
||||
m_dir = (data >> 7) & 1;
|
||||
}
|
||||
|
||||
uint8_t cmi01a_device::ws_dir_r()
|
||||
{
|
||||
return m_ws | (m_dir << 7);
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER( cmi01a_device::tri_r )
|
||||
{
|
||||
bool top_terminal_count = (m_dir == ENV_DIR_UP && m_rp == 0);
|
||||
bool bottom_terminal_count = (m_dir == ENV_DIR_DOWN && m_rp == 0xff);
|
||||
return (top_terminal_count || bottom_terminal_count) ? 0 : 1;
|
||||
const bool top_terminal_count = (m_env_dir == ENV_DIR_UP && m_env == 0xff);
|
||||
const bool bottom_terminal_count = (m_env_dir == ENV_DIR_DOWN && m_env == 0x00);
|
||||
const int state = (top_terminal_count || bottom_terminal_count) ? 1 : 0;
|
||||
if (m_channel == 5) LOG("CH%d: PIA0 CB1 Read (/TRI): %d\n", m_channel, state);
|
||||
return state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( cmi01a_device::cmi01a_irq )
|
||||
@ -187,14 +352,36 @@ void cmi01a_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
case TIMER_EOSI:
|
||||
eosi_timer_cb();
|
||||
break;
|
||||
case TIMER_BCAS:
|
||||
bcas_tick();
|
||||
}
|
||||
}
|
||||
|
||||
void cmi01a_device::reset_bcas_counter()
|
||||
{
|
||||
m_bcas_q1_ticks = 2;
|
||||
m_bcas_q1 = 0;
|
||||
m_bcas_q2_ticks = 4;
|
||||
m_bcas_q2 = 0;
|
||||
|
||||
m_ptm->set_clock(0, 0);
|
||||
m_ptm->set_clock(1, 0);
|
||||
m_ptm->set_clock(2, 0);
|
||||
}
|
||||
|
||||
void cmi01a_device::bcas_tick()
|
||||
{
|
||||
if (m_ptm_o1 != m_zx_ff)
|
||||
return;
|
||||
}
|
||||
|
||||
void cmi01a_device::eosi_timer_cb()
|
||||
{
|
||||
m_stream->update();
|
||||
m_segment_cnt &= ~0x4000;
|
||||
m_pia[1]->cb1_w(0);
|
||||
|
||||
// printf("End of sound\n");
|
||||
if (m_channel == 5) LOG("CH%d: End of sound\n", m_channel);
|
||||
}
|
||||
|
||||
void cmi01a_device::zx_timer_cb()
|
||||
@ -210,19 +397,71 @@ void cmi01a_device::zx_timer_cb()
|
||||
{
|
||||
// Pulse /ZCINT if the O1 output of the PTM has changed
|
||||
if (m_ptm_o1 != m_zx_ff)
|
||||
m_pia[0]->ca1_w(0);
|
||||
{
|
||||
reset_bcas_counter();
|
||||
pulse_zcint();
|
||||
}
|
||||
|
||||
m_zx_ff = m_ptm_o1;
|
||||
m_pia[0]->ca1_w(1);
|
||||
}
|
||||
|
||||
// Update ECLK
|
||||
bool eclk = (m_ptm_o2 && m_zx_ff) || (m_ptm_o3 && !m_zx_ff);
|
||||
set_eclk(eclk);
|
||||
update_eclk();
|
||||
}
|
||||
|
||||
void cmi01a_device::update_eclk()
|
||||
{
|
||||
bool eclk = (m_ptm_o2 && m_zx_ff) || (m_ptm_o3 && !m_zx_ff);
|
||||
if (m_channel == 5) logerror("CH%d: eclk = (%d && %d) || (%d && %d) = %d\n", m_channel, m_ptm_o2, m_zx_ff, m_ptm_o3, m_zx_ff ? 0 : 1, eclk ? 1 : 0);
|
||||
m_stream->update();
|
||||
set_eclk(eclk);
|
||||
}
|
||||
|
||||
void cmi01a_device::wpe_w(int state)
|
||||
{
|
||||
m_nwpe = state ? false : true;
|
||||
}
|
||||
|
||||
void cmi01a_device::eload_w(int state)
|
||||
{
|
||||
if (m_channel == 5) LOG("CH%d PIA1 CA2: %d\n", m_channel, state);
|
||||
m_pia1_ca2 = state;
|
||||
}
|
||||
|
||||
void cmi01a_device::clock_envelope()
|
||||
{
|
||||
m_stream->update();
|
||||
const bool old_tri = m_tri;
|
||||
if (m_env_dir == ENV_DIR_DOWN)
|
||||
{
|
||||
if (m_env > 0)
|
||||
{
|
||||
m_env--;
|
||||
m_ediv_rate = ((m_env >> 2) & 0x3c) | 0x03;
|
||||
if (m_channel == 5) LOG("CH%d, Clocking envelope down, new rp: %02x\n", m_channel, m_env);
|
||||
}
|
||||
m_tri = m_env == 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_env < 0xff)
|
||||
{
|
||||
m_env++;
|
||||
m_ediv_rate = ((~m_env >> 2) & 0x3c) | 0x03;
|
||||
if (m_channel == 5) LOG("CH%d, Clocking envelope up, new rp: %02x\n", m_channel, m_env);
|
||||
}
|
||||
m_tri = m_env == 0xff;
|
||||
}
|
||||
if (old_tri != m_tri)
|
||||
{
|
||||
m_pia[0]->cb1_w(m_tri ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
void cmi01a_device::tick_ediv()
|
||||
{
|
||||
if (m_channel == 5) logerror("CH%d ticking ediv, rate: %02x\n", m_channel, m_ediv_rate);
|
||||
m_ediv_out = s_7497_rate_table[m_ediv_rate][m_ediv_count];
|
||||
m_ediv_count = (m_ediv_count + 1) & 0x3f;
|
||||
}
|
||||
|
||||
void cmi01a_device::set_eclk(bool eclk)
|
||||
@ -233,7 +472,10 @@ void cmi01a_device::set_eclk(bool eclk)
|
||||
if (old_eclk == m_eclk)
|
||||
return;
|
||||
|
||||
tick_ediv();
|
||||
if (!old_eclk && m_eclk)
|
||||
{
|
||||
tick_ediv();
|
||||
}
|
||||
|
||||
// A B !(A && B) !A || !B
|
||||
// 0 0 1 1
|
||||
@ -241,48 +483,49 @@ void cmi01a_device::set_eclk(bool eclk)
|
||||
// 1 0 1 1
|
||||
// 1 1 0 0
|
||||
|
||||
//const bool load = (m_status & CHANNEL_STATUS_LOAD);
|
||||
//const bool a = !load || !eclk;
|
||||
//const bool b = load || m_ediv_out;
|
||||
const bool a = !m_load || !eclk;
|
||||
const bool b = m_load || !m_ediv_out;
|
||||
|
||||
//const bool div_clk = !a || !b;
|
||||
const bool old_env_clk = m_env_clk;
|
||||
m_env_clk = !a || !b;
|
||||
LOG("CH%d checking envelope: A: !!load(%d) || !eclk(%d) = %d\n", m_channel, m_load ? 0 : 1, eclk ? 0 : 1, a);
|
||||
LOG("CH%d checking envelope: B: !load(%d) || !eout(%d) = %d\n", m_channel, m_load ? 1 : 0, m_ediv_out ? 0 : 1, b);
|
||||
LOG("CH%d checking envelope: C: !%d || !%d = %d\n", m_channel, a ? 1 : 0, b ? 1 : 0, m_env_clk ? 1 : 0);
|
||||
if (!old_env_clk && m_env_clk)
|
||||
{
|
||||
clock_envelope();
|
||||
}
|
||||
}
|
||||
|
||||
void cmi01a_device::run_voice()
|
||||
{
|
||||
int val_a = m_pia[1]->a_output();
|
||||
int pitch = ((val_a & 3) << 8)
|
||||
| m_pia[1]->b_output();
|
||||
int o_val = (val_a >> 2) & 0xf;
|
||||
|
||||
LOG("CH%d running voice: PIA1 A output = %02x\n", m_channel, (uint8_t)val_a);
|
||||
LOG("CH%d running voice: Pitch = %04x\n", m_channel, (uint16_t)pitch);
|
||||
LOG("CH%d running voice: o_val = %x\n", m_channel, o_val);
|
||||
if (m_channel == 5) LOG("CH%d running voice: Pitch = %04x\n", m_channel, (uint16_t)m_pitch);
|
||||
if (m_channel == 5) LOG("CH%d running voice: o_val = %x\n", m_channel, m_octave);
|
||||
|
||||
int m_tune = m_cmi02_pia[0]->b_output();
|
||||
LOG("CH%d running voice: Tuning = %02x\n", m_channel, (uint8_t)m_tune);
|
||||
if (m_channel == 5) LOG("CH%d running voice: Tuning = %02x\n", m_channel, (uint8_t)m_tune);
|
||||
double mfreq = (double)(0xf00 | m_tune) * ((MASTER_OSCILLATOR.dvalue() / 2.0) / 4096.0);
|
||||
LOG("CH%d running voice: mfreq = %f (%03x * %f)\n", m_channel, mfreq, 0xf00 | m_tune, (MASTER_OSCILLATOR.dvalue() / 2.0) / 4096.0);
|
||||
if (m_channel == 5) LOG("CH%d running voice: mfreq = %f (%03x * %f)\n", m_channel, mfreq, 0xf00 | m_tune, (MASTER_OSCILLATOR.dvalue() / 2.0) / 4096.0);
|
||||
|
||||
double cfreq = ((double)(0x800 | (pitch << 1)) * mfreq) / 4096.0;
|
||||
LOG("CH%d running voice: cfreq = %f (%04x * %f) / 4096.0\n", m_channel, cfreq, 0x800 | (pitch << 1), mfreq, cfreq);
|
||||
double cfreq = ((double)(0x800 | (m_pitch << 1)) * mfreq) / 4096.0;
|
||||
if (m_channel == 5) LOG("CH%d running voice: cfreq = %f (%04x * %f) / 4096.0\n", m_channel, cfreq, 0x800 | (m_pitch << 1), mfreq, cfreq);
|
||||
|
||||
if (cfreq > MASTER_OSCILLATOR.dvalue())
|
||||
{
|
||||
LOG("CH%d Ignoring voice run due to excessive frequency\n");
|
||||
if (m_channel == 5) LOG("CH%d Ignoring voice run due to excessive frequency\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG("CH%d Running voice\n", m_channel);
|
||||
if (m_channel == 5) LOG("CH%d Running voice\n", m_channel);
|
||||
/* Octave register enabled? */
|
||||
if (!BIT(o_val, 3))
|
||||
cfreq /= (double)(2 << ((7 ^ o_val) & 7));
|
||||
if (!BIT(m_octave, 3))
|
||||
cfreq /= (double)(2 << ((7 ^ m_octave) & 7));
|
||||
|
||||
cfreq /= 16.0;
|
||||
|
||||
m_freq = cfreq;
|
||||
|
||||
LOG("CH%d running voice: Final freq: %f\n", m_channel, m_freq);
|
||||
if (m_channel == 5) LOG("CH%d running voice: Final freq: %f\n", m_channel, m_freq);
|
||||
|
||||
m_stream->set_sample_rate(cfreq);
|
||||
|
||||
@ -291,10 +534,10 @@ void cmi01a_device::run_voice()
|
||||
attotime zx_period = attotime::from_ticks(64, cfreq);
|
||||
m_zx_timer->adjust(zx_period, 0, zx_period);
|
||||
|
||||
if (m_status & CHANNEL_STATUS_LOAD)
|
||||
if (m_load)
|
||||
{
|
||||
int samples = 0x4000 - (m_segment_cnt & 0x3fff);
|
||||
LOG("CH%d voice is %04x samples long\n", m_channel, samples);
|
||||
if (m_channel == 5) LOG("CH%d voice is %04x samples long\n", m_channel, samples);
|
||||
m_eosi_timer->adjust(attotime::from_ticks(samples, cfreq));
|
||||
}
|
||||
}
|
||||
@ -303,19 +546,22 @@ WRITE_LINE_MEMBER( cmi01a_device::pia_0_cb2_w )
|
||||
{
|
||||
int old_state = m_pia0_cb2_state;
|
||||
m_pia0_cb2_state = state;
|
||||
LOG("CH%d PIA0 CB2: %d\n", m_channel, state);
|
||||
if (m_channel == 5) LOG("CH%d PIA0 CB2: %d\n", m_channel, state);
|
||||
|
||||
//streams_update();
|
||||
m_stream->update();
|
||||
|
||||
/* RUN */
|
||||
if (!old_state && m_pia0_cb2_state)
|
||||
{
|
||||
m_status |= CHANNEL_STATUS_RUN;
|
||||
m_run = true;
|
||||
|
||||
/* Only reset address counter if /LOAD not asserted */
|
||||
if ((m_status & CHANNEL_STATUS_LOAD) == 0)
|
||||
/* Clear /EOSI */
|
||||
m_pia[1]->cb1_w(1);
|
||||
|
||||
/* Only reset address counter if LOAD not asserted */
|
||||
if (!m_load)
|
||||
{
|
||||
m_segment_cnt = 0x4000 | ((m_pia[0]->a_output() & 0x7f) << 7);
|
||||
m_segment_cnt = 0x4000 | (m_ws << 7);
|
||||
m_new_addr = 1;
|
||||
}
|
||||
|
||||
@ -334,10 +580,10 @@ WRITE_LINE_MEMBER( cmi01a_device::pia_0_cb2_w )
|
||||
|
||||
if (old_state && !m_pia0_cb2_state)
|
||||
{
|
||||
m_status &= ~CHANNEL_STATUS_RUN;
|
||||
m_run = false;
|
||||
|
||||
/* Clear /EOSI */
|
||||
m_pia[1]->cb1_w(1);
|
||||
/* Set /EOSI */
|
||||
m_pia[1]->cb1_w(0);
|
||||
|
||||
m_ptm->set_g1(1);
|
||||
m_ptm->set_g2(1);
|
||||
@ -358,16 +604,16 @@ void cmi01a_device::update_wave_addr(int inc)
|
||||
++m_segment_cnt;
|
||||
|
||||
/* Update end of sound interrupt flag */
|
||||
//m_pia[1]->cb1_w((m_segment_cnt & 0x4000) >> 14);
|
||||
m_pia[1]->cb1_w((m_segment_cnt & 0x4000) >> 14);
|
||||
|
||||
/* TODO Update zero crossing flag */
|
||||
//m_pia[1]->ca1_w((m_segment_cnt & 0x40) >> 6);
|
||||
m_pia[1]->ca1_w((m_segment_cnt & 0x40) >> 6);
|
||||
|
||||
/* Clock a latch on a transition */
|
||||
if ((old_cnt & 0x40) && !(m_segment_cnt & 0x40))
|
||||
{
|
||||
//m_pia[1]->ca2_w(1);
|
||||
//m_pia[1]->ca2_w(0);
|
||||
m_pia[1]->ca2_w(1);
|
||||
m_pia[1]->ca2_w(0);
|
||||
}
|
||||
|
||||
/* Zero crossing interrupt is a pulse */
|
||||
@ -381,23 +627,26 @@ WRITE_LINE_MEMBER( cmi01a_device::ptm_irq )
|
||||
WRITE_LINE_MEMBER( cmi01a_device::ptm_o1 )
|
||||
{
|
||||
m_ptm_o1 = state;
|
||||
// TODO: Update ECLK
|
||||
if (m_ptm_o1 != m_zx_ff)
|
||||
reset_bcas_counter();
|
||||
update_eclk();
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( cmi01a_device::ptm_o2 )
|
||||
{
|
||||
m_ptm_o2 = state;
|
||||
// TODO: Update ECLK
|
||||
update_eclk();
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( cmi01a_device::ptm_o3 )
|
||||
{
|
||||
m_ptm_o3 = state;
|
||||
// TODO: Update ECLK
|
||||
update_eclk();
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER( cmi01a_device::eosi_r )
|
||||
{
|
||||
if (m_channel == 5) LOG("CH%d PIA1 CB1 Read: %d\n", m_channel, BIT(m_segment_cnt, 14));
|
||||
return BIT(m_segment_cnt, 14);
|
||||
}
|
||||
|
||||
@ -408,11 +657,10 @@ READ_LINE_MEMBER( cmi01a_device::zx_r )
|
||||
|
||||
void cmi01a_device::write(offs_t offset, uint8_t data)
|
||||
{
|
||||
LOG("%s: channel card %d write: %02x = %02x\n", machine().describe_context(), m_channel, offset, data);
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x0:
|
||||
if (m_channel == 5) LOG("%s: CH%d Porthole Write to %04x: %02x\n", machine().describe_context(), m_channel, m_segment_cnt & 0x3fff, data);
|
||||
if (m_new_addr)
|
||||
m_new_addr = 0;
|
||||
|
||||
@ -421,28 +669,32 @@ void cmi01a_device::write(offs_t offset, uint8_t data)
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
m_env_dir_ctrl = ENV_DIR_DOWN;
|
||||
if (m_channel == 5) LOG("%s: CH%d set Envelope Dir Down (%02x)\n", machine().describe_context(), m_channel, data);
|
||||
m_env_dir = ENV_DIR_DOWN;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
m_env_dir_ctrl = ENV_DIR_UP;
|
||||
if (m_channel == 5) LOG("%s: CH%d set Envelope Dir Up (%02x)\n", machine().describe_context(), m_channel, data);
|
||||
m_env_dir = ENV_DIR_UP;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
if (m_channel == 5) LOG("%s: CH%d set Volume Latch: %02x\n", machine().describe_context(), m_channel, data);
|
||||
m_vol_latch = data;
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
if (m_channel == 5) LOG("%s: CH%d set Filter Latch: %02x\n", machine().describe_context(), m_channel, data);
|
||||
m_flt_latch = data;
|
||||
break;
|
||||
|
||||
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||
LOG("CH%d PIA0 Write: %d = %02x\n", m_channel, offset & 3, data);
|
||||
if (m_channel == 5) LOG("CH%d PIA0 Write: %d = %02x\n", m_channel, offset & 3, data);
|
||||
m_pia[0]->write(offset & 3, data);
|
||||
break;
|
||||
|
||||
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||
LOG("CH%d PIA1 Write: %d = %02x\n", m_channel, (BIT(offset, 0) << 1) | BIT(offset, 1), data);
|
||||
if (m_channel == 5) LOG("CH%d PIA1 Write: %d = %02x\n", m_channel, (BIT(offset, 0) << 1) | BIT(offset, 1), data);
|
||||
m_pia[1]->write((BIT(offset, 0) << 1) | BIT(offset, 1), data);
|
||||
break;
|
||||
|
||||
@ -456,13 +708,13 @@ void cmi01a_device::write(offs_t offset, uint8_t data)
|
||||
if ((offset == 5 || offset == 7) && (data < 0x30))
|
||||
data = 0xff;
|
||||
|
||||
LOG("CH%d PTM Write: %d = %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data);
|
||||
if (m_channel == 5) LOG("CH%d PTM Write: %d = %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data);
|
||||
m_ptm->write((a2 << 2) | (a1 << 1) | a0, data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG("%s: Unknown channel card write to E0%02X = %02X\n", machine().describe_context(), offset, data);
|
||||
if (m_channel == 5) LOG("%s: Unknown channel card write to E0%02X = %02X\n", machine().describe_context(), offset, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -483,29 +735,33 @@ uint8_t cmi01a_device::read(offs_t offset)
|
||||
break;
|
||||
}
|
||||
data = m_wave_ram[m_segment_cnt & 0x3fff];
|
||||
if (m_channel == 5) LOG("%s: CH%d Porthole Read: %02x\n", machine().describe_context(), m_channel, data);
|
||||
update_wave_addr(1);
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
m_env_dir_ctrl = ENV_DIR_DOWN;
|
||||
if (m_channel == 5) LOG("%s: CH%d set Envelope Dir Down (R)\n", machine().describe_context(), m_channel);
|
||||
m_env_dir = ENV_DIR_DOWN;
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
m_env_dir_ctrl = ENV_DIR_UP;
|
||||
if (m_channel == 5) LOG("%s: CH%d set Envelope Dir Up (R)\n", machine().describe_context(), m_channel);
|
||||
m_env_dir = ENV_DIR_UP;
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
if (m_channel == 5) LOG("%s: CH%d read Volume Latch (ff)\n", machine().describe_context(), m_channel);
|
||||
data = 0xff;
|
||||
break;
|
||||
|
||||
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||
data = m_pia[0]->read(offset & 3);
|
||||
LOG("CH%d PIA0 Read: %d = %02x\n", m_channel, offset & 3, data);
|
||||
if (m_channel == 5) LOG("CH%d PIA0 Read: %d = %02x\n", m_channel, offset & 3, data);
|
||||
break;
|
||||
|
||||
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||
data = m_pia[1]->read((BIT(offset, 0) << 1) | BIT(offset, 1));
|
||||
LOG("CH%d PIA1 Read: %d = %02x\n", m_channel, (BIT(offset, 0) << 1) | BIT(offset, 1), data);
|
||||
if (m_channel == 5) LOG("CH%d PIA1 Read: %d = %02x\n", m_channel, (BIT(offset, 0) << 1) | BIT(offset, 1), data);
|
||||
break;
|
||||
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
@ -516,16 +772,16 @@ uint8_t cmi01a_device::read(offs_t offset)
|
||||
|
||||
data = m_ptm->read((a2 << 2) | (a1 << 1) | a0);
|
||||
|
||||
LOG("CH%d PTM Read: %d = %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data);
|
||||
if (m_channel == 5) LOG("CH%d PTM Read: %d = %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG("%s: Unknown channel card %d read from E0%02X\n", machine().describe_context(), m_channel, offset);
|
||||
if (m_channel == 5) LOG("%s: Unknown channel card %d read from E0%02X\n", machine().describe_context(), m_channel, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
LOG("%s: channel card %d read: %02x = %02x\n", machine().describe_context(), m_channel, offset, data);
|
||||
if (m_channel == 5) LOG("%s: channel card %d read: %02x = %02x\n", machine().describe_context(), m_channel, offset, data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include "machine/6840ptm.h"
|
||||
#include "machine/input_merger.h"
|
||||
|
||||
#define ENV_DIR_DOWN 0
|
||||
#define ENV_DIR_UP 1
|
||||
#define ENV_DIR_UP 0
|
||||
#define ENV_DIR_DOWN 1
|
||||
|
||||
#define CHANNEL_STATUS_LOAD 1
|
||||
#define CHANNEL_STATUS_RUN 2
|
||||
@ -45,6 +45,7 @@ protected:
|
||||
|
||||
static const device_timer_id TIMER_ZX = 0;
|
||||
static const device_timer_id TIMER_EOSI = 1;
|
||||
static const device_timer_id TIMER_BCAS = 2;
|
||||
|
||||
required_device<input_merger_device> m_irq_merger;
|
||||
required_device_array<pia6821_device, 2> m_pia;
|
||||
@ -57,8 +58,20 @@ protected:
|
||||
private:
|
||||
DECLARE_WRITE_LINE_MEMBER(cmi01a_irq);
|
||||
|
||||
void bcas_tick();
|
||||
void reset_bcas_counter();
|
||||
|
||||
void clock_envelope();
|
||||
void tick_ediv();
|
||||
void set_eclk(bool eclk);
|
||||
void update_eclk();
|
||||
|
||||
void pulse_zcint();
|
||||
void pulse_gzx();
|
||||
void reset_waveform_segment();
|
||||
void check_segment_load();
|
||||
void wpe_w(int state);
|
||||
void load_w(int state);
|
||||
|
||||
void zx_timer_cb();
|
||||
void eosi_timer_cb();
|
||||
@ -72,37 +85,59 @@ private:
|
||||
|
||||
emu_timer * m_eosi_timer;
|
||||
|
||||
emu_timer * m_bcas_timer;
|
||||
|
||||
std::unique_ptr<uint8_t[]> m_wave_ram;
|
||||
uint16_t m_segment_cnt;
|
||||
uint8_t m_new_addr; // Flag
|
||||
uint8_t m_env_dir_ctrl;
|
||||
uint8_t m_vol_latch;
|
||||
uint8_t m_flt_latch;
|
||||
uint8_t m_rp;
|
||||
uint8_t m_ws;
|
||||
int m_dir;
|
||||
int m_pia0_cb2_state;
|
||||
uint8_t m_rp;
|
||||
uint8_t m_ws;
|
||||
int m_dir;
|
||||
int m_env_dir;
|
||||
uint8_t m_env;
|
||||
int m_pia0_cb2_state;
|
||||
|
||||
double m_freq;
|
||||
uint8_t m_status;
|
||||
uint8_t m_bcas_q1_ticks;
|
||||
uint8_t m_bcas_q1;
|
||||
uint8_t m_bcas_q2_ticks;
|
||||
uint8_t m_bcas_q2;
|
||||
|
||||
int m_ptm_o1;
|
||||
int m_ptm_o2;
|
||||
int m_ptm_o3;
|
||||
double m_freq;
|
||||
|
||||
bool m_eclk;
|
||||
bool m_ediv_out;
|
||||
int m_ptm_o1;
|
||||
int m_ptm_o2;
|
||||
int m_ptm_o3;
|
||||
|
||||
bool m_load;
|
||||
bool m_run;
|
||||
bool m_gzx;
|
||||
bool m_nwpe;
|
||||
bool m_tri;
|
||||
bool m_pia1_ca2;
|
||||
|
||||
bool m_eclk;
|
||||
bool m_env_clk;
|
||||
bool m_ediv_out;
|
||||
uint8_t m_ediv_rate;
|
||||
uint8_t m_ediv_count;
|
||||
|
||||
uint16_t m_pitch;
|
||||
uint8_t m_octave;
|
||||
|
||||
devcb_write_line m_irq_cb;
|
||||
|
||||
void rp_w(uint8_t data);
|
||||
void ws_dir_w(uint8_t data);
|
||||
uint8_t ws_dir_r();
|
||||
DECLARE_READ_LINE_MEMBER( tri_r );
|
||||
DECLARE_WRITE_LINE_MEMBER( pia_0_ca2_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( pia_0_cb2_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( eload_w );
|
||||
|
||||
DECLARE_READ_LINE_MEMBER( eosi_r );
|
||||
DECLARE_READ_LINE_MEMBER( zx_r );
|
||||
uint8_t pia_1_a_r();
|
||||
void pia_1_a_w(uint8_t data);
|
||||
void pia_1_b_w(uint8_t data);
|
||||
|
||||
@ -110,6 +145,8 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER( ptm_o2 );
|
||||
DECLARE_WRITE_LINE_MEMBER( ptm_o3 );
|
||||
DECLARE_WRITE_LINE_MEMBER( ptm_irq );
|
||||
|
||||
static const uint8_t s_7497_rate_table[64][64];
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
@ -2281,28 +2281,28 @@ void cmi_state::cmi2x(machine_config &config)
|
||||
|
||||
// Channel cards
|
||||
cmi01a_device &cmi01a_0(CMI01A_CHANNEL_CARD(config, "cmi01a_0", SYSTEM_CAS_CLOCK, 0));
|
||||
cmi01a_0.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_0.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_0.irq_callback().set(FUNC(cmi_state::channel_irq<0>));
|
||||
cmi01a_device &cmi01a_1(CMI01A_CHANNEL_CARD(config, "cmi01a_1", SYSTEM_CAS_CLOCK, 1));
|
||||
cmi01a_1.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_1.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_1.irq_callback().set(FUNC(cmi_state::channel_irq<1>));
|
||||
cmi01a_device &cmi01a_2(CMI01A_CHANNEL_CARD(config, "cmi01a_2", SYSTEM_CAS_CLOCK, 2));
|
||||
cmi01a_2.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_2.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_2.irq_callback().set(FUNC(cmi_state::channel_irq<2>));
|
||||
cmi01a_device &cmi01a_3(CMI01A_CHANNEL_CARD(config, "cmi01a_3", SYSTEM_CAS_CLOCK, 3));
|
||||
cmi01a_3.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_3.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_3.irq_callback().set(FUNC(cmi_state::channel_irq<3>));
|
||||
cmi01a_device &cmi01a_4(CMI01A_CHANNEL_CARD(config, "cmi01a_4", SYSTEM_CAS_CLOCK, 4));
|
||||
cmi01a_4.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_4.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_4.irq_callback().set(FUNC(cmi_state::channel_irq<4>));
|
||||
cmi01a_device &cmi01a_5(CMI01A_CHANNEL_CARD(config, "cmi01a_5", SYSTEM_CAS_CLOCK, 5));
|
||||
cmi01a_5.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_5.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_5.irq_callback().set(FUNC(cmi_state::channel_irq<5>));
|
||||
cmi01a_device &cmi01a_6(CMI01A_CHANNEL_CARD(config, "cmi01a_6", SYSTEM_CAS_CLOCK, 6));
|
||||
cmi01a_6.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_6.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_6.irq_callback().set(FUNC(cmi_state::channel_irq<6>));
|
||||
cmi01a_device &cmi01a_7(CMI01A_CHANNEL_CARD(config, "cmi01a_7", SYSTEM_CAS_CLOCK, 7));
|
||||
cmi01a_7.add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
cmi01a_7.add_route(ALL_OUTPUTS, "mono", 0.12);
|
||||
cmi01a_7.irq_callback().set(FUNC(cmi_state::channel_irq<7>));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user