mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +03:00
Merge pull request #563 from meesokim/patch-5
[spc1500] some feature fixed for the official demo application [Miso Kim]
This commit is contained in:
commit
2204ccc92c
@ -12,9 +12,12 @@ Samsung SPC-1500 driver by Miso Kim
|
||||
2016-01-03 user defined char (PCG, Programmable Character Generator) support
|
||||
2016-01-05 detection of color palette initialization
|
||||
2016-01-06 80x16 mode graphic mode support
|
||||
2016-01-10 double character support
|
||||
2016-01-12 PCG adressing improved
|
||||
2016-01-13 Cassette tape motor improved
|
||||
|
||||
TODO:
|
||||
- Verify PCG ram read
|
||||
- Verify PCG ram read for Korean character (english character is fine)
|
||||
- Support floppy disk drive with SD-1500A controller card
|
||||
|
||||
****************************************************************************/
|
||||
@ -249,8 +252,8 @@ public:
|
||||
, m_pio(*this, "ppi8255")
|
||||
, m_sound(*this, "ay8910")
|
||||
, m_palette(*this, "palette")
|
||||
, m_timer(nullptr)
|
||||
{}
|
||||
DECLARE_WRITE_LINE_MEMBER(irq_w);
|
||||
DECLARE_READ8_MEMBER(psga_r);
|
||||
DECLARE_READ8_MEMBER(porta_r);
|
||||
DECLARE_WRITE_LINE_MEMBER( centronics_busy_w ) { m_centronics_busy = state; }
|
||||
@ -280,19 +283,22 @@ public:
|
||||
DECLARE_VIDEO_START(spc);
|
||||
MC6845_UPDATE_ROW(crtc_update_row);
|
||||
MC6845_RECONFIGURE(crtc_reconfig);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(timer);
|
||||
private:
|
||||
UINT8 *m_p_ram;
|
||||
UINT8 m_ipl;
|
||||
UINT8 m_palet[3];
|
||||
UINT8 m_paltbl[8];
|
||||
UINT16 m_page;
|
||||
UINT16 m_pcg_addr;
|
||||
UINT8 m_pcg_char, m_pcg_attr;
|
||||
UINT8 m_pcg_char, m_pcg_attr, m_char_change, m_pcg_char0;
|
||||
UINT16 m_pcg_offset[3];
|
||||
int m_char_count;
|
||||
attotime m_time;
|
||||
bool m_romsel;
|
||||
bool m_double_mode;
|
||||
bool m_p5bit;
|
||||
bool m_motor;
|
||||
bool m_motor_toggle;
|
||||
UINT8 m_crtc_vreg[0x100];
|
||||
bool m_centronics_busy;
|
||||
virtual void machine_start() override;
|
||||
@ -312,6 +318,7 @@ private:
|
||||
required_device<palette_device> m_palette;
|
||||
UINT8 *m_font;
|
||||
UINT8 m_priority;
|
||||
emu_timer *m_timer;
|
||||
void get_pcg_addr();
|
||||
};
|
||||
|
||||
@ -347,17 +354,17 @@ WRITE8_MEMBER( spc1500_state::portb_w)
|
||||
|
||||
WRITE8_MEMBER( spc1500_state::psgb_w)
|
||||
{
|
||||
attotime time = machine().scheduler().time();
|
||||
int elapsed_time = m_timer->elapsed().as_attoseconds()/ATTOSECONDS_PER_MICROSECOND;
|
||||
if (m_ipl != ((data>>1)&1))
|
||||
{
|
||||
m_ipl = ((data>>1)&1);
|
||||
membank("bank1")->set_entry(m_ipl ? 0 : 1);
|
||||
}
|
||||
m_cass->set_state(BIT(data, 6) ? CASSETTE_SPEAKER_ENABLED : CASSETTE_SPEAKER_MUTED);
|
||||
if (!m_motor && BIT(data, 7) && ATTOSECONDS_IN_MSEC((time - m_time).as_attoseconds()) > 1000)
|
||||
if (m_motor && !BIT(data, 7) && (elapsed_time > 100))
|
||||
{
|
||||
m_cass->change_state((m_cass->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
|
||||
m_time = time;
|
||||
m_timer->reset();
|
||||
}
|
||||
m_motor = BIT(data, 7);
|
||||
}
|
||||
@ -369,13 +376,12 @@ WRITE8_MEMBER( spc1500_state::portc_w)
|
||||
m_double_mode = (!m_p5bit && BIT(data, 5)); // double access I/O mode
|
||||
m_p5bit = BIT(data, 5);
|
||||
m_vdg->set_clock(VDP_CLOCK/(BIT(data, 2) ? 48 : 24));
|
||||
|
||||
}
|
||||
|
||||
READ8_MEMBER( spc1500_state::portb_r)
|
||||
{
|
||||
UINT8 data = 0;
|
||||
data |= ((m_cass->get_state() & CASSETTE_MASK_UISTATE) != CASSETTE_STOPPED) && ((m_cass->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_ENABLED) ? 0x0 : 0x1;
|
||||
data |= ((m_cass->get_state() & CASSETTE_MASK_UISTATE) == CASSETTE_STOPPED || ((m_cass->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED));
|
||||
data |= (m_dipsw->read() & 1) << 4;
|
||||
data |= (m_cass->input() > 0.0038)<<1;
|
||||
data |= m_vdg->vsync_r()<<7;
|
||||
@ -407,21 +413,15 @@ READ8_MEMBER( spc1500_state::crtc_r)
|
||||
return 0;
|
||||
}
|
||||
|
||||
READ8_MEMBER( spc1500_state::pcg_r)
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(spc1500_state::timer)
|
||||
{
|
||||
get_pcg_addr();
|
||||
if (BIT(m_pcg_attr,5)) // PCG font
|
||||
if(m_motor_toggle == true)
|
||||
{
|
||||
if ((offset&0x1f00) == 0x1400)
|
||||
offset += 0x300;
|
||||
return m_pcgram[m_pcg_addr+(offset&0xf)+(((offset & 0x1f00) - 0x1500)<<3)];
|
||||
m_cass->change_state((m_cass->get_state() & CASSETTE_MASK_MOTOR) == CASSETTE_MOTOR_DISABLED ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MASK_MOTOR);
|
||||
m_motor_toggle = false;
|
||||
}
|
||||
else // ROM font
|
||||
{
|
||||
return m_font[(m_crtc_vreg[0x9]==15?0x1000:0)+m_pcg_addr+(offset&0xf)];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spc1500_state::get_pcg_addr()
|
||||
{
|
||||
UINT16 vaddr = 0;
|
||||
@ -438,14 +438,44 @@ void spc1500_state::get_pcg_addr()
|
||||
}
|
||||
m_pcg_char = m_p_videoram[0x1000 + vaddr];
|
||||
m_pcg_attr = m_p_videoram[vaddr];
|
||||
m_pcg_addr = m_pcg_char * (m_crtc_vreg[0x9]+1);
|
||||
if (m_pcg_char != m_char_change)
|
||||
{
|
||||
m_char_change = m_pcg_char;
|
||||
m_pcg_offset[0] = 0;
|
||||
m_pcg_offset[1] = 0;
|
||||
m_pcg_offset[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( spc1500_state::pcg_w)
|
||||
{
|
||||
int reg = (offset>>8)-0x15;
|
||||
get_pcg_addr();
|
||||
m_pcg_addr=m_pcg_addr+(offset&0xf)+(((offset & 0x1f00) - 0x1500)<<3);
|
||||
m_pcgram[m_pcg_addr] = data;
|
||||
// printf("pcgram:0x%04x 0x%02x\n",m_pcg_addr, data);
|
||||
|
||||
m_pcgram[m_pcg_char * 8 + m_pcg_offset[reg] + (reg*0x800)] = data;
|
||||
if (m_pcg_offset[reg] == 7)
|
||||
m_pcg_offset[reg] = 0;
|
||||
else
|
||||
m_pcg_offset[reg]++;
|
||||
}
|
||||
|
||||
READ8_MEMBER( spc1500_state::pcg_r)
|
||||
{
|
||||
int reg = (offset>>8)-0x15;
|
||||
UINT8 data = 0;
|
||||
get_pcg_addr();
|
||||
if (reg < 0) reg = 2;
|
||||
if (BIT(m_pcg_attr,5)) // PCG font
|
||||
{
|
||||
data = m_pcgram[m_pcg_char * 8 + m_pcg_offset[reg]+(reg*0x800)];
|
||||
}
|
||||
else // ROM font
|
||||
{
|
||||
data = m_font[(m_crtc_vreg[0x9]==15?0x1000:0)+(m_pcg_char * 16)+m_pcg_offset[reg]];
|
||||
}
|
||||
if (m_pcg_offset[reg]++ > m_crtc_vreg[0x9]-1)
|
||||
m_pcg_offset[reg] = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( spc1500_state::priority_w)
|
||||
@ -457,7 +487,9 @@ WRITE8_MEMBER( spc1500_state::palet_w)
|
||||
{
|
||||
m_palet[(offset>>8)&0x0f] = data;
|
||||
for(int i=1, j=0; i < 0x100; i<<=1, j++)
|
||||
{
|
||||
m_paltbl[j] = (m_palet[0]&i?1:0)|(m_palet[1]&i?2:0)|(m_palet[2]&i?4:0);
|
||||
}
|
||||
}
|
||||
|
||||
PALETTE_INIT_MEMBER(spc1500_state,spc)
|
||||
@ -515,23 +547,31 @@ MC6845_UPDATE_ROW(spc1500_state::crtc_update_row)
|
||||
UINT8 pen = (nopalet ? color : m_paltbl[color]);
|
||||
UINT8 pixelpen = 0;
|
||||
UINT8 pixel = 0;
|
||||
if (hs == 4 && ascii & 0x80)
|
||||
if (hs == 4 && (ascii & 0x80))
|
||||
{
|
||||
UINT16 wpixelb = (pixelb << 8) + (*(pp+1));
|
||||
UINT16 wpixelr = (pixelr << 8) + (*(pp+0x4001));
|
||||
UINT16 wpixelg = (pixelg << 8) + (*(pp+0x8001));
|
||||
han2 = *(pv+0x1001);
|
||||
h1 = (ascii>>2)&0x1f;
|
||||
h2 = ((ascii<<3)|(han2>>5))&0x1f;
|
||||
h3 = (han2)&0x1f;
|
||||
pf = &m_font[0x2000+(h1 * 32) + (cho[h2] + (h3 != 0) -1) * 16 * 2 * 32 + n];
|
||||
hfnt = (*pf << 8) | (*(pf+16));
|
||||
pf = &m_font[0x4000+(h2 * 32) + (h3 == 0 ? 0 : 1) * 16 * 2 * 32 + n];
|
||||
hfnt = hfnt & ((*pf << 8) | (*(pf+16)));
|
||||
pf = &m_font[0x6000+(h3 * 32) + (jong[h2]-1) * 16 * 2 * 32 + n];
|
||||
hfnt = hfnt & ((*pf << 8) | (*(pf+16)));
|
||||
if (ascii != 0xfa)
|
||||
{
|
||||
han2 = *(pv+0x1001);
|
||||
h1 = (ascii>>2)&0x1f;
|
||||
h2 = ((ascii<<3)|(han2>>5))&0x1f;
|
||||
h3 = (han2)&0x1f;
|
||||
pf = &m_font[0x2000+(h1 * 32) + (cho[h2] + (h3 != 0) -1) * 16 * 2 * 32 + n];
|
||||
hfnt = (*pf << 8) | (*(pf+16));
|
||||
pf = &m_font[0x4000+(h2 * 32) + (h3 == 0 ? 0 : 1) * 16 * 2 * 32 + n];
|
||||
hfnt = hfnt & ((*pf << 8) | (*(pf+16)));
|
||||
pf = &m_font[0x6000+(h3 * 32) + (jong[h2]-1) * 16 * 2 * 32 + n];
|
||||
hfnt = hfnt & ((*pf << 8) | (*(pf+16)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ascii = *(pv+0x1001);
|
||||
pf = &m_font[0x6000+(ascii*32) + n];
|
||||
hfnt = (*pf << 8) | (*(pf+16));
|
||||
}
|
||||
hfnt = (inv ? 0xffff - hfnt : hfnt);
|
||||
//printf("0x%04x\n" , hfnt);
|
||||
for (j = 0x8000; j > 0; j>>=1)
|
||||
{
|
||||
pixel = ((wpixelg&j ? 4:0 )|(wpixelr&j? 2:0)|(wpixelb&j ? 1:0));
|
||||
@ -542,7 +582,7 @@ MC6845_UPDATE_ROW(spc1500_state::crtc_update_row)
|
||||
}
|
||||
else if (attr & 0x20)
|
||||
{
|
||||
UINT8 *pa = &m_pcgram[(ascii<<hs)+n];
|
||||
UINT8 *pa = &m_pcgram[(ascii*(m_crtc_vreg[0x9]+1))+n];
|
||||
UINT8 b = *pa;
|
||||
UINT8 r = *(pa+0x800);
|
||||
UINT8 g = *(pa+0x1000);
|
||||
@ -557,7 +597,6 @@ MC6845_UPDATE_ROW(spc1500_state::crtc_update_row)
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("%c", ascii);
|
||||
UINT8 fnt = m_font[(hs == 4 ? 0x1000 : (attr & (1<<6) ? 0x80<<4 : 0)) + (ascii<<4) + n];
|
||||
if (ascii == 0 && (attr & 0x08) && inv)
|
||||
{
|
||||
@ -821,6 +860,8 @@ void spc1500_state::machine_start()
|
||||
// intialize banks 2, 3, 4 (write banks)
|
||||
membank("bank2")->set_base(m_p_ram);
|
||||
membank("bank4")->set_base(m_p_ram + 0x8000);
|
||||
m_timer = timer_alloc(0);
|
||||
m_timer->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
void spc1500_state::machine_reset()
|
||||
@ -829,6 +870,7 @@ void spc1500_state::machine_reset()
|
||||
m_time = machine().scheduler().time();
|
||||
m_double_mode = false;
|
||||
memset(&m_paltbl[0], 1, 8);
|
||||
m_char_count = 0;
|
||||
}
|
||||
|
||||
READ8_MEMBER(spc1500_state::mc6845_videoram_r)
|
||||
@ -853,11 +895,6 @@ READ8_MEMBER( spc1500_state::porta_r )
|
||||
return data;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( spc1500_state::irq_w )
|
||||
{
|
||||
m_maincpu->set_input_line(0, state ? CLEAR_LINE : HOLD_LINE);
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( spc1500, spc1500_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu",Z80, XTAL_4MHz)
|
||||
@ -873,7 +910,6 @@ static MACHINE_CONFIG_START( spc1500, spc1500_state )
|
||||
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
|
||||
MCFG_SCREEN_SIZE(640, 400)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0,640-1,0,400-1)
|
||||
//MCFG_MC6845_VISAREA_ADJUST(50,50,640-50,400-50)
|
||||
MCFG_SCREEN_UPDATE_DEVICE("mc6845", mc6845_device, screen_update )
|
||||
MCFG_PALETTE_ADD("palette", 8)
|
||||
MCFG_PALETTE_INIT_OWNER(spc1500_state, spc)
|
||||
@ -890,6 +926,8 @@ static MACHINE_CONFIG_START( spc1500, spc1500_state )
|
||||
MCFG_I8255_OUT_PORTB_CB(WRITE8(spc1500_state, portb_w))
|
||||
MCFG_I8255_OUT_PORTC_CB(WRITE8(spc1500_state, portc_w))
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC("1hz", spc1500_state, timer, attotime::from_hz(1))
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
MCFG_SOUND_ADD("ay8910", AY8910, XTAL_4MHz / 2)
|
||||
@ -906,7 +944,7 @@ static MACHINE_CONFIG_START( spc1500, spc1500_state )
|
||||
|
||||
MCFG_CASSETTE_ADD("cassette")
|
||||
MCFG_CASSETTE_FORMATS(spc1000_cassette_formats)
|
||||
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_DISABLED)
|
||||
MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_SPEAKER_MUTED | CASSETTE_MOTOR_DISABLED)
|
||||
|
||||
MCFG_SOFTWARE_LIST_ADD("cass_list", "spc1500_cass")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user