mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
Preliminary SoC emulation for Sitronix ST2204 and ST2205U
This commit is contained in:
parent
7791be49e4
commit
27ddae4ecf
@ -1434,6 +1434,9 @@ end
|
||||
--@src/devices/cpu/m6502/m740.h,CPUS["M6502"] = true
|
||||
--@src/devices/cpu/m6502/m3745x.h,CPUS["M6502"] = true
|
||||
--@src/devices/cpu/m6502/m5074x.h,CPUS["M6502"] = true
|
||||
--@src/devices/cpu/m6502/st2xxx.h,CPUS["M6502"] = true
|
||||
--@src/devices/cpu/m6502/st2204.h,CPUS["M6502"] = true
|
||||
--@src/devices/cpu/m6502/st2205u.h,CPUS["M6502"] = true
|
||||
--@src/devices/cpu/m6502/xavix.h,CPUS["XAVIX"] = true
|
||||
--@src/devices/cpu/m6502/xavix.h,CPUS["XAVIX2000"] = true
|
||||
|
||||
@ -1479,6 +1482,12 @@ if (CPUS["M6502"]~=null) then
|
||||
MAME_DIR .. "src/devices/cpu/m6502/m3745x.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/m5074x.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/m5074x.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/st2xxx.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/st2xxx.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/st2204.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/st2204.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/st2205u.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/st2205u.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/xavix.cpp",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/xavix.h",
|
||||
MAME_DIR .. "src/devices/cpu/m6502/xavix2000.cpp",
|
||||
@ -1496,6 +1505,7 @@ if (CPUS["M6502"]~=null) then
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/on2a03.lst", GEN_DIR .. "emu/cpu/m6502/n2a03.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dn2a03.lst" }, {"@echo Generating n2a03 disassembler source file...", PYTHON .. " $(1) s n2a03 $(<) $(2) $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/om740.lst" , GEN_DIR .. "emu/cpu/m6502/m740.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dm740.lst" }, {"@echo Generating m740 disassembler source file...", PYTHON .. " $(1) s m740 $(<) $(2) $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/dr65c02.lst", GEN_DIR .. "emu/cpu/m6502/r65c02.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", }, {"@echo Generating r65c02 disassembler source file...", PYTHON .. " $(1) s r65c02 - $(<) $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/ost2xxx.lst" , GEN_DIR .. "emu/cpu/m6502/st2xxx.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dst2xxx.lst" }, {"@echo Generating st2xxx disassembler source file...", PYTHON .. " $(1) s st2xxx $(<) $(2) $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/oxavix.lst", GEN_DIR .. "emu/cpu/m6502/xavix.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dxavix.lst" }, {"@echo Generating xavix disassembler source file...", PYTHON .. " $(1) s xavix $(<) $(2) $(@)" }},
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/oxavix2000.lst", GEN_DIR .. "emu/cpu/m6502/xavix2000.hxx", { MAME_DIR .. "src/devices/cpu/m6502/m6502make.py", MAME_DIR .. "src/devices/cpu/m6502/dxavix2000.lst" }, {"@echo Generating xavix2000 disassembler source file...", PYTHON .. " $(1) s xavix2000 $(<) $(2) $(@)" }},
|
||||
}
|
||||
@ -1511,6 +1521,7 @@ if (CPUS["M6502"]~=null) then
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/n2a03.cpp", GEN_DIR .. "emu/cpu/m6502/n2a03.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/r65c02.cpp", GEN_DIR .. "emu/cpu/m6502/r65c02.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/m740.cpp", GEN_DIR .. "emu/cpu/m6502/m740.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/st2xxx.cpp", GEN_DIR .. "emu/cpu/m6502/st2xxx.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/xavix.cpp", GEN_DIR .. "emu/cpu/m6502/xavix.hxx" },
|
||||
{ MAME_DIR .. "src/devices/cpu/m6502/xavix2000.cpp", GEN_DIR .. "emu/cpu/m6502/xavix2000.hxx" },
|
||||
}
|
||||
|
20
src/devices/cpu/m6502/dst2xxx.lst
Normal file
20
src/devices/cpu/m6502/dst2xxx.lst
Normal file
@ -0,0 +1,20 @@
|
||||
# license:BSD-3-Clause
|
||||
# copyright-holders:Olivier Galibert
|
||||
# almost identical to r65c02
|
||||
brk_st_imp ora_idx nop_imm nop_c_imp tsb_zpg ora_zpg asl_c_zpg rmb_bzp php_imp ora_imm asl_acc nop_c_imp tsb_aba ora_aba asl_c_aba bbr_zpb
|
||||
bpl_rel ora_idy ora_zpi nop_c_imp trb_zpg ora_zpx asl_c_zpx rmb_bzp clc_imp ora_aby inc_acc nop_c_imp trb_aba ora_abx asl_c_abx bbr_zpb
|
||||
jsr_adr and_idx nop_imm nop_c_imp bit_zpg and_zpg rol_c_zpg rmb_bzp plp_imp and_imm rol_acc nop_c_imp bit_aba and_aba rol_c_aba bbr_zpb
|
||||
bmi_rel and_idy and_zpi nop_c_imp bit_zpx and_zpx rol_c_zpx rmb_bzp sec_imp and_aby dec_acc nop_c_imp bit_abx and_abx rol_c_abx bbr_zpb
|
||||
rti_st_imp eor_idx nop_imm nop_c_imp nop_zpg eor_zpg lsr_c_zpg rmb_bzp pha_imp eor_imm lsr_acc nop_c_imp jmp_adr eor_aba lsr_c_aba bbr_zpb
|
||||
bvc_rel eor_idy eor_zpi nop_c_imp nop_zpx eor_zpx lsr_c_zpx rmb_bzp cli_imp eor_aby phy_imp nop_c_imp nop_c_aba eor_abx lsr_c_abx bbr_zpb
|
||||
rts_imp adc_c_idx nop_imm nop_c_imp stz_zpg adc_c_zpg ror_c_zpg rmb_bzp pla_imp adc_c_imm ror_acc nop_c_imp jmp_c_ind adc_c_aba ror_c_aba bbr_zpb
|
||||
bvs_rel adc_c_idy adc_c_zpi nop_c_imp stz_zpx adc_c_zpx ror_c_zpx rmb_bzp sei_imp adc_c_aby ply_imp nop_c_imp jmp_iax adc_c_abx ror_c_abx bbr_zpb
|
||||
bra_rel sta_idx nop_imm nop_c_imp sty_zpg sta_zpg stx_zpg smb_bzp dey_imp bit_imm txa_imp nop_c_imp sty_aba sta_aba stx_aba bbs_zpb
|
||||
bcc_rel sta_idy sta_zpi nop_c_imp sty_zpx sta_zpx stx_zpy smb_bzp tya_imp sta_aby txs_imp nop_c_imp stz_aba sta_abx stz_abx bbs_zpb
|
||||
ldy_imm lda_idx ldx_imm nop_c_imp ldy_zpg lda_zpg ldx_zpg smb_bzp tay_imp lda_imm tax_imp nop_c_imp ldy_aba lda_aba ldx_aba bbs_zpb
|
||||
bcs_rel lda_idy lda_zpi nop_c_imp ldy_zpx lda_zpx ldx_zpy smb_bzp clv_imp lda_aby tsx_imp nop_c_imp ldy_abx lda_abx ldx_aby bbs_zpb
|
||||
cpy_imm cmp_idx nop_imm nop_c_imp cpy_zpg cmp_zpg dec_c_zpg smb_bzp iny_imp cmp_imm dex_imp wai_imp cpy_aba cmp_aba dec_c_aba bbs_zpb
|
||||
bne_rel cmp_idy cmp_zpi nop_c_imp nop_zpx cmp_zpx dec_c_zpx smb_bzp cld_imp cmp_aby phx_imp stp_imp nop_c_abx cmp_abx dec_c_abx bbs_zpb
|
||||
cpx_imm sbc_c_idx nop_imm nop_c_imp cpx_zpg sbc_c_zpg inc_c_zpg smb_bzp inx_imp sbc_c_imm nop_imp nop_c_imp cpx_aba sbc_c_aba inc_c_aba bbs_zpb
|
||||
beq_rel sbc_c_idy sbc_c_zpi nop_c_imp nop_zpx sbc_c_zpx inc_c_zpx smb_bzp sed_imp sbc_c_aby plx_imp nop_c_imp nop_c_abx sbc_c_abx inc_c_abx bbs_zpb
|
||||
reset_st
|
58
src/devices/cpu/m6502/ost2xxx.lst
Normal file
58
src/devices/cpu/m6502/ost2xxx.lst
Normal file
@ -0,0 +1,58 @@
|
||||
# license:BSD-3-Clause
|
||||
# copyright-holders:Olivier Galibert
|
||||
# m65c02 opcodes, with a twist
|
||||
|
||||
brk_st_imp
|
||||
if(irq_taken || nmi_state) {
|
||||
read_pc_noinc();
|
||||
} else {
|
||||
read_pc();
|
||||
}
|
||||
write(SP, PC >> 8);
|
||||
dec_SP();
|
||||
write(SP, PC);
|
||||
dec_SP();
|
||||
write(SP, irq_taken || nmi_state ? P & ~F_B : P);
|
||||
dec_SP();
|
||||
set_irq_service(true);
|
||||
if(irq_taken && nmi_state) { // NMI is not present on actual parts
|
||||
PC = read_vector(0x7ffa);
|
||||
PC = set_h(PC, read_vector(0x7ffb));
|
||||
nmi_state = false;
|
||||
} else if(irq_taken) {
|
||||
TMP = acknowledge_irq();
|
||||
PC = read_vector(0x7ff8 - (TMP << 1));
|
||||
PC = set_h(PC, read_vector(0x7ff9 - (TMP << 1)));
|
||||
} else {
|
||||
PC = read_vector(0x7ffe);
|
||||
PC = set_h(PC, read_vector(0x7fff));
|
||||
}
|
||||
irq_taken = false;
|
||||
P = (P | F_I) & ~F_D; // Do *not* move after the prefetch
|
||||
prefetch();
|
||||
inst_state = -1;
|
||||
|
||||
rti_st_imp
|
||||
read_pc_noinc();
|
||||
read(SP);
|
||||
inc_SP();
|
||||
P = read(SP) | (F_B|F_E);
|
||||
inc_SP();
|
||||
PC = read(SP);
|
||||
inc_SP();
|
||||
PC = set_h(PC, read(SP));
|
||||
set_irq_service(false);
|
||||
prefetch();
|
||||
|
||||
reset_st
|
||||
read_arg(0xffff);
|
||||
read_pc_noinc();
|
||||
read(SP); dec_SP();
|
||||
read(SP); dec_SP();
|
||||
read(SP); dec_SP();
|
||||
P = (P | F_I) & ~F_D;
|
||||
set_irq_service(false);
|
||||
PC = read_vector(0x7ffc);
|
||||
PC = set_h(PC, read_vector(0x7ffd));
|
||||
prefetch();
|
||||
inst_state = -1;
|
276
src/devices/cpu/m6502/st2204.cpp
Normal file
276
src/devices/cpu/m6502/st2204.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Sitronix ST2204 8-Bit Integrated Microcontroller
|
||||
|
||||
Functional blocks:
|
||||
* Interrupt controller (11 levels excluding BRK and RESET)
|
||||
* GPIO (6 ports, 8 bits each)
|
||||
* External bus (up to 7 CS outputs, 48M maximum addressable)
|
||||
* Timers/event counters with clocking outputs (2 plus base timer)
|
||||
* Programmable sound generator (2 channels plus DAC)
|
||||
* LCD controller (320x240 B/W or 240x160 4-gray)
|
||||
* Serial peripheral interface
|
||||
* UART (built-in BRG; RS-232 and IrDA modes)
|
||||
* Direct memory access
|
||||
* Power down modes (WAI-0, WAI-1, STP)
|
||||
* Watchdog timer
|
||||
* Low voltage detector
|
||||
* 512K ROM (may be disabled)
|
||||
* 10K RAM
|
||||
|
||||
Emulation is largely based on documentation for the ST2202, which
|
||||
has similar though somewhat lesser capabilities.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "st2204.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(ST2204, st2204_device, "st2204", "Sitronix ST2204 Integrated Microcontroller")
|
||||
|
||||
st2204_device::st2204_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: st2xxx_device(mconfig, ST2204, tag, owner, clock,
|
||||
address_map_constructor(FUNC(st2204_device::int_map), this),
|
||||
26, // logical; only 23 address lines are brought out
|
||||
0x0f7f)
|
||||
{
|
||||
}
|
||||
|
||||
void st2204_device::device_start()
|
||||
{
|
||||
std::unique_ptr<mi_st2204> intf = std::make_unique<mi_st2204>();
|
||||
intf->data = &space(AS_DATA);
|
||||
intf->dcache = space(AS_DATA).cache<0, 0, ENDIANNESS_LITTLE>();
|
||||
intf->irr_enable = false;
|
||||
intf->irr = 0;
|
||||
intf->prr = 0;
|
||||
intf->drr = 0;
|
||||
intf->irq_service = false;
|
||||
|
||||
save_item(NAME(m_pdata));
|
||||
save_item(NAME(m_pctrl));
|
||||
save_item(NAME(m_psel));
|
||||
save_item(NAME(m_pfun));
|
||||
save_item(NAME(m_sys));
|
||||
save_item(NAME(m_pmcr));
|
||||
save_item(NAME(m_ireq));
|
||||
save_item(NAME(m_iena));
|
||||
save_item(NAME(intf->irr_enable));
|
||||
save_item(NAME(intf->irr));
|
||||
save_item(NAME(intf->prr));
|
||||
save_item(NAME(intf->drr));
|
||||
save_item(NAME(intf->irq_service));
|
||||
|
||||
mintf = std::move(intf);
|
||||
init();
|
||||
|
||||
state_add(ST_IRR, "IRR", downcast<mi_st2204 &>(*mintf).irr).mask(0xff);
|
||||
state_add(ST_PRR, "PRR", downcast<mi_st2204 &>(*mintf).prr).mask(0xfff);
|
||||
state_add(ST_DRR, "DRR", downcast<mi_st2204 &>(*mintf).drr).mask(0x7ff);
|
||||
state_add<u8>(ST_IREQ, "IREQ", [this]() { return m_ireq; }, [this](u16 data) { m_ireq = data; update_irq_state(); }).mask(m_ireq_mask);
|
||||
state_add<u8>(ST_IENA, "IENA", [this]() { return m_iena; }, [this](u16 data) { m_iena = data; update_irq_state(); }).mask(m_ireq_mask);
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
state_add(ST_PDA + i, string_format("PD%c", 'A' + i).c_str(), m_pdata[i]);
|
||||
state_add(ST_PCA + i, string_format("PC%c", 'A' + i).c_str(), m_pctrl[i]);
|
||||
if (i == 2)
|
||||
state_add(ST_PSA + i, string_format("PS%c", 'A' + i).c_str(), m_psel[i]);
|
||||
if (i == 2 || i == 3)
|
||||
state_add(ST_PFC + i - 2, string_format("PF%c", 'A' + i).c_str(), m_pfun[i - 2]);
|
||||
}
|
||||
state_add(ST_PDL, "PDL", m_pdata[6]);
|
||||
state_add(ST_PCL, "PCL", m_pctrl[6]);
|
||||
state_add(ST_PMCR, "PMCR", m_pmcr);
|
||||
state_add<u8>(ST_SYS, "SYS", [this]() { return m_sys; }, [this](u8 data) { sys_w(data); });
|
||||
}
|
||||
|
||||
void st2204_device::device_reset()
|
||||
{
|
||||
st2xxx_device::device_reset();
|
||||
|
||||
mi_st2204 &m = downcast<mi_st2204 &>(*mintf);
|
||||
m.irr_enable = false;
|
||||
m.irr = 0;
|
||||
m.prr = 0;
|
||||
m.drr = 0;
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::pread(u16 adr)
|
||||
{
|
||||
u16 bank = irq_service && irr_enable ? irr : prr;
|
||||
return data->read_byte(u32(bank ^ 1) << 14 | (adr & 0x3fff));
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::preadc(u16 adr)
|
||||
{
|
||||
u16 bank = irq_service && irr_enable ? irr : prr;
|
||||
return dcache->read_byte(u32(bank ^ 1) << 14 | (adr & 0x3fff));
|
||||
}
|
||||
|
||||
void st2204_device::mi_st2204::pwrite(u16 adr, u8 val)
|
||||
{
|
||||
u16 bank = irq_service && irr_enable ? irr : prr;
|
||||
data->write_byte(u32(bank ^ 1) << 14 | (adr & 0x3fff), val);
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::dread(u16 adr)
|
||||
{
|
||||
return data->read_byte(u32(drr) << 15 | (adr & 0x7fff));
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::dreadc(u16 adr)
|
||||
{
|
||||
return dcache->read_byte(u32(drr) << 15 | (adr & 0x7fff));
|
||||
}
|
||||
|
||||
void st2204_device::mi_st2204::dwrite(u16 adr, u8 val)
|
||||
{
|
||||
data->write_byte(u32(drr) << 15 | (adr & 0x7fff), val);
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::read(u16 adr)
|
||||
{
|
||||
return program->read_byte(adr);
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::read_sync(u16 adr)
|
||||
{
|
||||
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : cache->read_byte(adr);
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::read_arg(u16 adr)
|
||||
{
|
||||
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : cache->read_byte(adr);
|
||||
}
|
||||
|
||||
u8 st2204_device::mi_st2204::read_vector(u16 adr)
|
||||
{
|
||||
return pread(adr);
|
||||
}
|
||||
|
||||
void st2204_device::mi_st2204::write(u16 adr, u8 val)
|
||||
{
|
||||
program->write_byte(adr, val);
|
||||
}
|
||||
|
||||
u8 st2204_device::pmcr_r()
|
||||
{
|
||||
return m_pmcr;
|
||||
}
|
||||
|
||||
void st2204_device::pmcr_w(u8 data)
|
||||
{
|
||||
m_pmcr = data;
|
||||
}
|
||||
|
||||
u8 st2204_device::sys_r()
|
||||
{
|
||||
return m_sys | 0x01;
|
||||
}
|
||||
|
||||
void st2204_device::sys_w(u8 data)
|
||||
{
|
||||
m_sys = data;
|
||||
downcast<mi_st2204 &>(*mintf).irr_enable = BIT(data, 2);
|
||||
}
|
||||
|
||||
u8 st2204_device::irr_r()
|
||||
{
|
||||
return downcast<mi_st2204 &>(*mintf).irr;
|
||||
}
|
||||
|
||||
void st2204_device::irr_w(u8 data)
|
||||
{
|
||||
downcast<mi_st2204 &>(*mintf).irr = data;
|
||||
}
|
||||
|
||||
u8 st2204_device::prrl_r()
|
||||
{
|
||||
return downcast<mi_st2204 &>(*mintf).prr & 0xff;
|
||||
}
|
||||
|
||||
void st2204_device::prrl_w(u8 data)
|
||||
{
|
||||
u16 &prr = downcast<mi_st2204 &>(*mintf).prr;
|
||||
prr = data | (prr & 0x0f00);
|
||||
}
|
||||
|
||||
u8 st2204_device::prrh_r()
|
||||
{
|
||||
return downcast<mi_st2204 &>(*mintf).prr >> 8;
|
||||
}
|
||||
|
||||
void st2204_device::prrh_w(u8 data)
|
||||
{
|
||||
u16 &prr = downcast<mi_st2204 &>(*mintf).prr;
|
||||
prr = (data & 0x0f) << 16 | (prr & 0x00ff);
|
||||
}
|
||||
|
||||
u8 st2204_device::drrl_r()
|
||||
{
|
||||
return downcast<mi_st2204 &>(*mintf).drr & 0xff;
|
||||
}
|
||||
|
||||
void st2204_device::drrl_w(u8 data)
|
||||
{
|
||||
u16 &drr = downcast<mi_st2204 &>(*mintf).drr;
|
||||
drr = data | (drr & 0x0700);
|
||||
}
|
||||
|
||||
u8 st2204_device::drrh_r()
|
||||
{
|
||||
return downcast<mi_st2204 &>(*mintf).drr >> 8;
|
||||
}
|
||||
|
||||
void st2204_device::drrh_w(u8 data)
|
||||
{
|
||||
u16 &drr = downcast<mi_st2204 &>(*mintf).drr;
|
||||
drr = (data & 0x07) << 16 | (drr & 0x00ff);
|
||||
}
|
||||
|
||||
u8 st2204_device::pmem_r(offs_t offset)
|
||||
{
|
||||
return downcast<mi_st2204 &>(*mintf).pread(offset);
|
||||
}
|
||||
|
||||
void st2204_device::pmem_w(offs_t offset, u8 data)
|
||||
{
|
||||
downcast<mi_st2204 &>(*mintf).pwrite(offset, data);
|
||||
}
|
||||
|
||||
u8 st2204_device::dmem_r(offs_t offset)
|
||||
{
|
||||
return downcast<mi_st2204 &>(*mintf).dread(offset);
|
||||
}
|
||||
|
||||
void st2204_device::dmem_w(offs_t offset, u8 data)
|
||||
{
|
||||
downcast<mi_st2204 &>(*mintf).dwrite(offset, data);
|
||||
}
|
||||
|
||||
void st2204_device::int_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0004).rw(FUNC(st2204_device::pdata_r), FUNC(st2204_device::pdata_w));
|
||||
map(0x0005, 0x0005).rw(FUNC(st2204_device::psc_r), FUNC(st2204_device::psc_w));
|
||||
map(0x0008, 0x000c).rw(FUNC(st2204_device::pdata_r), FUNC(st2204_device::pdata_w));
|
||||
map(0x000d, 0x000d).rw(FUNC(st2204_device::pfc_r), FUNC(st2204_device::pfc_w));
|
||||
map(0x000e, 0x000e).rw(FUNC(st2204_device::pfd_r), FUNC(st2204_device::pfd_w));
|
||||
map(0x000f, 0x000f).rw(FUNC(st2204_device::pmcr_r), FUNC(st2204_device::pmcr_w));
|
||||
map(0x0030, 0x0030).rw(FUNC(st2204_device::sys_r), FUNC(st2204_device::sys_w));
|
||||
map(0x0031, 0x0031).rw(FUNC(st2204_device::irr_r), FUNC(st2204_device::irr_w));
|
||||
map(0x0032, 0x0032).rw(FUNC(st2204_device::prrl_r), FUNC(st2204_device::prrl_w));
|
||||
map(0x0033, 0x0033).rw(FUNC(st2204_device::prrh_r), FUNC(st2204_device::prrh_w));
|
||||
map(0x0034, 0x0034).rw(FUNC(st2204_device::drrl_r), FUNC(st2204_device::drrl_w));
|
||||
map(0x0035, 0x0035).rw(FUNC(st2204_device::drrh_r), FUNC(st2204_device::drrh_w));
|
||||
map(0x003c, 0x003c).rw(FUNC(st2204_device::ireql_r), FUNC(st2204_device::ireql_w));
|
||||
map(0x003d, 0x003d).rw(FUNC(st2204_device::ireqh_r), FUNC(st2204_device::ireqh_w));
|
||||
map(0x003e, 0x003e).rw(FUNC(st2204_device::ienal_r), FUNC(st2204_device::ienal_w));
|
||||
map(0x003f, 0x003f).rw(FUNC(st2204_device::ienah_r), FUNC(st2204_device::ienah_w));
|
||||
map(0x004c, 0x004c).rw(FUNC(st2204_device::pl_r), FUNC(st2204_device::pl_w));
|
||||
map(0x004e, 0x004e).w(FUNC(st2204_device::pcl_w));
|
||||
map(0x0080, 0x27ff).ram(); // 10K internal SRAM; extent of mapping guessed
|
||||
map(0x4000, 0x7fff).rw(FUNC(st2204_device::pmem_r), FUNC(st2204_device::pmem_w));
|
||||
map(0x8000, 0xffff).rw(FUNC(st2204_device::dmem_r), FUNC(st2204_device::dmem_w));
|
||||
}
|
72
src/devices/cpu/m6502/st2204.h
Normal file
72
src/devices/cpu/m6502/st2204.h
Normal file
@ -0,0 +1,72 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Sitronix ST2204 8-Bit Integrated Microcontroller
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_M6502_ST2204_H
|
||||
#define MAME_CPU_M6502_ST2204_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "st2xxx.h"
|
||||
|
||||
class st2204_device : public st2xxx_device
|
||||
{
|
||||
public:
|
||||
st2204_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
class mi_st2204 : public mi_st2xxx {
|
||||
public:
|
||||
virtual u8 read(u16 adr) override;
|
||||
virtual u8 read_sync(u16 adr) override;
|
||||
virtual u8 read_arg(u16 adr) override;
|
||||
virtual u8 read_vector(u16 adr) override;
|
||||
virtual void write(u16 adr, u8 val) override;
|
||||
|
||||
u8 pread(u16 adr);
|
||||
u8 preadc(u16 adr);
|
||||
void pwrite(u16 adr, u8 val);
|
||||
u8 dread(u16 adr);
|
||||
u8 dreadc(u16 adr);
|
||||
void dwrite(u16 adr, u8 val);
|
||||
|
||||
bool irr_enable;
|
||||
u8 irr;
|
||||
u16 prr;
|
||||
u16 drr;
|
||||
};
|
||||
|
||||
u8 sys_r();
|
||||
void sys_w(u8 data);
|
||||
u8 irr_r();
|
||||
void irr_w(u8 data);
|
||||
u8 prrl_r();
|
||||
void prrl_w(u8 data);
|
||||
u8 prrh_r();
|
||||
void prrh_w(u8 data);
|
||||
u8 drrl_r();
|
||||
void drrl_w(u8 data);
|
||||
u8 drrh_r();
|
||||
void drrh_w(u8 data);
|
||||
u8 pmcr_r();
|
||||
void pmcr_w(u8 data);
|
||||
|
||||
u8 pmem_r(offs_t offset);
|
||||
void pmem_w(offs_t offset, u8 data);
|
||||
u8 dmem_r(offs_t offset);
|
||||
void dmem_w(offs_t offset, u8 data);
|
||||
|
||||
void int_map(address_map &map);
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(ST2204, st2204_device)
|
||||
|
||||
#endif // MAME_MACHINE_M6502_ST2204_H
|
400
src/devices/cpu/m6502/st2205u.cpp
Normal file
400
src/devices/cpu/m6502/st2205u.cpp
Normal file
@ -0,0 +1,400 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Sitronix ST2205U 8-Bit Integrated Microcontroller
|
||||
|
||||
Functional blocks:
|
||||
* Interrupt controller (15 levels excluding BRK and RESET)
|
||||
* GPIO (7 ports, 8 bits each)
|
||||
* External bus (up to 7 CS outputs, 48M maximum addressable)
|
||||
* Timers/event counters with clocking outputs (4 plus base timer)
|
||||
* Programmable sound generator (4 channels with FIFOs, plus PWM
|
||||
or ADPCM DAC and 16x8 signed multiplicator)
|
||||
* LCD controller (640x400 B/W, 400x320 4-gray, 160xRGBx120 16-gray)
|
||||
* Serial peripheral interface
|
||||
* UART (built-in BRG; RS-232 and IrDA modes)
|
||||
* USB 1.1 (separate control and bulk transfer endpoint buffers)
|
||||
* Direct memory access
|
||||
* NAND/AND Flash memory interface (includes ECC generator)
|
||||
* Power down modes (WAI-0, WAI-1, STP)
|
||||
* Watchdog timer
|
||||
* Real time clock (seconds, minutes, hours with alarm interrupts)
|
||||
* Low voltage detector with reset
|
||||
* 512K ROM (may be disabled)
|
||||
* 32K SRAM
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "st2205u.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(ST2205U, st2205u_device, "st2205", "Sitronix ST2205U Integrated Microcontroller")
|
||||
|
||||
st2205u_device::st2205u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: st2xxx_device(mconfig, ST2205U, tag, owner, clock,
|
||||
address_map_constructor(FUNC(st2205u_device::int_map), this),
|
||||
26, // logical; only 23 address lines are brought out
|
||||
0xdfff)
|
||||
, m_lvctr(0)
|
||||
{
|
||||
}
|
||||
|
||||
void st2205u_device::device_start()
|
||||
{
|
||||
std::unique_ptr<mi_st2205u> intf = std::make_unique<mi_st2205u>();
|
||||
intf->data = &space(AS_DATA);
|
||||
intf->dcache = space(AS_DATA).cache<0, 0, ENDIANNESS_LITTLE>();
|
||||
intf->irr_enable = false;
|
||||
intf->irr = 0;
|
||||
intf->prr = 0;
|
||||
intf->drr = 0;
|
||||
intf->brr = 0;
|
||||
intf->irq_service = false;
|
||||
|
||||
intf->ram = make_unique_clear<u8[]>(0x8000);
|
||||
|
||||
save_item(NAME(m_pdata));
|
||||
save_item(NAME(m_pctrl));
|
||||
save_item(NAME(m_psel));
|
||||
save_item(NAME(m_pfun));
|
||||
save_item(NAME(m_sys));
|
||||
save_item(NAME(m_pmcr));
|
||||
save_item(NAME(m_ireq));
|
||||
save_item(NAME(m_iena));
|
||||
save_item(NAME(m_lvctr));
|
||||
save_item(NAME(intf->irr_enable));
|
||||
save_item(NAME(intf->irr));
|
||||
save_item(NAME(intf->prr));
|
||||
save_item(NAME(intf->drr));
|
||||
save_item(NAME(intf->brr));
|
||||
save_item(NAME(intf->irq_service));
|
||||
save_pointer(NAME(intf->ram), 0x8000);
|
||||
|
||||
mintf = std::move(intf);
|
||||
init();
|
||||
|
||||
state_add(ST_IRR, "IRR", downcast<mi_st2205u &>(*mintf).irr).mask(0x87ff);
|
||||
state_add(ST_PRR, "PRR", downcast<mi_st2205u &>(*mintf).prr).mask(0x87ff);
|
||||
state_add(ST_DRR, "DRR", downcast<mi_st2205u &>(*mintf).drr).mask(0x8fff);
|
||||
state_add(ST_BRR, "BRR", downcast<mi_st2205u &>(*mintf).brr).mask(0x9fff);
|
||||
state_add<u8>(ST_IREQ, "IREQ", [this]() { return m_ireq; }, [this](u16 data) { m_ireq = data; update_irq_state(); }).mask(m_ireq_mask);
|
||||
state_add<u8>(ST_IENA, "IENA", [this]() { return m_iena; }, [this](u16 data) { m_iena = data; update_irq_state(); }).mask(m_ireq_mask);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
state_add(ST_PDA + i, string_format("PD%c", 'A' + i).c_str(), m_pdata[i]);
|
||||
state_add(ST_PCA + i, string_format("PC%c", 'A' + i).c_str(), m_pctrl[i]);
|
||||
if (i == 2 || i == 4)
|
||||
state_add(ST_PSA + i, string_format("PS%c", 'A' + i).c_str(), m_psel[i]);
|
||||
if (i == 2 || i == 3)
|
||||
state_add(ST_PFC + i - 2, string_format("PF%c", 'A' + i).c_str(), m_pfun[i - 2]).mask(i == 2 ? 0xfe : 0xff);
|
||||
}
|
||||
state_add(ST_PDL, "PDL", m_pdata[6]);
|
||||
state_add(ST_PCL, "PCL", m_pctrl[6]);
|
||||
state_add(ST_PMCR, "PMCR", m_pmcr);
|
||||
state_add<u8>(ST_SYS, "SYS", [this]() { return m_sys; }, [this](u8 data) { sys_w(data); }).mask(0xfe);
|
||||
state_add(ST_LVCTR, "LVCTR", m_lvctr).mask(0x0f);
|
||||
}
|
||||
|
||||
void st2205u_device::device_reset()
|
||||
{
|
||||
st2xxx_device::device_reset();
|
||||
|
||||
mi_st2205u &m = downcast<mi_st2205u &>(*mintf);
|
||||
m.irr_enable = false;
|
||||
m.irr = 0;
|
||||
m.prr = 0;
|
||||
m.drr = 0;
|
||||
|
||||
m_lvctr = 0;
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::pread(u16 adr)
|
||||
{
|
||||
u16 bank = irq_service ? irr : prr;
|
||||
if (BIT(bank, 15))
|
||||
return ram[0x4000 | (adr & 0x3fff)];
|
||||
else
|
||||
return data->read_byte(u32(bank) << 14 | (adr & 0x3fff));
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::preadc(u16 adr)
|
||||
{
|
||||
u16 bank = irq_service ? irr : prr;
|
||||
if (BIT(bank, 15))
|
||||
return ram[0x4000 | (adr & 0x3fff)];
|
||||
else
|
||||
return dcache->read_byte(u32(bank) << 14 | (adr & 0x3fff));
|
||||
}
|
||||
|
||||
void st2205u_device::mi_st2205u::pwrite(u16 adr, u8 val)
|
||||
{
|
||||
u16 bank = irq_service ? irr : prr;
|
||||
if (BIT(bank, 15))
|
||||
ram[0x4000 | (adr & 0x3fff)] = val;
|
||||
else
|
||||
data->write_byte(u32(bank) << 14 | (adr & 0x3fff), val);
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::dread(u16 adr)
|
||||
{
|
||||
if (BIT(drr, 15))
|
||||
return ram[adr & 0x7fff];
|
||||
else
|
||||
return data->read_byte(u32(drr) << 15 | (adr & 0x7fff));
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::dreadc(u16 adr)
|
||||
{
|
||||
if (BIT(drr, 15))
|
||||
return ram[adr & 0x7fff];
|
||||
else
|
||||
return dcache->read_byte(u32(drr) << 15 | (adr & 0x7fff));
|
||||
}
|
||||
|
||||
void st2205u_device::mi_st2205u::dwrite(u16 adr, u8 val)
|
||||
{
|
||||
if (BIT(drr, 15))
|
||||
ram[adr & 0x7fff] = val;
|
||||
else
|
||||
data->write_byte(u32(drr) << 15 | (adr & 0x7fff), val);
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::bread(u16 adr)
|
||||
{
|
||||
if (BIT(brr, 15))
|
||||
return ram[0x2000 | (adr & 0x1fff)];
|
||||
else
|
||||
return data->read_byte(u32(brr) << 13 | (adr & 0x1fff));
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::breadc(u16 adr)
|
||||
{
|
||||
if (BIT(brr, 15))
|
||||
return ram[0x2000 | (adr & 0x1fff)];
|
||||
else
|
||||
return dcache->read_byte(u32(brr) << 13 | (adr & 0x1fff));
|
||||
}
|
||||
|
||||
void st2205u_device::mi_st2205u::bwrite(u16 adr, u8 val)
|
||||
{
|
||||
if (BIT(brr, 15))
|
||||
ram[0x2000 | (adr & 0x1fff)] = val;
|
||||
else
|
||||
data->write_byte(u32(brr) << 13 | (adr & 0x1fff), val);
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::read(u16 adr)
|
||||
{
|
||||
return program->read_byte(adr);
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::read_sync(u16 adr)
|
||||
{
|
||||
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : BIT(adr, 13) ? breadc(adr) : cache->read_byte(adr);
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::read_arg(u16 adr)
|
||||
{
|
||||
return BIT(adr, 15) ? dreadc(adr) : BIT(adr, 14) ? preadc(adr) : BIT(adr, 13) ? breadc(adr) : cache->read_byte(adr);
|
||||
}
|
||||
|
||||
u8 st2205u_device::mi_st2205u::read_vector(u16 adr)
|
||||
{
|
||||
return pread(adr);
|
||||
}
|
||||
|
||||
void st2205u_device::mi_st2205u::write(u16 adr, u8 val)
|
||||
{
|
||||
program->write_byte(adr, val);
|
||||
}
|
||||
|
||||
u8 st2205u_device::irrl_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).irr & 0xff;
|
||||
}
|
||||
|
||||
void st2205u_device::irrl_w(u8 data)
|
||||
{
|
||||
u16 &irr = downcast<mi_st2205u &>(*mintf).irr;
|
||||
irr = data | (irr & 0x8f00);
|
||||
}
|
||||
|
||||
u8 st2205u_device::irrh_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).irr >> 8;
|
||||
}
|
||||
|
||||
void st2205u_device::irrh_w(u8 data)
|
||||
{
|
||||
u16 &irr = downcast<mi_st2205u &>(*mintf).irr;
|
||||
irr = (data & 0x8f) << 16 | (irr & 0x00ff);
|
||||
}
|
||||
|
||||
u8 st2205u_device::prrl_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).prr & 0xff;
|
||||
}
|
||||
|
||||
void st2205u_device::prrl_w(u8 data)
|
||||
{
|
||||
u16 &prr = downcast<mi_st2205u &>(*mintf).prr;
|
||||
prr = data | (prr & 0x8f00);
|
||||
}
|
||||
|
||||
u8 st2205u_device::prrh_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).prr >> 8;
|
||||
}
|
||||
|
||||
void st2205u_device::prrh_w(u8 data)
|
||||
{
|
||||
u16 &prr = downcast<mi_st2205u &>(*mintf).prr;
|
||||
prr = (data & 0x8f) << 16 | (prr & 0x00ff);
|
||||
}
|
||||
|
||||
u8 st2205u_device::drrl_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).drr & 0xff;
|
||||
}
|
||||
|
||||
void st2205u_device::drrl_w(u8 data)
|
||||
{
|
||||
u16 &drr = downcast<mi_st2205u &>(*mintf).drr;
|
||||
drr = data | (drr & 0x8700);
|
||||
}
|
||||
|
||||
u8 st2205u_device::drrh_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).drr >> 8;
|
||||
}
|
||||
|
||||
void st2205u_device::drrh_w(u8 data)
|
||||
{
|
||||
u16 &drr = downcast<mi_st2205u &>(*mintf).drr;
|
||||
drr = (data & 0x87) << 16 | (drr & 0x00ff);
|
||||
}
|
||||
|
||||
u8 st2205u_device::brrl_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).brr & 0xff;
|
||||
}
|
||||
|
||||
void st2205u_device::brrl_w(u8 data)
|
||||
{
|
||||
u16 &brr = downcast<mi_st2205u &>(*mintf).brr;
|
||||
brr = data | (brr & 0x9f00);
|
||||
}
|
||||
|
||||
u8 st2205u_device::brrh_r()
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).brr >> 8;
|
||||
}
|
||||
|
||||
void st2205u_device::brrh_w(u8 data)
|
||||
{
|
||||
u16 &brr = downcast<mi_st2205u &>(*mintf).brr;
|
||||
brr = (data & 0x9f) << 16 | (brr & 0x00ff);
|
||||
}
|
||||
|
||||
u8 st2205u_device::pmcr_r()
|
||||
{
|
||||
return m_pmcr;
|
||||
}
|
||||
|
||||
void st2205u_device::pmcr_w(u8 data)
|
||||
{
|
||||
m_pmcr = data;
|
||||
}
|
||||
|
||||
u8 st2205u_device::sys_r()
|
||||
{
|
||||
return m_sys;
|
||||
}
|
||||
|
||||
void st2205u_device::sys_w(u8 data)
|
||||
{
|
||||
m_sys = data & 0xfe;
|
||||
downcast<mi_st2205u &>(*mintf).irr_enable = BIT(data, 2);
|
||||
}
|
||||
|
||||
u8 st2205u_device::lvctr_r()
|
||||
{
|
||||
return m_lvctr | 0x01;
|
||||
}
|
||||
|
||||
void st2205u_device::lvctr_w(u8 data)
|
||||
{
|
||||
m_lvctr = data & 0x0f;
|
||||
}
|
||||
|
||||
u8 st2205u_device::ram_r(offs_t offset)
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).ram[0x0080 + offset];
|
||||
}
|
||||
|
||||
void st2205u_device::ram_w(offs_t offset, u8 data)
|
||||
{
|
||||
downcast<mi_st2205u &>(*mintf).ram[0x0080 + offset] = data;
|
||||
}
|
||||
|
||||
u8 st2205u_device::pmem_r(offs_t offset)
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).pread(offset);
|
||||
}
|
||||
|
||||
void st2205u_device::pmem_w(offs_t offset, u8 data)
|
||||
{
|
||||
downcast<mi_st2205u &>(*mintf).pwrite(offset, data);
|
||||
}
|
||||
|
||||
u8 st2205u_device::dmem_r(offs_t offset)
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).dread(offset);
|
||||
}
|
||||
|
||||
void st2205u_device::dmem_w(offs_t offset, u8 data)
|
||||
{
|
||||
downcast<mi_st2205u &>(*mintf).dwrite(offset, data);
|
||||
}
|
||||
|
||||
u8 st2205u_device::bmem_r(offs_t offset)
|
||||
{
|
||||
return downcast<mi_st2205u &>(*mintf).bread(offset);
|
||||
}
|
||||
|
||||
void st2205u_device::bmem_w(offs_t offset, u8 data)
|
||||
{
|
||||
downcast<mi_st2205u &>(*mintf).bwrite(offset, data);
|
||||
}
|
||||
|
||||
void st2205u_device::int_map(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0005).rw(FUNC(st2205u_device::pdata_r), FUNC(st2205u_device::pdata_w));
|
||||
map(0x0006, 0x0006).rw(FUNC(st2205u_device::psc_r), FUNC(st2205u_device::psc_w));
|
||||
map(0x0007, 0x0007).rw(FUNC(st2205u_device::pse_r), FUNC(st2205u_device::pse_w));
|
||||
map(0x0008, 0x000d).rw(FUNC(st2205u_device::pctrl_r), FUNC(st2205u_device::pctrl_w));
|
||||
map(0x000e, 0x000e).rw(FUNC(st2205u_device::pfc_r), FUNC(st2205u_device::pfc_w));
|
||||
map(0x000f, 0x000f).rw(FUNC(st2205u_device::pfd_r), FUNC(st2205u_device::pfd_w));
|
||||
map(0x0030, 0x0030).rw(FUNC(st2205u_device::irrl_r), FUNC(st2205u_device::irrl_w));
|
||||
map(0x0031, 0x0031).rw(FUNC(st2205u_device::irrh_r), FUNC(st2205u_device::irrh_w));
|
||||
map(0x0032, 0x0032).rw(FUNC(st2205u_device::prrl_r), FUNC(st2205u_device::prrl_w));
|
||||
map(0x0033, 0x0033).rw(FUNC(st2205u_device::prrh_r), FUNC(st2205u_device::prrh_w));
|
||||
map(0x0034, 0x0034).rw(FUNC(st2205u_device::drrl_r), FUNC(st2205u_device::drrl_w));
|
||||
map(0x0035, 0x0035).rw(FUNC(st2205u_device::drrh_r), FUNC(st2205u_device::drrh_w));
|
||||
map(0x0036, 0x0036).rw(FUNC(st2205u_device::brrl_r), FUNC(st2205u_device::brrl_w));
|
||||
map(0x0037, 0x0037).rw(FUNC(st2205u_device::brrh_r), FUNC(st2205u_device::brrh_w));
|
||||
map(0x0039, 0x0039).rw(FUNC(st2205u_device::sys_r), FUNC(st2205u_device::sys_w));
|
||||
map(0x003a, 0x003a).rw(FUNC(st2205u_device::pmcr_r), FUNC(st2205u_device::pmcr_w));
|
||||
map(0x003c, 0x003c).rw(FUNC(st2205u_device::ireql_r), FUNC(st2205u_device::ireql_w));
|
||||
map(0x003d, 0x003d).rw(FUNC(st2205u_device::ireqh_r), FUNC(st2205u_device::ireqh_w));
|
||||
map(0x003e, 0x003e).rw(FUNC(st2205u_device::ienal_r), FUNC(st2205u_device::ienal_w));
|
||||
map(0x003f, 0x003f).rw(FUNC(st2205u_device::ienah_r), FUNC(st2205u_device::ienah_w));
|
||||
map(0x004e, 0x004e).rw(FUNC(st2205u_device::pl_r), FUNC(st2205u_device::pl_w));
|
||||
map(0x004f, 0x004f).rw(FUNC(st2205u_device::pcl_r), FUNC(st2205u_device::pcl_w));
|
||||
map(0x0057, 0x0057).rw(FUNC(st2205u_device::lvctr_r), FUNC(st2205u_device::lvctr_w));
|
||||
map(0x0080, 0x1fff).rw(FUNC(st2205u_device::ram_r), FUNC(st2205u_device::ram_w)); // assumed to be shared with banked RAM
|
||||
map(0x2000, 0x3fff).rw(FUNC(st2205u_device::bmem_r), FUNC(st2205u_device::bmem_w));
|
||||
map(0x4000, 0x7fff).rw(FUNC(st2205u_device::pmem_r), FUNC(st2205u_device::pmem_w));
|
||||
map(0x8000, 0xffff).rw(FUNC(st2205u_device::dmem_r), FUNC(st2205u_device::dmem_w));
|
||||
}
|
97
src/devices/cpu/m6502/st2205u.h
Normal file
97
src/devices/cpu/m6502/st2205u.h
Normal file
@ -0,0 +1,97 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Sitronix ST2205U 8-Bit Integrated Microcontroller
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_CPU_M6502_ST2205U_H
|
||||
#define MAME_CPU_M6502_ST2205U_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "st2xxx.h"
|
||||
|
||||
class st2205u_device : public st2xxx_device
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
ST_BRR = ST_IENA + 1,
|
||||
ST_LVCTR
|
||||
};
|
||||
|
||||
st2205u_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
class mi_st2205u : public mi_st2xxx {
|
||||
public:
|
||||
virtual u8 read(u16 adr) override;
|
||||
virtual u8 read_sync(u16 adr) override;
|
||||
virtual u8 read_arg(u16 adr) override;
|
||||
virtual u8 read_vector(u16 adr) override;
|
||||
virtual void write(u16 adr, u8 val) override;
|
||||
|
||||
u8 pread(u16 adr);
|
||||
u8 preadc(u16 adr);
|
||||
void pwrite(u16 adr, u8 val);
|
||||
u8 dread(u16 adr);
|
||||
u8 dreadc(u16 adr);
|
||||
void dwrite(u16 adr, u8 val);
|
||||
u8 bread(u16 adr);
|
||||
u8 breadc(u16 adr);
|
||||
void bwrite(u16 adr, u8 val);
|
||||
|
||||
bool irr_enable;
|
||||
u16 irr;
|
||||
u16 prr;
|
||||
u16 drr;
|
||||
u16 brr;
|
||||
|
||||
std::unique_ptr<u8[]> ram;
|
||||
};
|
||||
|
||||
u8 irrl_r();
|
||||
void irrl_w(u8 data);
|
||||
u8 irrh_r();
|
||||
void irrh_w(u8 data);
|
||||
u8 prrl_r();
|
||||
void prrl_w(u8 data);
|
||||
u8 prrh_r();
|
||||
void prrh_w(u8 data);
|
||||
u8 drrl_r();
|
||||
void drrl_w(u8 data);
|
||||
u8 drrh_r();
|
||||
void drrh_w(u8 data);
|
||||
u8 brrl_r();
|
||||
void brrl_w(u8 data);
|
||||
u8 brrh_r();
|
||||
void brrh_w(u8 data);
|
||||
u8 sys_r();
|
||||
void sys_w(u8 data);
|
||||
u8 pmcr_r();
|
||||
void pmcr_w(u8 data);
|
||||
u8 lvctr_r();
|
||||
void lvctr_w(u8 data);
|
||||
|
||||
u8 ram_r(offs_t offset);
|
||||
void ram_w(offs_t offset, u8 data);
|
||||
u8 pmem_r(offs_t offset);
|
||||
void pmem_w(offs_t offset, u8 data);
|
||||
u8 dmem_r(offs_t offset);
|
||||
void dmem_w(offs_t offset, u8 data);
|
||||
u8 bmem_r(offs_t offset);
|
||||
void bmem_w(offs_t offset, u8 data);
|
||||
|
||||
void int_map(address_map &map);
|
||||
|
||||
u8 m_lvctr;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(ST2205U, st2205u_device)
|
||||
|
||||
#endif // MAME_MACHINE_M6502_ST2205_H
|
252
src/devices/cpu/m6502/st2xxx.cpp
Normal file
252
src/devices/cpu/m6502/st2xxx.cpp
Normal file
@ -0,0 +1,252 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:AJR
|
||||
/**********************************************************************
|
||||
|
||||
Sitronix ST2XXX LCD MCUs
|
||||
|
||||
This extended SoC family combines a 65C02 CPU core (including the
|
||||
Rockwell bit opcodes) with a wide variety of on-chip peripherals.
|
||||
Features common to all besides internal RAM and ROM are parallel
|
||||
ports, internal timers, a multi-level interrupt controller, LCD
|
||||
controllers (of varying degrees of sophistication), R/C/slow XTAL
|
||||
clock generators, power management and PSG channels for speaker
|
||||
output. Each MCU also has numerous pins dedicated to LCD segment
|
||||
drivers, an external bus addressing several MB of off-chip
|
||||
memory using multiple chip select signals, or both. Program ROM,
|
||||
whether internal or external, is banked to a greater or lesser
|
||||
extent except on the smallest single-chip ST20XX models.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "st2xxx.h"
|
||||
#include "r65c02d.h"
|
||||
|
||||
st2xxx_device::st2xxx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map, int data_bits, u16 ireq_mask)
|
||||
: r65c02_device(mconfig, type, tag, owner, clock)
|
||||
, m_data_config("data", ENDIANNESS_LITTLE, 8, data_bits, 0)
|
||||
, m_in_port_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}}
|
||||
, m_out_port_cb{{*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}}
|
||||
, m_pdata{0}
|
||||
, m_pctrl{0}
|
||||
, m_psel{0}
|
||||
, m_pfun{0}
|
||||
, m_pmcr(0)
|
||||
, m_ireq(0)
|
||||
, m_iena(0)
|
||||
, m_ireq_mask(ireq_mask)
|
||||
, m_sys(0)
|
||||
{
|
||||
program_config.m_internal_map = std::move(internal_map);
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector st2xxx_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_PROGRAM, &program_config),
|
||||
std::make_pair(AS_DATA, &m_data_config)
|
||||
};
|
||||
}
|
||||
|
||||
void st2xxx_device::device_resolve_objects()
|
||||
{
|
||||
for (auto &cb : m_in_port_cb)
|
||||
cb.resolve_safe(0xff);
|
||||
for (auto &cb : m_out_port_cb)
|
||||
cb.resolve_safe();
|
||||
}
|
||||
|
||||
void st2xxx_device::device_reset()
|
||||
{
|
||||
m6502_device::device_reset();
|
||||
|
||||
// reset port registers
|
||||
std::fill(std::begin(m_pdata), std::end(m_pdata), 0xff);
|
||||
std::fill(std::begin(m_pctrl), std::end(m_pctrl), 0);
|
||||
std::fill(std::begin(m_psel), std::end(m_psel), 0xff);
|
||||
std::fill(std::begin(m_pfun), std::end(m_pfun), 0);
|
||||
for (auto &cb : m_out_port_cb)
|
||||
cb(0xff);
|
||||
m_pmcr = 0x80;
|
||||
|
||||
// reset interrupt registers
|
||||
m_ireq = 0;
|
||||
m_iena = 0;
|
||||
update_irq_state();
|
||||
|
||||
// reset miscellaneous registers
|
||||
m_sys = 0;
|
||||
}
|
||||
|
||||
std::unique_ptr<util::disasm_interface> st2xxx_device::create_disassembler()
|
||||
{
|
||||
return std::make_unique<r65c02_disassembler>();
|
||||
}
|
||||
|
||||
u8 st2xxx_device::acknowledge_irq()
|
||||
{
|
||||
// IREQH interrupts have priority over IREQL interrupts
|
||||
for (int level = 8; level < 16; level++)
|
||||
{
|
||||
if (BIT(m_ireq & m_iena, level))
|
||||
{
|
||||
m_ireq &= ~(1 << level);
|
||||
update_irq_state();
|
||||
return level;
|
||||
}
|
||||
}
|
||||
for (int level = 0; level < 8; level++)
|
||||
{
|
||||
if (BIT(m_ireq & m_iena, level))
|
||||
{
|
||||
m_ireq &= ~(1 << level);
|
||||
update_irq_state();
|
||||
return level;
|
||||
}
|
||||
}
|
||||
throw emu_fatalerror("ST2XXX: no IRQ to acknowledge!\n");
|
||||
}
|
||||
|
||||
u8 st2xxx_device::pdata_r(offs_t offset)
|
||||
{
|
||||
u8 pdata = m_pdata[offset];
|
||||
u8 pinmask = ~m_pctrl[offset] | (pdata & ~m_psel[offset]);
|
||||
if (pinmask != 0)
|
||||
pdata = (pdata & ~pinmask) | (m_in_port_cb[offset](0, pinmask) & pinmask);
|
||||
return pdata;
|
||||
}
|
||||
|
||||
void st2xxx_device::pdata_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (data != m_pdata[offset])
|
||||
{
|
||||
m_pdata[offset] = data;
|
||||
m_out_port_cb[offset](0, data, m_pctrl[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
u8 st2xxx_device::pctrl_r(offs_t offset)
|
||||
{
|
||||
return m_pctrl[offset];
|
||||
}
|
||||
|
||||
void st2xxx_device::pctrl_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (data != m_pctrl[offset])
|
||||
{
|
||||
m_pctrl[offset] = data;
|
||||
m_out_port_cb[offset](0, m_pdata[offset], data);
|
||||
}
|
||||
}
|
||||
|
||||
u8 st2xxx_device::pfc_r()
|
||||
{
|
||||
return m_pfun[0];
|
||||
}
|
||||
|
||||
void st2xxx_device::pfc_w(u8 data)
|
||||
{
|
||||
m_pfun[0] = data;
|
||||
}
|
||||
|
||||
u8 st2xxx_device::pfd_r()
|
||||
{
|
||||
return m_pfun[1];
|
||||
}
|
||||
|
||||
void st2xxx_device::pfd_w(u8 data)
|
||||
{
|
||||
m_pfun[1] = data;
|
||||
}
|
||||
|
||||
u8 st2xxx_device::pl_r()
|
||||
{
|
||||
return pdata_r(6);
|
||||
}
|
||||
|
||||
void st2xxx_device::pl_w(u8 data)
|
||||
{
|
||||
pdata_w(6, data);
|
||||
}
|
||||
|
||||
u8 st2xxx_device::psc_r()
|
||||
{
|
||||
return m_psel[2];
|
||||
}
|
||||
|
||||
void st2xxx_device::psc_w(u8 data)
|
||||
{
|
||||
m_psel[2] = data;
|
||||
}
|
||||
|
||||
u8 st2xxx_device::pse_r()
|
||||
{
|
||||
return m_psel[4];
|
||||
}
|
||||
|
||||
void st2xxx_device::pse_w(u8 data)
|
||||
{
|
||||
m_psel[4] = data;
|
||||
}
|
||||
|
||||
u8 st2xxx_device::pcl_r()
|
||||
{
|
||||
return pctrl_r(6);
|
||||
}
|
||||
|
||||
void st2xxx_device::pcl_w(u8 data)
|
||||
{
|
||||
pctrl_w(6, data);
|
||||
}
|
||||
|
||||
u8 st2xxx_device::ireql_r()
|
||||
{
|
||||
return m_ireq & 0x00ff;
|
||||
}
|
||||
|
||||
void st2xxx_device::ireql_w(u8 data)
|
||||
{
|
||||
if ((m_ireq & ~data & 0x00ff) != 0)
|
||||
{
|
||||
m_ireq &= data | 0xff00;
|
||||
update_irq_state();
|
||||
}
|
||||
}
|
||||
|
||||
u8 st2xxx_device::ireqh_r()
|
||||
{
|
||||
return m_ireq >> 8;
|
||||
}
|
||||
|
||||
void st2xxx_device::ireqh_w(u8 data)
|
||||
{
|
||||
if ((m_ireq & ~(u16(data) << 8) & 0xff00) != 0)
|
||||
{
|
||||
m_ireq &= u16(data) << 8 | 0x00ff;
|
||||
update_irq_state();
|
||||
}
|
||||
}
|
||||
|
||||
u8 st2xxx_device::ienal_r()
|
||||
{
|
||||
return m_iena & 0x00ff;
|
||||
}
|
||||
|
||||
void st2xxx_device::ienal_w(u8 data)
|
||||
{
|
||||
m_iena = (m_iena & 0xff00) | (data & m_ireq_mask);
|
||||
update_irq_state();
|
||||
}
|
||||
|
||||
u8 st2xxx_device::ienah_r()
|
||||
{
|
||||
return m_iena >> 8;
|
||||
}
|
||||
|
||||
void st2xxx_device::ienah_w(u8 data)
|
||||
{
|
||||
m_iena = (m_iena & 0x00ff) | ((u16(data) << 8) & m_ireq_mask);
|
||||
update_irq_state();
|
||||
}
|
||||
|
||||
#include "cpu/m6502/st2xxx.hxx"
|
134
src/devices/cpu/m6502/st2xxx.h
Normal file
134
src/devices/cpu/m6502/st2xxx.h
Normal file
@ -0,0 +1,134 @@
|
||||
#ifndef MAME_CPU_M6502_ST2XXX_H
|
||||
#define MAME_CPU_M6502_ST2XXX_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "r65c02.h"
|
||||
|
||||
class st2xxx_device : public r65c02_device {
|
||||
public:
|
||||
enum {
|
||||
ST_PDA = M6502_IR + 1,
|
||||
ST_PDB,
|
||||
ST_PDC,
|
||||
ST_PDD,
|
||||
ST_PDE,
|
||||
ST_PDF,
|
||||
ST_PDL,
|
||||
ST_PCA,
|
||||
ST_PCB,
|
||||
ST_PCC,
|
||||
ST_PCD,
|
||||
ST_PCE,
|
||||
ST_PCF,
|
||||
ST_PCL,
|
||||
ST_PSA,
|
||||
ST_PSB,
|
||||
ST_PSC,
|
||||
ST_PSD,
|
||||
ST_PSE,
|
||||
ST_PSF,
|
||||
ST_PSL,
|
||||
ST_PFC,
|
||||
ST_PFD,
|
||||
ST_PMCR,
|
||||
ST_SYS,
|
||||
ST_IRR,
|
||||
ST_PRR,
|
||||
ST_DRR,
|
||||
ST_IREQ,
|
||||
ST_IENA
|
||||
};
|
||||
|
||||
auto in_pa_callback() { return m_in_port_cb[0].bind(); }
|
||||
auto out_pa_callback() { return m_out_port_cb[0].bind(); }
|
||||
auto in_pb_callback() { return m_in_port_cb[1].bind(); }
|
||||
auto out_pb_callback() { return m_out_port_cb[1].bind(); }
|
||||
auto in_pc_callback() { return m_in_port_cb[2].bind(); }
|
||||
auto out_pc_callback() { return m_out_port_cb[2].bind(); }
|
||||
auto in_pd_callback() { return m_in_port_cb[3].bind(); }
|
||||
auto out_pd_callback() { return m_out_port_cb[3].bind(); }
|
||||
auto in_pe_callback() { return m_in_port_cb[4].bind(); }
|
||||
auto out_pe_callback() { return m_out_port_cb[4].bind(); }
|
||||
auto in_pf_callback() { return m_in_port_cb[5].bind(); }
|
||||
auto out_pf_callback() { return m_out_port_cb[5].bind(); }
|
||||
auto in_pl_callback() { return m_in_port_cb[6].bind(); }
|
||||
auto out_pl_callback() { return m_out_port_cb[6].bind(); }
|
||||
|
||||
protected:
|
||||
st2xxx_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, address_map_constructor internal_map, int data_bits, u16 ireq_mask);
|
||||
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
virtual void device_resolve_objects() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
|
||||
virtual void do_exec_full() override;
|
||||
virtual void do_exec_partial() override;
|
||||
|
||||
class mi_st2xxx : public memory_interface {
|
||||
public:
|
||||
virtual u8 read_vector(u16 adr) = 0;
|
||||
|
||||
address_space *data;
|
||||
memory_access_cache<0, 0, ENDIANNESS_LITTLE> *dcache;
|
||||
bool irq_service;
|
||||
};
|
||||
|
||||
u8 read_vector(u16 adr) { return downcast<mi_st2xxx &>(*mintf).read_vector(adr); }
|
||||
void set_irq_service(bool state) { downcast<mi_st2xxx &>(*mintf).irq_service = state; }
|
||||
|
||||
void update_irq_state() { irq_state = (m_ireq & m_iena) != 0; }
|
||||
u8 acknowledge_irq();
|
||||
|
||||
u8 pdata_r(offs_t offset);
|
||||
void pdata_w(offs_t offset, u8 data);
|
||||
u8 pctrl_r(offs_t offset);
|
||||
void pctrl_w(offs_t offset, u8 data);
|
||||
u8 pl_r();
|
||||
void pl_w(u8 data);
|
||||
u8 pcl_r();
|
||||
void pcl_w(u8 data);
|
||||
u8 psc_r();
|
||||
void psc_w(u8 data);
|
||||
u8 pse_r();
|
||||
void pse_w(u8 data);
|
||||
u8 pfc_r();
|
||||
void pfc_w(u8 data);
|
||||
u8 pfd_r();
|
||||
void pfd_w(u8 data);
|
||||
|
||||
u8 ireql_r();
|
||||
void ireql_w(u8 data);
|
||||
u8 ireqh_r();
|
||||
void ireqh_w(u8 data);
|
||||
u8 ienal_r();
|
||||
void ienal_w(u8 data);
|
||||
u8 ienah_r();
|
||||
void ienah_w(u8 data);
|
||||
|
||||
#define O(o) void o ## _full(); void o ## _partial()
|
||||
|
||||
O(brk_st_imp);
|
||||
O(rti_st_imp);
|
||||
O(reset_st);
|
||||
|
||||
#undef O
|
||||
|
||||
address_space_config m_data_config;
|
||||
|
||||
devcb_read8 m_in_port_cb[7];
|
||||
devcb_write8 m_out_port_cb[7];
|
||||
|
||||
u8 m_pdata[7];
|
||||
u8 m_pctrl[7];
|
||||
u8 m_psel[7];
|
||||
u8 m_pfun[2];
|
||||
u8 m_pmcr;
|
||||
u16 m_ireq;
|
||||
u16 m_iena;
|
||||
const u16 m_ireq_mask;
|
||||
u8 m_sys;
|
||||
};
|
||||
|
||||
#endif // MAME_CPU_M6502_ST2XXX_H
|
@ -1,125 +1,61 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:R. Belmont
|
||||
// copyright-holders:AJR
|
||||
/***************************************************************************
|
||||
|
||||
inteladv.cpp: VTech Intelligence Advance E/R Lerncomputer
|
||||
|
||||
CPU is a Rockwell R65C02 (the dead-end bit-twiddling 65C02, as opposed to
|
||||
the WDC version that the 65816 is back-compatible with) with some customizations:
|
||||
|
||||
JMP (ZP) accepts a 3rd ZP location after the 16-bit address to jump to which
|
||||
contains a bank value for the ROM window at 0x4000. I believe it's in 0x4000
|
||||
byte segments, as the first long jump uses a value of 4 and that leads to
|
||||
the correct start of a subroutine at 0x10000 + the offset.
|
||||
|
||||
JSR / RTS may also push and pop an additional byte for the bank offset but
|
||||
this is not proven yet.
|
||||
VTech Intelligence Advance E/R Lerncomputer
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/m6502/r65c02.h"
|
||||
#include "machine/timer.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "cpu/m6502/st2204.h"
|
||||
#include "cpu/m6502/st2205u.h"
|
||||
|
||||
class inteladv_state : public driver_device
|
||||
{
|
||||
public:
|
||||
inteladv_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_palette(*this, "palette")
|
||||
{ }
|
||||
inteladv_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
{
|
||||
}
|
||||
|
||||
void inteladv(machine_config &config);
|
||||
void dyndesk(machine_config &config);
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
private:
|
||||
u32 screen_update_inteladv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void inteladv_main(address_map &map);
|
||||
void dyndesk_main(address_map &map);
|
||||
void inteladv_map(address_map &map);
|
||||
void dyndesk_map(address_map &map);
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<palette_device> m_palette;
|
||||
};
|
||||
|
||||
void inteladv_state::video_start()
|
||||
void inteladv_state::inteladv_map(address_map &map)
|
||||
{
|
||||
map(0x000000, 0x7fffff).rom().region("maincpu", 0);
|
||||
}
|
||||
|
||||
u32 inteladv_state::screen_update_inteladv(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
void inteladv_state::dyndesk_map(address_map &map)
|
||||
{
|
||||
bitmap.fill(0, cliprect);
|
||||
screen.priority().fill(0, cliprect);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inteladv_state::inteladv_main(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x01ff).ram(); // zero page and stack
|
||||
map(0x4000, 0x5fff).rom().region("maincpu", 0x0000); // boot code at 4000
|
||||
map(0x8000, 0x8fff).rom().region("maincpu", 0x8000); // fixed ROM region?
|
||||
map(0xf000, 0xffff).rom().region("maincpu", 0x3000); // boot and other vectors at 3FFx
|
||||
}
|
||||
|
||||
void inteladv_state::dyndesk_main(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0fff).ram();
|
||||
map(0x4000, 0x5fff).rom().region("maincpu", 0x4000); // FIXME: this is banked
|
||||
map(0xc000, 0xdfff).rom().region("maincpu", 0x4000);
|
||||
map(0xffe0, 0xffff).rom().region("maincpu", 0x7fe0); // vectors are good for boot, but may also be banked
|
||||
map(0x000000, 0x1fffff).rom().region("maincpu", 0).nopw(); // writes to low memory go to external RAM instead?
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( inteladv )
|
||||
INPUT_PORTS_END
|
||||
|
||||
void inteladv_state::machine_start()
|
||||
{
|
||||
}
|
||||
|
||||
void inteladv_state::machine_reset()
|
||||
{
|
||||
}
|
||||
|
||||
void inteladv_state::inteladv(machine_config &config)
|
||||
{
|
||||
/* basic machine hardware */
|
||||
R65C02(config, m_maincpu, XTAL(1'000'000));
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &inteladv_state::inteladv_main);
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
screen.set_refresh_hz(59.62); /* verified on pcb */
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
screen.set_size(64*8, 32*8);
|
||||
screen.set_visarea(40, 400-1, 16, 240-1);
|
||||
screen.set_screen_update(FUNC(inteladv_state::screen_update_inteladv));
|
||||
screen.set_palette("palette");
|
||||
|
||||
PALETTE(config, "palette").set_format(palette_device::xBGR_888, 256).enable_shadows();
|
||||
|
||||
/* sound hardware */
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
ST2205U(config, m_maincpu, 32768 * 122);
|
||||
m_maincpu->set_addrmap(AS_DATA, &inteladv_state::inteladv_map);
|
||||
}
|
||||
|
||||
void inteladv_state::dyndesk(machine_config &config)
|
||||
{
|
||||
inteladv(config);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &inteladv_state::dyndesk_main);
|
||||
ST2204(config, m_maincpu, 32768 * 122);
|
||||
m_maincpu->set_addrmap(AS_DATA, &inteladv_state::dyndesk_map);
|
||||
}
|
||||
|
||||
ROM_START( inteladv )
|
||||
ROM_REGION( 0x800000, "maincpu", 0 ) /* main program */
|
||||
ROM_REGION( 0x800000, "maincpu", 0 )
|
||||
ROM_LOAD( "vtechinteladv.bin", 0x000000, 0x800000, CRC(e24dbbcb) SHA1(7cb7f25f5eb123ae4c46cd4529aafd95508b2210) )
|
||||
ROM_END
|
||||
|
||||
@ -135,7 +71,7 @@ ROM_START( cars2lap )
|
||||
ROM_LOAD("n25s16.u6", 0x00000, 0x200000, CRC(ec1ba96e) SHA1(51b8844ae77adf20f74f268d380d268c9ce19785))
|
||||
ROM_END
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 2005, inteladv, 0, 0, inteladv, inteladv, inteladv_state, empty_init, "VTech", "Intelligence Advance E/R (Germany)", MACHINE_NOT_WORKING )
|
||||
COMP( 2003, dyndesk, 0, 0, dyndesk, inteladv, inteladv_state, empty_init, "VTech", "DynamiDesk (Germany)", MACHINE_NOT_WORKING )
|
||||
COMP( 2012, cars2lap, 0, 0, inteladv, inteladv, inteladv_state, empty_init, "VTech", "CARS 2 Laptop (Germany)", MACHINE_IS_SKELETON ) // might not belong here
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 2005, inteladv, 0, 0, inteladv, inteladv, inteladv_state, empty_init, "VTech", "Intelligence Advance E/R (Germany)", MACHINE_IS_SKELETON )
|
||||
COMP( 2003, dyndesk, 0, 0, dyndesk, inteladv, inteladv_state, empty_init, "VTech", "DynamiDesk (Germany)", MACHINE_IS_SKELETON )
|
||||
COMP( 2012, cars2lap, 0, 0, dyndesk, inteladv, inteladv_state, empty_init, "VTech", "CARS 2 Laptop (Germany)", MACHINE_IS_SKELETON ) // probably doesn't belong here
|
||||
|
Loading…
Reference in New Issue
Block a user