rainbow: Add color board [Bavarese]

* first incarnatation of the Color Graphics Option for Rainbow-100 B
* Clock, VRAM reads/writes + values of uninitialized registers still unverified
* (see BUGS section in main driver).

vis: checkpoint (nw)
This commit is contained in:
cracyc 2016-10-02 20:40:44 -05:00
parent e2e65c9613
commit 83517be327
5 changed files with 1020 additions and 181 deletions

View File

@ -49,6 +49,7 @@ void mcd_isa_device::device_start()
{ {
cdrom_image_device::device_start(); cdrom_image_device::device_start();
set_isa_device(); set_isa_device();
m_isa->set_dma_channel(5, this, FALSE);
m_isa->install_device(0x0310, 0x0311, *this, &mcd_isa_device::map, 16); m_isa->install_device(0x0310, 0x0311, *this, &mcd_isa_device::map, 16);
} }
@ -58,41 +59,91 @@ void mcd_isa_device::device_start()
void mcd_isa_device::device_reset() void mcd_isa_device::device_reset()
{ {
m_data = false; m_stat = m_cdrom_handle ? STAT_READY | STAT_CHANGE : 0;
m_stat = m_cdrom_handle ? STAT_READY : 0; m_cmdrd_count = 0;
m_flag = FLAG_STAT; m_cmdbuf_count = 0;
m_rd_count = 0;
m_buf_count = 0; m_buf_count = 0;
m_curtoctrk = 1; m_curtoctrk = 1;
m_dma = 0; m_dma = 0;
m_irq = 0; m_irq = 0;
m_conf = 0;
m_dmalen = 2048;
m_locked = false; m_locked = false;
m_change = true;
m_newstat = true;
m_data = false;
}
bool mcd_isa_device::read_sector()
{
if(!m_readcount)
{
m_isa->drq5_w(CLEAR_LINE);
if(m_irq & IRQ_DATACOMP)
m_isa->irq5_w(ASSERT_LINE);
m_data = false;
m_cmdbuf[0] = STAT_SPIN | STAT_READY;
m_cmdbuf_count = 1;
return false;
}
UINT32 lba = msf_to_lba(m_readmsf);
cdrom_read_data(m_cdrom_handle, lba - 150, m_buf, m_mode & 0x40 ? CD_TRACK_MODE1_RAW : CD_TRACK_MODE1);
m_readmsf = lba_to_msf(lba + 1);
m_buf_count = m_dmalen + 1;
m_buf_idx = 0;
m_data = true;
m_readcount--;
if(m_dma)
m_isa->drq5_w(ASSERT_LINE);
if(m_irq & IRQ_DATAREADY)
m_isa->irq5_w(ASSERT_LINE);
return true;
} }
READ8_MEMBER(mcd_isa_device::flag_r) READ8_MEMBER(mcd_isa_device::flag_r)
{ {
UINT8 ret = m_flag; UINT8 ret = 0;
m_flag = 0; if(!m_buf_count || !m_data)
ret |= FLAG_NODATA;
if(m_buf_count == m_dmalen + 1)
ret |= FLAG_DATAREADY;
if(!m_cmdbuf_count || !m_newstat)
ret |= FLAG_NOSTAT; // all command results are status
return ret; return ret;
} }
READ8_MEMBER(mcd_isa_device::data_r) READ8_MEMBER(mcd_isa_device::data_r)
{ {
if(!m_data) m_isa->irq5_w(CLEAR_LINE);
if(m_cmdbuf_count)
{ {
if(m_buf_count) m_cmdbuf_count--;
{ return m_cmdbuf[m_cmdbuf_idx++];
m_flag = FLAG_DATA;
m_data = true;
}
return m_stat;
} }
else if(m_buf_count) else if(m_buf_count)
{ {
UINT8 ret = m_buf[m_buf_idx++]; UINT8 ret = m_buf_idx < 2352 ? m_buf[m_buf_idx++] : 0;
m_buf_count--; m_buf_count--;
if(m_buf_count) if(!m_buf_count)
m_flag = FLAG_DATA; read_sector();
return ret;
}
return m_stat;
}
UINT16 mcd_isa_device::dack16_r(int line)
{
if(m_buf_count & ~1)
{
UINT16 ret = 0;
if(m_buf_idx < 2351)
{
ret = m_buf[m_buf_idx++];
ret |= (m_buf[m_buf_idx++] << 8);
}
m_buf_count -= 2;
if(!m_buf_count)
read_sector();
return ret; return ret;
} }
return 0; return 0;
@ -105,27 +156,34 @@ WRITE8_MEMBER(mcd_isa_device::reset_w)
WRITE8_MEMBER(mcd_isa_device::cmd_w) WRITE8_MEMBER(mcd_isa_device::cmd_w)
{ {
if(m_rd_count) if(m_cmdrd_count)
{ {
m_rd_count--; m_cmdrd_count--;
switch(m_cmd) switch(m_cmd)
{ {
case CMD_SET_MODE: case CMD_SET_MODE:
m_mode = data; m_mode = data;
m_buf[0] = 0; m_cmdbuf[1] = 0;
m_buf_count = 1; m_cmdbuf_count = 2;
break; break;
case CMD_LOCK: case CMD_LOCK:
m_locked = data & 1 ? true : false; m_locked = data & 1 ? true : false;
m_buf[0] = 0; m_cmdbuf[1] = 0;
m_buf[1] = 0; m_cmdbuf[2] = 0;
m_buf_count = 2; m_cmdbuf_count = 3;
break; break;
case CMD_CONFIG: case CMD_CONFIG:
switch(m_rd_count) switch(m_cmdrd_count)
{ {
case 1: case 1:
if(m_conf == 1)
{
m_dmalen = data << 8;
break;
}
m_conf = data; m_conf = data;
if(m_conf == 1)
m_cmdrd_count++;
break; break;
case 0: case 0:
switch(m_conf) switch(m_conf)
@ -133,50 +191,69 @@ WRITE8_MEMBER(mcd_isa_device::cmd_w)
case 0x10: case 0x10:
m_irq = data; m_irq = data;
break; break;
case 0x01:
m_dmalen |= data;
break;
case 0x02: case 0x02:
m_dma = data; m_dma = data;
break; break;
} }
m_buf[0] = 0; m_cmdbuf[1] = 0;
m_buf_count = 1; m_cmdbuf_count = 2;
m_conf = 0;
break; break;
} }
} break;
if(!m_rd_count) case CMD_READ1X:
case CMD_READ2X:
switch(m_cmdrd_count)
{ {
m_data = false; case 5:
m_flag = FLAG_STAT; m_readmsf = 0;
m_stat = m_cdrom_handle ? STAT_READY : 0; case 4:
case 3:
m_readmsf |= bcd_2_dec(data) << ((m_cmdrd_count - 3) * 8);
break;
case 0:
m_readcount = data + 1;
read_sector();
m_cmdbuf_count = 1;
m_cmdbuf[0] = STAT_SPIN | STAT_READY;
break;
} }
break;
}
if(!m_cmdrd_count)
m_stat = m_cdrom_handle ? (STAT_READY | (m_change ? STAT_CHANGE : 0)) : 0;
return; return;
} }
m_cmd = data; m_cmd = data;
m_buf_idx = 0; m_cmdbuf_idx = 0;
m_rd_count = 0; m_cmdrd_count = 0;
m_buf_count = 0; m_cmdbuf_count = 1;
m_stat = m_cdrom_handle ? STAT_READY : 0; m_cmdbuf[0] = m_cdrom_handle ? (STAT_READY | (m_change ? STAT_CHANGE : 0)) : 0;
m_data = false;
switch(data) switch(data)
{ {
case CMD_GET_INFO: case CMD_GET_INFO:
if(m_cdrom_handle) if(m_cdrom_handle)
{ {
UINT32 first = lba_to_msf(150), last = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, 0xaa)); UINT32 first = lba_to_msf(150), last = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, 0xaa));
m_buf[0] = 1; m_cmdbuf[1] = 1;
m_buf[1] = dec_2_bcd(cdrom_get_last_track(m_cdrom_handle)); m_cmdbuf[2] = dec_2_bcd(cdrom_get_last_track(m_cdrom_handle));
m_buf[2] = dec_2_bcd((first >> 16) & 0xff); m_cmdbuf[3] = dec_2_bcd((last >> 16) & 0xff);
m_buf[3] = dec_2_bcd((first >> 8) & 0xff); m_cmdbuf[4] = dec_2_bcd((last >> 8) & 0xff);
m_buf[4] = dec_2_bcd(first & 0xff); m_cmdbuf[5] = dec_2_bcd(last & 0xff);
m_buf[5] = dec_2_bcd((last >> 16) & 0xff); m_cmdbuf[6] = dec_2_bcd((first >> 16) & 0xff);
m_buf[6] = dec_2_bcd((last >> 8) & 0xff); m_cmdbuf[7] = dec_2_bcd((first >> 8) & 0xff);
m_buf[7] = dec_2_bcd(last & 0xff); m_cmdbuf[8] = dec_2_bcd(first & 0xff);
m_buf[8] = 0; m_cmdbuf[9] = 0;
m_buf_count = 9; m_cmdbuf_count = 10;
} }
else else
{ {
m_buf_count = 1; m_cmdbuf_count = 1;
m_buf[0] = 0; m_cmdbuf[0] = STAT_CMD_CHECK;
m_stat = STAT_CMD_CHECK;
} }
break; break;
case CMD_GET_Q: case CMD_GET_Q:
@ -185,29 +262,31 @@ WRITE8_MEMBER(mcd_isa_device::cmd_w)
int tracks = cdrom_get_last_track(m_cdrom_handle); int tracks = cdrom_get_last_track(m_cdrom_handle);
UINT32 start = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, m_curtoctrk)); UINT32 start = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, m_curtoctrk));
UINT32 end = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, m_curtoctrk < tracks ? m_curtoctrk + 1 : 0xaa)); UINT32 end = lba_to_msf(cdrom_get_track_start(m_cdrom_handle, m_curtoctrk < tracks ? m_curtoctrk + 1 : 0xaa));
m_buf[0] = 1; // track type? m_cmdbuf[1] = (cdrom_get_adr_control(m_cdrom_handle, m_curtoctrk) << 4) & 0xf0;
m_buf[1] = 0; // track num except when reading toc m_cmdbuf[2] = 0; // track num except when reading toc
m_buf[2] = dec_2_bcd(m_curtoctrk); // index m_cmdbuf[3] = dec_2_bcd(m_curtoctrk); // index
m_buf[3] = dec_2_bcd((start >> 16) & 0xff); m_cmdbuf[4] = dec_2_bcd((start >> 16) & 0xff);
m_buf[4] = dec_2_bcd((start >> 8) & 0xff); m_cmdbuf[5] = dec_2_bcd((start >> 8) & 0xff);
m_buf[5] = dec_2_bcd(start & 0xff); m_cmdbuf[6] = dec_2_bcd(start & 0xff);
m_buf[6] = 0; m_cmdbuf[7] = 0;
m_buf[7] = dec_2_bcd((end >> 16) & 0xff); m_cmdbuf[8] = dec_2_bcd((end >> 16) & 0xff);
m_buf[8] = dec_2_bcd((end >> 8) & 0xff); m_cmdbuf[9] = dec_2_bcd((end >> 8) & 0xff);
m_buf[9] = dec_2_bcd(end & 0xff); m_cmdbuf[10] = dec_2_bcd(end & 0xff);
if(m_curtoctrk >= tracks) if(m_curtoctrk >= tracks)
m_curtoctrk = 1; m_curtoctrk = 1;
m_buf_count = 10; m_cmdbuf_count = 11;
} }
else else
m_stat = STAT_CMD_CHECK; {
m_cmdbuf_count = 1;
m_cmdbuf[0] = STAT_CMD_CHECK;
}
break; break;
case CMD_GET_STAT: case CMD_GET_STAT:
m_buf[0] = m_stat; m_change = false;
m_buf_count = 1;
break; break;
case CMD_SET_MODE: case CMD_SET_MODE:
m_rd_count = 1; m_cmdrd_count = 1;
break; break;
case CMD_STOPCDDA: case CMD_STOPCDDA:
case CMD_STOP: case CMD_STOP:
@ -215,32 +294,34 @@ WRITE8_MEMBER(mcd_isa_device::cmd_w)
m_curtoctrk = 1; m_curtoctrk = 1;
break; break;
case CMD_CONFIG: case CMD_CONFIG:
m_rd_count = 2; m_cmdrd_count = 2;
break; break;
case CMD_READ: case CMD_READ1X:
case CMD_READ2X:
if(m_cdrom_handle)
{
m_drvmode = DRV_MODE_READ; m_drvmode = DRV_MODE_READ;
break; m_cmdrd_count = 6;
case CMD_READCDDA: }
m_drvmode = DRV_MODE_CDDA; else
{
m_cmdbuf_count = 1;
m_cmdbuf[0] = STAT_CMD_CHECK;
}
break; break;
case CMD_GET_VER: case CMD_GET_VER:
m_buf[0] = 1; // ? m_cmdbuf[1] = 1; // ?
m_buf[1] = 'D'; m_cmdbuf[2] = 'D';
m_buf[2] = 0; m_cmdbuf[3] = 0;
m_buf_count = 3; m_cmdbuf_count = 4;
break; break;
case CMD_EJECT: case CMD_EJECT:
break; break;
case CMD_LOCK: case CMD_LOCK:
m_rd_count = 1; m_cmdrd_count = 1;
break; break;
default: default:
m_stat |= STAT_CMD_CHECK; m_cmdbuf[0] = m_stat | STAT_CMD_CHECK;
break; break;
} }
if(!m_rd_count)
{
m_data = false;
m_flag = FLAG_STAT;
}
} }

View File

@ -31,23 +31,33 @@ public:
DECLARE_READ8_MEMBER(flag_r); DECLARE_READ8_MEMBER(flag_r);
DECLARE_WRITE8_MEMBER(cmd_w); DECLARE_WRITE8_MEMBER(cmd_w);
DECLARE_WRITE8_MEMBER(reset_w); DECLARE_WRITE8_MEMBER(reset_w);
virtual UINT16 dack16_r(int line) override;
protected: protected:
// device-level overrides // device-level overrides
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
private: private:
bool read_sector();
bool m_change;
bool m_newstat;
bool m_data; bool m_data;
UINT8 m_stat; UINT8 m_stat;
UINT8 m_flag; UINT8 m_buf[2352];
UINT8 m_buf[2048];
int m_buf_count; int m_buf_count;
int m_buf_idx; int m_buf_idx;
int m_rd_count; UINT8 m_cmdbuf[16];
int m_cmdbuf_count;
int m_cmdrd_count;
int m_cmdbuf_idx;
UINT8 m_mode; UINT8 m_mode;
UINT8 m_cmd; UINT8 m_cmd;
UINT8 m_conf; UINT8 m_conf;
UINT8 m_irq; UINT8 m_irq;
UINT8 m_dma; UINT8 m_dma;
UINT16 m_dmalen;
UINT32 m_readmsf;
UINT8 m_readcount;
bool m_locked; bool m_locked;
int m_drvmode; int m_drvmode;
int m_curtoctrk; int m_curtoctrk;
@ -70,8 +80,8 @@ private:
CMD_STOPCDDA = 0x70, CMD_STOPCDDA = 0x70,
CMD_CONFIG = 0x90, CMD_CONFIG = 0x90,
CMD_SET_VOL = 0xae, CMD_SET_VOL = 0xae,
CMD_READ = 0xc0, CMD_READ1X = 0xc0,
CMD_READCDDA = 0xc1, CMD_READ2X = 0xc1,
CMD_GET_VER = 0xdc, CMD_GET_VER = 0xdc,
CMD_STOP = 0xf0, CMD_STOP = 0xf0,
CMD_EJECT = 0xf6, CMD_EJECT = 0xf6,
@ -90,10 +100,16 @@ private:
DRV_MODE_CDDA DRV_MODE_CDDA
}; };
enum { enum {
FLAG_DATA = 2, FLAG_NODATA = 2,
FLAG_STAT = 4, FLAG_NOSTAT = 4,
FLAG_DATAREADY = 8, //??
FLAG_OPEN = 16 FLAG_OPEN = 16
}; };
enum {
IRQ_DATAREADY = 1,
IRQ_DATACOMP = 2,
IRQ_ERROR = 4
};
}; };

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ protected:
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
virtual void dack16_w(int line, UINT16 data) override { m_sample[m_samples++] = data; if(m_samples == 2) m_isa->drq7_w(CLEAR_LINE); } virtual void dack16_w(int line, UINT16 data) override { if(m_samples < 2) m_sample[m_samples++] = data; else m_isa->drq7_w(CLEAR_LINE); }
virtual machine_config_constructor device_mconfig_additions() const override; virtual machine_config_constructor device_mconfig_additions() const override;
private: private:
required_device<dac_device> m_dacr; required_device<dac_device> m_dacr;
@ -30,8 +30,8 @@ private:
UINT8 m_data[2][16]; UINT8 m_data[2][16];
UINT8 m_mode; UINT8 m_mode;
UINT8 m_stat; UINT8 m_stat;
int m_sample_byte; unsigned int m_sample_byte;
int m_samples; unsigned int m_samples;
emu_timer *m_pcm; emu_timer *m_pcm;
}; };
@ -164,13 +164,13 @@ WRITE8_MEMBER(vis_audio_device::pcm_w)
m_mode = data; m_mode = data;
break; break;
case 0x02: case 0x02:
m_data[0][m_index[0]] = data; m_data[0][m_index[0] & 0xf] = data;
break; break;
case 0x03: case 0x03:
m_index[0] = data; m_index[0] = data;
break; break;
case 0x04: case 0x04:
m_data[1][m_index[1]] = data; m_data[1][m_index[1] & 0xf] = data;
break; break;
case 0x05: case 0x05:
m_index[1] = data; m_index[1] = data;

View File

@ -1,4 +1,3 @@
<?xml version="1.0"?>
<mamelayout version="2"> <mamelayout version="2">
<element name="driveled" defstate="0"> <element name="driveled" defstate="0">
<disk state="1"> <disk state="1">
@ -115,7 +114,7 @@
<view name="Default Layout"> <view name="Default Layout">
<screen index="0"> <screen index="0">
<bounds x="30" y="0" width="640" height="480" /> <bounds x="30" y="0" width="~scr0width~" height="~scr0height~" />
</screen> </screen>
<bezel name="driveled0" element="driveled"> <bezel name="driveled0" element="driveled">
@ -221,10 +220,33 @@
</bezel> </bezel>
</view> </view>
<view name="Screen Only"> <view name="Text Only">
<screen index="0"> <screen index="0">
<bounds x="0" y="0" width="640" height="480" /> <bounds x="30" y="0" width="~scr0width~" height="~scr0height~" />
</screen> </screen>
</view> </view>
<view name="Graphics Only">
<screen index="1">
<bounds x="0" y="0" width="~scr1width~" height="~scr1height~" />
</screen>
</view>
<view name="Dual Side-by-Side">
<screen index="0">
<bounds x="0" y="0" width="~scr0width~" height="~scr0height~" />
</screen>
<screen index="1">
<bounds x="~scr0width~" y="0" width="~scr1width~" height="~scr1height~" />
</screen>
</view>
<view name="Dual Over-Under">
<screen index="0">
<bounds x="30" y="0" width="~scr0width~" height="~scr0height~" />
</screen>
<screen index="1">
<bounds x="30" y="~scr0height~" width="~scr1width~" height="~scr1height~" />
</screen>
</view>
</mamelayout> </mamelayout>