mirror of
https://github.com/holub/mame
synced 2025-04-16 05:24:54 +03:00
New machines marked as NOT_WORKING
------------------ Hewlett-Packard Jornada 720 [Ryan Holtz] * arm7: Fixed interaction between instruction prefetching with the MMU enabled. [Ryan Holtz] * sa111: Added skeleton device for Intel SA-1111 Microprocessor Companion Chip. [Ryan Holtz] * sed1356: Added skeleton device for Epson/Seiko SED1356 video controller. [Ryan Holtz] * sa1110: Various cleanups. Added rudimentary SSP module support. [Ryan Holtz]
This commit is contained in:
parent
3ec0a65969
commit
7ebdb0bd97
@ -2886,6 +2886,18 @@ if (MACHINES["SA1110"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/sa1111.h,MACHINES["SA1111"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["SA1111"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/sa1111.cpp",
|
||||
MAME_DIR .. "src/devices/machine/sa1111.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/saa1043.h,MACHINES["SAA1043"] = true
|
||||
|
@ -886,6 +886,17 @@ if (VIDEOS["SED1330"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/video/sed1356.h,VIDEOS["SED1356"] = true
|
||||
--------------------------------------------------
|
||||
if (VIDEOS["SED1356"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/video/sed1356.cpp",
|
||||
MAME_DIR .. "src/devices/video/sed1356.h",
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/video/sed1500.h,VIDEOS["SED1500"] = true
|
||||
|
@ -364,6 +364,7 @@ VIDEOS["SCN2674"] = true
|
||||
VIDEOS["PWM_DISPLAY"] = true
|
||||
--VIDEOS["SED1200"] = true
|
||||
--VIDEOS["SED1330"] = true
|
||||
--VIDEOS["SED1356"] = true
|
||||
--VIDEOS["SED1500"] = true
|
||||
--VIDEOS["SED1520"] = true
|
||||
VIDEOS["SNES_PPU"] = true
|
||||
@ -623,6 +624,7 @@ MACHINES["S3520CF"] = true
|
||||
MACHINES["S3C24XX"] = true
|
||||
--MACHINES["S3C44B0"] = true
|
||||
--MACHINES["SA1110"] = true
|
||||
--MACHINES["SA1111"] = true
|
||||
MACHINES["SATURN"] = true
|
||||
MACHINES["SCC68070"] = true
|
||||
MACHINES["SCN_PCI"] = true
|
||||
|
@ -394,6 +394,7 @@ VIDEOS["PWM_DISPLAY"] = true
|
||||
VIDEOS["SDA5708"] = true
|
||||
VIDEOS["SED1200"] = true
|
||||
VIDEOS["SED1330"] = true
|
||||
VIDEOS["SED1356"] = true
|
||||
VIDEOS["SED1500"] = true
|
||||
VIDEOS["SED1520"] = true
|
||||
VIDEOS["SNES_PPU"] = true
|
||||
@ -655,6 +656,7 @@ MACHINES["S3520CF"] = true
|
||||
MACHINES["S3C24XX"] = true
|
||||
MACHINES["S3C44B0"] = true
|
||||
MACHINES["SA1110"] = true
|
||||
MACHINES["SA1111"] = true
|
||||
MACHINES["SAA1043"] = true
|
||||
MACHINES["SATURN"] = true
|
||||
MACHINES["SCC68070"] = true
|
||||
@ -2596,6 +2598,7 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/hp2640.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/hp95lx.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/hp9825.cpp",
|
||||
MAME_DIR .. "src/mame/drivers/jornada.cpp",
|
||||
}
|
||||
|
||||
createMESSProjects(_target, _subtarget, "hec2hrp")
|
||||
|
@ -42,7 +42,7 @@ TODO:
|
||||
#define LOG_COPRO_UNKNOWN (1 << 4)
|
||||
#define LOG_COPRO_RESERVED (1 << 5)
|
||||
|
||||
#define VERBOSE (0) //(LOG_MMU | LOG_COPRO_READS | LOG_COPRO_WRITES)
|
||||
#define VERBOSE (0) // (LOG_MMU | LOG_COPRO_READS | LOG_COPRO_WRITES | LOG_COPRO_UNKNOWN | LOG_COPRO_RESERVED)
|
||||
#include "logmacro.h"
|
||||
|
||||
#define PRINT_HAPYFSH2 (0)
|
||||
@ -100,6 +100,7 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type
|
||||
|
||||
memset(m_insn_prefetch_buffer, 0, sizeof(uint32_t) * 3);
|
||||
memset(m_insn_prefetch_address, 0, sizeof(uint32_t) * 3);
|
||||
memset(m_insn_prefetch_valid, 0, sizeof(bool) * 3);
|
||||
m_insn_prefetch_count = 0;
|
||||
m_insn_prefetch_index = 0;
|
||||
}
|
||||
@ -444,7 +445,7 @@ int arm7_cpu_device::detect_fault(int desc_lvl1, int ap, int flags)
|
||||
}
|
||||
|
||||
|
||||
bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_exception)
|
||||
bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags)
|
||||
{
|
||||
if (addr < 0x2000000)
|
||||
{
|
||||
@ -474,41 +475,31 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_except
|
||||
{
|
||||
addr = ( desc_lvl1 & COPRO_TLB_SECTION_PAGE_MASK ) | ( addr & ~COPRO_TLB_SECTION_PAGE_MASK );
|
||||
}
|
||||
else
|
||||
else if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
if (no_exception)
|
||||
return false;
|
||||
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
uint8_t domain = (desc_lvl1 >> 5) & 0xF;
|
||||
LOGMASKED(LOG_MMU, "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
m_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (9 << 0) : (13 << 0)) | (domain << 4); // 9 = section domain fault, 13 = section permission fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
update_irq_state();
|
||||
LOGMASKED(LOG_MMU, "vaddr %08X desc_lvl1 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
|
||||
addr, desc_lvl1, domain, (m_domainAccessControl >> ((desc_lvl1 >> 4) & 0x1e)) & 3, (desc_lvl1 >> 10) & 3, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0);
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOGMASKED(LOG_MMU, "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
m_pendingAbtP = true;
|
||||
update_irq_state();
|
||||
}
|
||||
uint8_t domain = (desc_lvl1 >> 5) & 0xF;
|
||||
LOGMASKED(LOG_MMU, "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
m_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (9 << 0) : (13 << 0)) | (domain << 4); // 9 = section domain fault, 13 = section permission fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
update_irq_state();
|
||||
LOGMASKED(LOG_MMU, "vaddr %08X desc_lvl1 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
|
||||
addr, desc_lvl1, domain, (m_domainAccessControl >> ((desc_lvl1 >> 4) & 0x1e)) & 3, (desc_lvl1 >> 10) & 3, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0);
|
||||
return false;
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOGMASKED(LOG_MMU, "ARM7: Section Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (tlb_type == COPRO_TLB_UNMAPPED)
|
||||
{
|
||||
if (no_exception)
|
||||
return false;
|
||||
|
||||
// Unmapped, generate a translation fault
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", m_r[eR15], addr);
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address (D), PC = %08x, vaddr = %08x\n", m_r[eR15], addr);
|
||||
m_faultStatus[0] = (5 << 0); // 5 = section translation fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
@ -516,9 +507,7 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_except
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address, PC = %08x, vaddr = %08x\n", m_r[eR15], addr);
|
||||
m_pendingAbtP = true;
|
||||
update_irq_state();
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address (P), PC = %08x, vaddr = %08x\n", m_r[eR15], addr);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -533,17 +522,14 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_except
|
||||
fatalerror("ARM7: Not Yet Implemented: Coarse Table, Section Domain fault on virtual address, vaddr = %08x, domain = %08x, PC = %08x\n", addr, domain, m_r[eR15]);
|
||||
}
|
||||
|
||||
switch( desc_lvl2 & 3 )
|
||||
switch (desc_lvl2 & 3)
|
||||
{
|
||||
case COPRO_TLB_UNMAPPED:
|
||||
if (no_exception)
|
||||
return false;
|
||||
|
||||
// Unmapped, generate a translation fault
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
uint8_t domain = (desc_lvl1 >> 5) & 0xF;
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", addr, m_r[eR15]);
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address (D), lvl2, vaddr = %08x, PC %08X\n", addr, m_r[eR15]);
|
||||
m_faultStatus[0] = (7 << 0) | (domain << 4); // 7 = page translation fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
@ -551,9 +537,7 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_except
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address, vaddr = %08x, PC %08X\n", addr, m_r[eR15]);
|
||||
m_pendingAbtP = true;
|
||||
update_irq_state();
|
||||
LOGMASKED(LOG_MMU, "ARM7: Translation fault on unmapped virtual address (P), lvl2, vaddr = %08x, PC %08X\n", addr, m_r[eR15]);
|
||||
}
|
||||
return false;
|
||||
case COPRO_TLB_LARGE_PAGE:
|
||||
@ -567,44 +551,36 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_except
|
||||
int fault = detect_fault(desc_lvl1, ap, flags);
|
||||
if (fault == FAULT_NONE)
|
||||
{
|
||||
addr = ( desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK ) | ( addr & ~COPRO_TLB_SMALL_PAGE_MASK );
|
||||
addr = (desc_lvl2 & COPRO_TLB_SMALL_PAGE_MASK) | (addr & ~COPRO_TLB_SMALL_PAGE_MASK);
|
||||
break;
|
||||
}
|
||||
else if (no_exception)
|
||||
else if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
return false;
|
||||
uint8_t domain = (desc_lvl1 >> 5) & 0xF;
|
||||
// hapyfish expects a data abort when something tries to write to a read-only memory location from user mode
|
||||
LOGMASKED(LOG_MMU, "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
m_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (11 << 0) : (15 << 0)) | (domain << 4); // 11 = page domain fault, 15 = page permission fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
update_irq_state();
|
||||
LOGMASKED(LOG_MMU, "vaddr %08X desc_lvl2 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
|
||||
addr, desc_lvl2, domain, permission, ap, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0);
|
||||
}
|
||||
else
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
if (flags & ARM7_TLB_ABORT_D)
|
||||
{
|
||||
uint8_t domain = (desc_lvl1 >> 5) & 0xF;
|
||||
// hapyfish expects a data abort when something tries to write to a read-only memory location from user mode
|
||||
LOGMASKED(LOG_MMU, "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
m_faultStatus[0] = ((fault == FAULT_DOMAIN) ? (11 << 0) : (15 << 0)) | (domain << 4); // 11 = page domain fault, 15 = page permission fault
|
||||
m_faultAddress = addr;
|
||||
m_pendingAbtD = true;
|
||||
update_irq_state();
|
||||
LOGMASKED(LOG_MMU, "vaddr %08X desc_lvl2 %08X domain %d permission %d ap %d s %d r %d mode %d read %d write %d\n",
|
||||
addr, desc_lvl2, domain, permission, ap, (m_control & COPRO_CTRL_SYSTEM) ? 1 : 0, (m_control & COPRO_CTRL_ROM) ? 1 : 0,
|
||||
m_r[eCPSR] & MODE_FLAG, flags & ARM7_TLB_READ ? 1 : 0, flags & ARM7_TLB_WRITE ? 1 : 0);
|
||||
}
|
||||
else if (flags & ARM7_TLB_ABORT_P)
|
||||
{
|
||||
LOGMASKED(LOG_MMU, "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
m_pendingAbtP = true;
|
||||
update_irq_state();
|
||||
}
|
||||
return false;
|
||||
LOGMASKED(LOG_MMU, "ARM7: Page Table, Section %s fault on virtual address, vaddr = %08x, PC = %08x\n", (fault == FAULT_DOMAIN) ? "domain" : "permission", addr, m_r[eR15]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case COPRO_TLB_TINY_PAGE:
|
||||
// Tiny page descriptor
|
||||
if( ( desc_lvl1 & 3 ) == 1 )
|
||||
if ((desc_lvl1 & 3) == 1)
|
||||
{
|
||||
LOGMASKED(LOG_MMU, "ARM7: It would appear that we're looking up a tiny page from a coarse TLB lookup. This is bad. vaddr = %08x\n", addr);
|
||||
}
|
||||
addr = ( desc_lvl2 & COPRO_TLB_TINY_PAGE_MASK ) | ( addr & ~COPRO_TLB_TINY_PAGE_MASK );
|
||||
addr = (desc_lvl2 & COPRO_TLB_TINY_PAGE_MASK) | (addr & ~COPRO_TLB_TINY_PAGE_MASK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -616,7 +592,7 @@ bool arm7_cpu_device::arm7_tlb_translate(offs_t &addr, int flags, bool no_except
|
||||
bool arm7_cpu_device::memory_translate(int spacenum, int intention, offs_t &address)
|
||||
{
|
||||
/* only applies to the program address space and only does something if the MMU's enabled */
|
||||
if( spacenum == AS_PROGRAM && ( m_control & COPRO_CTRL_MMU_EN ) )
|
||||
if (spacenum == AS_PROGRAM && (m_control & COPRO_CTRL_MMU_EN))
|
||||
{
|
||||
return arm7_tlb_translate(address, 0);
|
||||
}
|
||||
@ -655,6 +631,7 @@ void arm7_cpu_device::device_start()
|
||||
save_item(NAME(m_insn_prefetch_index));
|
||||
save_item(NAME(m_insn_prefetch_buffer));
|
||||
save_item(NAME(m_insn_prefetch_address));
|
||||
save_item(NAME(m_insn_prefetch_valid));
|
||||
save_item(NAME(m_r));
|
||||
save_item(NAME(m_pendingIrq));
|
||||
save_item(NAME(m_pendingFiq));
|
||||
@ -835,11 +812,14 @@ void arm7_cpu_device::update_insn_prefetch(uint32_t curr_pc)
|
||||
for (uint32_t i = 0; i < to_fetch; i++)
|
||||
{
|
||||
uint32_t index = (i + start_index) % m_insn_prefetch_depth;
|
||||
if ((m_control & COPRO_CTRL_MMU_EN) && !arm7_tlb_translate(pc, ARM7_TLB_ABORT_P | ARM7_TLB_READ, true))
|
||||
m_insn_prefetch_valid[index] = true;
|
||||
offs_t physical_pc = pc;
|
||||
if ((m_control & COPRO_CTRL_MMU_EN) && !arm7_tlb_translate(physical_pc, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
|
||||
{
|
||||
m_insn_prefetch_valid[index] = false;
|
||||
break;
|
||||
}
|
||||
uint32_t op = m_pr32(pc);
|
||||
uint32_t op = m_pr32(physical_pc);
|
||||
//printf("ipb[%d] <- %08x(%08x)\n", index, op, pc);
|
||||
m_insn_prefetch_buffer[index] = op;
|
||||
m_insn_prefetch_address[index] = pc;
|
||||
@ -848,38 +828,28 @@ void arm7_cpu_device::update_insn_prefetch(uint32_t curr_pc)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t arm7_cpu_device::insn_fetch_thumb(uint32_t pc)
|
||||
bool arm7_cpu_device::insn_fetch_thumb(uint32_t pc, uint32_t &out_insn)
|
||||
{
|
||||
if (pc & 2)
|
||||
{
|
||||
uint16_t insn = (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word1_shift);
|
||||
m_insn_prefetch_index = (m_insn_prefetch_index + 1) % m_insn_prefetch_count;
|
||||
out_insn = (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word1_shift);
|
||||
bool valid = m_insn_prefetch_valid[m_insn_prefetch_index];
|
||||
m_insn_prefetch_index = (m_insn_prefetch_index + 1) % m_insn_prefetch_depth;
|
||||
m_insn_prefetch_count--;
|
||||
return insn;
|
||||
return valid;
|
||||
}
|
||||
return (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word0_shift);
|
||||
out_insn = (uint16_t)(m_insn_prefetch_buffer[m_insn_prefetch_index] >> m_prefetch_word0_shift);
|
||||
return m_insn_prefetch_valid[m_insn_prefetch_index];
|
||||
}
|
||||
|
||||
uint32_t arm7_cpu_device::insn_fetch_arm(uint32_t pc)
|
||||
bool arm7_cpu_device::insn_fetch_arm(uint32_t pc, uint32_t &out_insn)
|
||||
{
|
||||
//printf("ipb[%d] = %08x\n", m_insn_prefetch_index, m_insn_prefetch_buffer[m_insn_prefetch_index]);
|
||||
uint32_t insn = m_insn_prefetch_buffer[m_insn_prefetch_index];
|
||||
m_insn_prefetch_index = (m_insn_prefetch_index + 1) % m_insn_prefetch_count;
|
||||
out_insn = m_insn_prefetch_buffer[m_insn_prefetch_index];
|
||||
bool valid = m_insn_prefetch_valid[m_insn_prefetch_index];
|
||||
m_insn_prefetch_index = (m_insn_prefetch_index + 1) % m_insn_prefetch_depth;
|
||||
m_insn_prefetch_count--;
|
||||
return insn;
|
||||
}
|
||||
|
||||
int arm7_cpu_device::get_insn_prefetch_index(uint32_t address)
|
||||
{
|
||||
address &= ~3;
|
||||
for (uint32_t i = 0; i < m_insn_prefetch_depth; i++)
|
||||
{
|
||||
if (m_insn_prefetch_address[i] == address)
|
||||
{
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return valid;
|
||||
}
|
||||
|
||||
void arm7_cpu_device::execute_run()
|
||||
@ -1096,17 +1066,13 @@ void arm7_cpu_device::execute_run()
|
||||
// "In Thumb state, bit [0] is undefined and must be ignored. Bits [31:1] contain the PC."
|
||||
raddr = pc & (~1);
|
||||
|
||||
if ( m_control & COPRO_CTRL_MMU_EN )
|
||||
if (!insn_fetch_thumb(raddr, insn))
|
||||
{
|
||||
if (!arm7_tlb_translate(raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
|
||||
{
|
||||
goto skip_exec;
|
||||
}
|
||||
m_pendingAbtP = true;
|
||||
update_irq_state();
|
||||
goto skip_exec;
|
||||
}
|
||||
|
||||
insn = insn_fetch_thumb(raddr);
|
||||
(this->*thumb_handler[(insn & 0xffc0) >> 6])(pc, insn);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1117,26 +1083,13 @@ void arm7_cpu_device::execute_run()
|
||||
// "In ARM state, bits [1:0] of r15 are undefined and must be ignored. Bits [31:2] contain the PC."
|
||||
raddr = pc & (~3);
|
||||
|
||||
if ( m_control & COPRO_CTRL_MMU_EN )
|
||||
if (!insn_fetch_arm(raddr, insn))
|
||||
{
|
||||
if (!arm7_tlb_translate(raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ))
|
||||
{
|
||||
goto skip_exec;
|
||||
}
|
||||
m_pendingAbtP = true;
|
||||
update_irq_state();
|
||||
goto skip_exec;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (MODE26)
|
||||
{
|
||||
uint32_t temp1, temp2;
|
||||
temp1 = GET_CPSR & 0xF00000C3;
|
||||
temp2 = (R15 & 0xF0000000) | ((R15 & 0x0C000000) >> (26 - 6)) | (R15 & 0x00000003);
|
||||
if (temp1 != temp2) fatalerror( "%08X: 32-bit and 26-bit modes are out of sync (%08X %08X)\n", pc, temp1, temp2);
|
||||
}
|
||||
#endif
|
||||
|
||||
insn = insn_fetch_arm(raddr);
|
||||
|
||||
int op_offset = 0;
|
||||
/* process condition codes for this instruction */
|
||||
if ((insn >> INSN_COND_SHIFT) != COND_AL)
|
||||
@ -1353,14 +1306,15 @@ uint32_t arm7_cpu_device::arm7_rt_r_callback(offs_t offset)
|
||||
data = COPRO_CTRL | 0x70; // bits 4-6 always read back as "1" (bit 3 too in XScale)
|
||||
break;
|
||||
case 2: // Translation Table Base
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, TLB Base, PC = %08x\n", m_r[eR15]);
|
||||
data = COPRO_TLB_BASE;
|
||||
break;
|
||||
case 3: // Domain Access Control
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Domain Access Control\n");
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Domain Access Control, PC = %08x\n", m_r[eR15]);
|
||||
data = COPRO_DOMAIN_ACCESS_CONTROL;
|
||||
break;
|
||||
case 5: // Fault Status
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Fault Status\n");
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Fault Status, PC = %08x\n", m_r[eR15]);
|
||||
switch (op3)
|
||||
{
|
||||
case 0: data = COPRO_FAULT_STATUS_D; break;
|
||||
@ -1368,11 +1322,11 @@ uint32_t arm7_cpu_device::arm7_rt_r_callback(offs_t offset)
|
||||
}
|
||||
break;
|
||||
case 6: // Fault Address
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Fault Address\n");
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Fault Address, PC = %08x\n", m_r[eR15]);
|
||||
data = COPRO_FAULT_ADDRESS;
|
||||
break;
|
||||
case 13: // Read Process ID (PID)
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Read PID\n");
|
||||
LOGMASKED(LOG_COPRO_READS, "arm7_rt_r_callback, Read PID, PC = %08x\n", m_r[eR15]);
|
||||
data = COPRO_FCSE_PID;
|
||||
break;
|
||||
case 14: // Read Breakpoint
|
||||
@ -1449,12 +1403,12 @@ void arm7_cpu_device::arm7_rt_w_callback(offs_t offset, uint32_t data)
|
||||
COPRO_CTRL = data & COPRO_CTRL_MASK;
|
||||
break;
|
||||
case 2: // Translation Table Base
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback TLB Base = %08x (%d) (%d)\n", data, op2, op3);
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback TLB Base = %08x (%d) (%d), PC = %08x\n", data, op2, op3, m_r[eR15]);
|
||||
COPRO_TLB_BASE = data;
|
||||
m_tlb_base_mask = data & COPRO_TLB_BASE_MASK;
|
||||
break;
|
||||
case 3: // Domain Access Control
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Domain Access Control = %08x (%d) (%d)\n", data, op2, op3);
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Domain Access Control = %08x (%d) (%d), PC = %08x\n", data, op2, op3, m_r[eR15]);
|
||||
COPRO_DOMAIN_ACCESS_CONTROL = data;
|
||||
for (int i = 0; i < 32; i += 2)
|
||||
{
|
||||
@ -1462,7 +1416,7 @@ void arm7_cpu_device::arm7_rt_w_callback(offs_t offset, uint32_t data)
|
||||
}
|
||||
break;
|
||||
case 5: // Fault Status
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Fault Status = %08x (%d) (%d)\n", data, op2, op3);
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Fault Status = %08x (%d) (%d), PC = %08x\n", data, op2, op3, m_r[eR15]);
|
||||
switch (op3)
|
||||
{
|
||||
case 0: COPRO_FAULT_STATUS_D = data; break;
|
||||
@ -1470,20 +1424,20 @@ void arm7_cpu_device::arm7_rt_w_callback(offs_t offset, uint32_t data)
|
||||
}
|
||||
break;
|
||||
case 6: // Fault Address
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Fault Address = %08x (%d) (%d)\n", data, op2, op3);
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Fault Address = %08x (%d) (%d), PC = %08x\n", data, op2, op3, m_r[eR15]);
|
||||
COPRO_FAULT_ADDRESS = data;
|
||||
break;
|
||||
case 7: // Cache Operations
|
||||
// LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Cache Ops = %08x (%d) (%d)\n", data, op2, op3);
|
||||
break;
|
||||
case 8: // TLB Operations
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback TLB Ops = %08x (%d) (%d)\n", data, op2, op3);
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback TLB Ops = %08x (%d) (%d), PC = %08x\n", data, op2, op3, m_r[eR15]);
|
||||
break;
|
||||
case 9: // Read Buffer Operations
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Read Buffer Ops = %08x (%d) (%d)\n", data, op2, op3);
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Read Buffer Ops = %08x (%d) (%d), PC = %08x\n", data, op2, op3, m_r[eR15]);
|
||||
break;
|
||||
case 13: // Write Process ID (PID)
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Write PID = %08x (%d) (%d)\n", data, op2, op3);
|
||||
LOGMASKED(LOG_COPRO_WRITES, "arm7_rt_w_callback Write PID = %08x (%d) (%d), PC = %08x\n", data, op2, op3, m_r[eR15]);
|
||||
COPRO_FCSE_PID = data;
|
||||
m_pid_offset = (((COPRO_FCSE_PID >> 25) & 0x7F)) * 0x2000000;
|
||||
break;
|
||||
|
@ -147,15 +147,15 @@ protected:
|
||||
uint32_t m_r[/*NUM_REGS*/37];
|
||||
|
||||
void update_insn_prefetch(uint32_t curr_pc);
|
||||
virtual uint16_t insn_fetch_thumb(uint32_t pc);
|
||||
uint32_t insn_fetch_arm(uint32_t pc);
|
||||
int get_insn_prefetch_index(uint32_t address);
|
||||
bool insn_fetch_thumb(uint32_t pc, uint32_t &out_insn);
|
||||
bool insn_fetch_arm(uint32_t pc, uint32_t &out_insn);
|
||||
|
||||
uint32_t m_insn_prefetch_depth;
|
||||
uint32_t m_insn_prefetch_count;
|
||||
uint32_t m_insn_prefetch_index;
|
||||
uint32_t m_insn_prefetch_buffer[3];
|
||||
uint32_t m_insn_prefetch_address[3];
|
||||
bool m_insn_prefetch_valid[3];
|
||||
const uint32_t m_prefetch_word0_shift;
|
||||
const uint32_t m_prefetch_word1_shift;
|
||||
|
||||
@ -235,7 +235,7 @@ protected:
|
||||
void arm9ops_e(uint32_t insn);
|
||||
|
||||
void set_cpsr(uint32_t val);
|
||||
bool arm7_tlb_translate(offs_t &addr, int flags, bool no_exception = false);
|
||||
bool arm7_tlb_translate(offs_t &addr, int flags);
|
||||
uint32_t arm7_tlb_get_second_level_descriptor( uint32_t granularity, uint32_t first_desc, uint32_t vaddr );
|
||||
int detect_fault(int desc_lvl1, int ap, int flags);
|
||||
void arm7_check_irq_state();
|
||||
|
@ -150,7 +150,8 @@ void arm7_disassembler::WriteRegisterOperand1( std::ostream &stream, uint32_t op
|
||||
|
||||
util::stream_format(
|
||||
stream,
|
||||
", R%d", /* Operand 1 register, Operand 2 register, shift type */
|
||||
",%sR%d", /* Operand 1 register, (optional) sign, Operand 2 register, shift type */
|
||||
(opcode&0x800000)?" ":"-",
|
||||
(opcode >> 0) & 0xf);
|
||||
|
||||
//check for LSL 0
|
||||
|
@ -13,13 +13,15 @@
|
||||
#define LOG_UART (1 << 2)
|
||||
#define LOG_UART_HF (1 << 3)
|
||||
#define LOG_MCP (1 << 4)
|
||||
#define LOG_OSTIMER (1 << 5)
|
||||
#define LOG_RTC (1 << 6)
|
||||
#define LOG_POWER (1 << 7)
|
||||
#define LOG_RESET (1 << 8)
|
||||
#define LOG_GPIO (1 << 9)
|
||||
#define LOG_INTC (1 << 10)
|
||||
#define LOG_ALL (LOG_UNKNOWN | LOG_UART | LOG_MCP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC)
|
||||
#define LOG_SSP (1 << 5)
|
||||
#define LOG_OSTIMER (1 << 6)
|
||||
#define LOG_OSTIMER_HF (1 << 7)
|
||||
#define LOG_RTC (1 << 8)
|
||||
#define LOG_POWER (1 << 9)
|
||||
#define LOG_RESET (1 << 10)
|
||||
#define LOG_GPIO (1 << 11)
|
||||
#define LOG_INTC (1 << 12)
|
||||
#define LOG_ALL (LOG_UNKNOWN | LOG_UART | LOG_MCP | LOG_SSP | LOG_OSTIMER | LOG_RTC | LOG_POWER | LOG_RESET | LOG_GPIO | LOG_INTC)
|
||||
|
||||
#define VERBOSE (LOG_ALL)
|
||||
#include "logmacro.h"
|
||||
@ -34,6 +36,7 @@ sa1110_periphs_device::sa1110_periphs_device(const machine_config &mconfig, cons
|
||||
, m_mcp_irqs(*this, "mcpirq")
|
||||
, m_codec(*this, finder_base::DUMMY_TAG)
|
||||
, m_gpio_out(*this)
|
||||
, m_ssp_out(*this)
|
||||
{
|
||||
}
|
||||
|
||||
@ -707,6 +710,238 @@ void sa1110_periphs_device::mcp_w(offs_t offset, uint32_t data, uint32_t mem_mas
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Intel SA-1110 SSP - Synchronous Serial Port
|
||||
|
||||
pg. 331 to 347 Intel StrongARM SA-1110 Microprocessor Developer's Manual
|
||||
|
||||
*/
|
||||
|
||||
TIMER_CALLBACK_MEMBER(sa1110_periphs_device::ssp_rx_callback)
|
||||
{
|
||||
// TODO: Implement receiving data serially rather than in bulk.
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(sa1110_periphs_device::ssp_tx_callback)
|
||||
{
|
||||
// TODO: Implement transmitting data serially rather than in bulk.
|
||||
if (m_ssp_regs.tx_fifo_count)
|
||||
{
|
||||
const uint16_t data = m_ssp_regs.tx_fifo[m_ssp_regs.tx_fifo_read_idx];
|
||||
m_ssp_out(data);
|
||||
|
||||
m_ssp_regs.tx_fifo_read_idx = (m_ssp_regs.tx_fifo_read_idx + 1) % ARRAY_LENGTH(m_ssp_regs.tx_fifo);
|
||||
m_ssp_regs.tx_fifo_count--;
|
||||
|
||||
m_ssp_regs.sssr |= (1 << SSSR_TNF_BIT);
|
||||
|
||||
ssp_update_tx_level();
|
||||
}
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::ssp_update_enable_state()
|
||||
{
|
||||
if (BIT(m_ssp_regs.sscr0, SSCR0_SSE_BIT))
|
||||
{
|
||||
if (m_ssp_regs.tx_fifo_count != ARRAY_LENGTH(m_ssp_regs.tx_fifo))
|
||||
m_ssp_regs.sssr |= (1 << SSSR_TNF_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_TNF_BIT);
|
||||
|
||||
if (m_ssp_regs.rx_fifo_count != 0)
|
||||
m_ssp_regs.sssr |= (1 << SSSR_RNE_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_RNE_BIT);
|
||||
|
||||
if (m_ssp_regs.tx_fifo_count != 0)
|
||||
m_ssp_regs.sssr |= (1 << SSSR_BSY_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_BSY_BIT);
|
||||
|
||||
if (m_ssp_regs.tx_fifo_count <= 4)
|
||||
m_ssp_regs.sssr |= (1 << SSSR_TFS_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_TFS_BIT);
|
||||
|
||||
if (m_ssp_regs.rx_fifo_count >= 4)
|
||||
m_ssp_regs.sssr |= (1 << SSSR_RFS_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_RFS_BIT);
|
||||
|
||||
uint64_t bit_count = (m_ssp_regs.sscr0 & SSCR0_DSS_MASK) >> SSCR0_DSS_BIT;
|
||||
uint32_t clock_rate = 2 * (((m_ssp_regs.sscr0 & SSCR0_SCR_MASK) >> SSCR0_SCR_BIT) + 1);
|
||||
attotime packet_rate = attotime::from_ticks(bit_count * clock_rate, 3686400);
|
||||
m_ssp_regs.rx_timer->adjust(packet_rate, 0, packet_rate);
|
||||
m_ssp_regs.tx_timer->adjust(packet_rate, 0, packet_rate);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_TFS_BIT);
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_RFS_BIT);
|
||||
|
||||
m_ssp_regs.rx_fifo_read_idx = 0;
|
||||
m_ssp_regs.rx_fifo_write_idx = 0;
|
||||
m_ssp_regs.rx_fifo_count = 0;
|
||||
m_ssp_regs.tx_fifo_read_idx = 0;
|
||||
m_ssp_regs.tx_fifo_write_idx = 0;
|
||||
m_ssp_regs.tx_fifo_count = 0;
|
||||
|
||||
m_ssp_regs.rx_timer->adjust(attotime::never);
|
||||
m_ssp_regs.tx_timer->adjust(attotime::never);
|
||||
}
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::ssp_update_rx_level()
|
||||
{
|
||||
if (m_ssp_regs.rx_fifo_count >= 4)
|
||||
m_ssp_regs.sssr |= (1 << SSSR_RFS_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_RFS_BIT);
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::ssp_rx_fifo_push(const uint16_t data)
|
||||
{
|
||||
if (m_ssp_regs.rx_fifo_count < ARRAY_LENGTH(m_ssp_regs.rx_fifo))
|
||||
{
|
||||
m_ssp_regs.rx_fifo[m_ssp_regs.rx_fifo_write_idx] = data;
|
||||
m_ssp_regs.rx_fifo_write_idx = (m_ssp_regs.rx_fifo_write_idx + 1) % ARRAY_LENGTH(m_ssp_regs.rx_fifo);
|
||||
m_ssp_regs.rx_fifo_count++;
|
||||
|
||||
m_ssp_regs.sssr |= (1 << SSSR_RNE_BIT);
|
||||
|
||||
ssp_update_rx_level();
|
||||
}
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::ssp_update_tx_level()
|
||||
{
|
||||
if (m_ssp_regs.tx_fifo_count <= 4)
|
||||
m_ssp_regs.sssr |= (1 << SSSR_TFS_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_TFS_BIT);
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::ssp_tx_fifo_push(const uint16_t data)
|
||||
{
|
||||
if (m_ssp_regs.tx_fifo_count < ARRAY_LENGTH(m_ssp_regs.tx_fifo))
|
||||
{
|
||||
m_ssp_regs.tx_fifo[m_ssp_regs.tx_fifo_write_idx] = data;
|
||||
m_ssp_regs.tx_fifo_write_idx = (m_ssp_regs.tx_fifo_write_idx + 1) % ARRAY_LENGTH(m_ssp_regs.tx_fifo);
|
||||
m_ssp_regs.tx_fifo_count++;
|
||||
|
||||
if (m_ssp_regs.tx_fifo_count != ARRAY_LENGTH(m_ssp_regs.tx_fifo))
|
||||
m_ssp_regs.sssr |= (1 << SSSR_TNF_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_TNF_BIT);
|
||||
|
||||
ssp_update_tx_level();
|
||||
}
|
||||
|
||||
if (m_ssp_regs.tx_fifo_count || m_ssp_regs.rx_fifo_count)
|
||||
m_ssp_regs.sssr |= (1 << SSSR_BSY_BIT);
|
||||
else
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_BSY_BIT);
|
||||
}
|
||||
|
||||
uint16_t sa1110_periphs_device::ssp_rx_fifo_pop()
|
||||
{
|
||||
uint16_t data = m_ssp_regs.rx_fifo[m_ssp_regs.rx_fifo_read_idx];
|
||||
if (m_ssp_regs.rx_fifo_count)
|
||||
{
|
||||
m_ssp_regs.rx_fifo_read_idx = (m_ssp_regs.rx_fifo_read_idx + 1) % ARRAY_LENGTH(m_ssp_regs.rx_fifo);
|
||||
m_ssp_regs.rx_fifo_count--;
|
||||
|
||||
if (m_ssp_regs.rx_fifo_count == 0)
|
||||
m_ssp_regs.sssr &= ~(1 << SSSR_RNE_BIT);
|
||||
|
||||
ssp_update_rx_level();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
uint32_t sa1110_periphs_device::ssp_r(offs_t offset, uint32_t mem_mask)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REG_SSCR0:
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_r: SSP Control Register 0: %08x & %08x\n", machine().describe_context(), m_ssp_regs.sscr0, mem_mask);
|
||||
return m_ssp_regs.sscr0;
|
||||
case REG_SSCR1:
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_r: SSP Control Register 1: %08x & %08x\n", machine().describe_context(), m_ssp_regs.sscr1, mem_mask);
|
||||
return m_ssp_regs.sscr1;
|
||||
case REG_SSDR:
|
||||
{
|
||||
const uint32_t data = ssp_rx_fifo_pop();
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_r: SSP Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
return data;
|
||||
}
|
||||
case REG_SSSR:
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_r: SSP Status Register: %08x & %08x\n", machine().describe_context(), m_ssp_regs.sssr, mem_mask);
|
||||
LOGMASKED(LOG_SSP, "%s: Transmit FIFO Not Full: %d\n", machine().describe_context(), BIT(m_ssp_regs.sssr, SSSR_TNF_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Receive FIFO Not Empty: %d\n", machine().describe_context(), BIT(m_ssp_regs.sssr, SSSR_RNE_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: SSP Busy: %d\n", machine().describe_context(), BIT(m_ssp_regs.sssr, SSSR_BSY_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Transmit FIFO Service Request: %d\n", machine().describe_context(), BIT(m_ssp_regs.sssr, SSSR_TFS_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Receive FIFO Service Request: %d\n", machine().describe_context(), BIT(m_ssp_regs.sssr, SSSR_RFS_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Receive Overrun: %d\n", machine().describe_context(), BIT(m_ssp_regs.sssr, SSSR_ROR_BIT));
|
||||
return m_ssp_regs.sssr;
|
||||
default:
|
||||
LOGMASKED(LOG_SSP | LOG_UNKNOWN, "%s: ssp_r: Unknown address: %08x & %08x\n", machine().describe_context(), SSP_BASE_ADDR | (offset << 2), mem_mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::ssp_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case REG_SSCR0:
|
||||
{
|
||||
static const char *const s_dss_sizes[16] =
|
||||
{
|
||||
"Invalid [1]", "Invalid [2]", "Invalid [3]", "4-bit",
|
||||
"5-bit", "6-bit", "7-bit", "8-bit",
|
||||
"9-bit", "10-bit", "11-bit", "12-bit",
|
||||
"13-bit", "14-bit", "15-bit", "16-bit"
|
||||
};
|
||||
static const char *const s_frf_formats[4] = { "Motorola SPI", "TI Synchronous Serial", "National Microwire", "Reserved" };
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_w: SSP Control Register 0: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_SSP, "%s: Data Size Select: %s\n", machine().describe_context(), s_dss_sizes[(data & SSCR0_DSS_MASK) >> SSCR0_DSS_BIT]);
|
||||
LOGMASKED(LOG_SSP, "%s: Frame Format: %s\n", machine().describe_context(), s_frf_formats[(data & SSCR0_FRF_MASK) >> SSCR0_FRF_BIT]);
|
||||
LOGMASKED(LOG_SSP, "%s: SSP Enable: %d\n", machine().describe_context(), BIT(data, SSCR0_SSE_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Serial Clock Rate Divisor: %d\n", machine().describe_context(), 2 * (data & SSCR0_DSS_MASK) >> SSCR0_DSS_BIT);
|
||||
const uint32_t old = m_ssp_regs.sscr0;
|
||||
COMBINE_DATA(&m_ssp_regs.sscr0);
|
||||
if (BIT(old ^ m_ssp_regs.sscr0, SSCR0_SSE_BIT))
|
||||
ssp_update_enable_state();
|
||||
break;
|
||||
}
|
||||
case REG_SSCR1:
|
||||
{
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_w: SSP Control Register 1: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_SSP, "%s: Receive FIFO Interrupt Enable: %d\n", machine().describe_context(), BIT(data, SSCR1_RIE_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Transmit FIFO Interrupt Enable: %d\n", machine().describe_context(), BIT(data, SSCR1_TIE_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Loopback Mode Enable: %d\n", machine().describe_context(), BIT(data, SSCR1_LBM_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Serial Clock Polarity: %d\n", machine().describe_context(), BIT(data, SSCR1_SPO_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: Serial Clock Phase: %d\n", machine().describe_context(), BIT(data, SSCR1_SPH_BIT));
|
||||
LOGMASKED(LOG_SSP, "%s: External Clock Select: %d\n", machine().describe_context(), BIT(data, SSCR1_ECS_BIT));
|
||||
COMBINE_DATA(&m_ssp_regs.sscr1);
|
||||
break;
|
||||
}
|
||||
case REG_SSDR:
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_w: SSP Data Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
ssp_tx_fifo_push((uint16_t)data);
|
||||
break;
|
||||
case REG_SSSR:
|
||||
LOGMASKED(LOG_SSP, "%s: ssp_w: SSP Status Register = %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_SSP, "%s: Clear Receive Overrun: %d\n", machine().describe_context(), BIT(data, SSSR_ROR_BIT));
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_SSP | LOG_UNKNOWN, "%s: ssp_w: Unknown address: %08x = %08x & %08x\n", machine().describe_context(), SSP_BASE_ADDR | (offset << 2), data, mem_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Intel SA-1110 Operating System Timer
|
||||
@ -730,6 +965,9 @@ void sa1110_periphs_device::ostimer_update_count()
|
||||
{
|
||||
const attotime time_delta = machine().time() - m_ostmr_regs.last_count_sync;
|
||||
const uint64_t ticks_elapsed = time_delta.as_ticks(INTERNAL_OSC);
|
||||
if (ticks_elapsed == 0ULL) // Accrue time until we can tick at least once
|
||||
return;
|
||||
|
||||
const uint32_t wrapped_ticks = (uint32_t)ticks_elapsed;
|
||||
m_ostmr_regs.oscr += wrapped_ticks;
|
||||
m_ostmr_regs.last_count_sync = machine().time();
|
||||
@ -762,7 +1000,7 @@ uint32_t sa1110_periphs_device::ostimer_r(offs_t offset, uint32_t mem_mask)
|
||||
LOGMASKED(LOG_OSTIMER, "%s: ostimer_r: OS Timer Match Register 3: %08x & %08x\n", machine().describe_context(), m_ostmr_regs.osmr[3], mem_mask);
|
||||
return m_ostmr_regs.osmr[3];
|
||||
case REG_OSCR:
|
||||
LOGMASKED(LOG_OSTIMER, "%s: ostimer_r: OS Timer Counter Register: %08x & %08x\n", machine().describe_context(), m_ostmr_regs.oscr, mem_mask);
|
||||
LOGMASKED(LOG_OSTIMER_HF, "%s: ostimer_r: OS Timer Counter Register: %08x & %08x\n", machine().describe_context(), m_ostmr_regs.oscr, mem_mask);
|
||||
return m_ostmr_regs.oscr;
|
||||
case REG_OSSR:
|
||||
LOGMASKED(LOG_OSTIMER, "%s: ostimer_r: OS Timer Status Register: %08x & %08x\n", machine().describe_context(), m_ostmr_regs.ossr, mem_mask);
|
||||
@ -1225,7 +1463,7 @@ void sa1110_periphs_device::gpio_w(offs_t offset, uint32_t data, uint32_t mem_ma
|
||||
}
|
||||
case REG_GPCR:
|
||||
{
|
||||
LOGMASKED(LOG_GPIO, "%s: gpio_w: GPIO Pin Output Clear Register (ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
LOGMASKED(LOG_GPIO, "%s: gpio_w: GPIO Pin Output Clear Register: %08x & %08x\n", machine().describe_context(), data, mem_mask);
|
||||
const uint32_t old = m_gpio_regs.output_latch;
|
||||
m_gpio_regs.output_latch &= ~(data & mem_mask);
|
||||
const uint32_t changed = ((old ^ m_gpio_regs.output_latch) & m_gpio_regs.gpdr) & ~m_gpio_regs.gafr;
|
||||
@ -1412,6 +1650,20 @@ void sa1110_periphs_device::device_start()
|
||||
save_item(NAME(m_mcp_regs.telecom_tx_fifo_count));
|
||||
m_mcp_regs.telecom_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::mcp_telecom_tx_callback), this));
|
||||
|
||||
save_item(NAME(m_ssp_regs.sscr0));
|
||||
save_item(NAME(m_ssp_regs.sscr1));
|
||||
save_item(NAME(m_ssp_regs.sssr));
|
||||
save_item(NAME(m_ssp_regs.rx_fifo));
|
||||
save_item(NAME(m_ssp_regs.rx_fifo_read_idx));
|
||||
save_item(NAME(m_ssp_regs.rx_fifo_write_idx));
|
||||
save_item(NAME(m_ssp_regs.rx_fifo_count));
|
||||
m_ssp_regs.rx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::ssp_rx_callback), this));
|
||||
save_item(NAME(m_ssp_regs.tx_fifo));
|
||||
save_item(NAME(m_ssp_regs.tx_fifo_read_idx));
|
||||
save_item(NAME(m_ssp_regs.tx_fifo_write_idx));
|
||||
save_item(NAME(m_ssp_regs.tx_fifo_count));
|
||||
m_ssp_regs.tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sa1110_periphs_device::ssp_tx_callback), this));
|
||||
|
||||
save_item(NAME(m_ostmr_regs.osmr));
|
||||
save_item(NAME(m_ostmr_regs.oscr));
|
||||
save_item(NAME(m_ostmr_regs.ossr));
|
||||
@ -1459,6 +1711,7 @@ void sa1110_periphs_device::device_start()
|
||||
save_item(NAME(m_intc_regs.icpr));
|
||||
|
||||
m_gpio_out.resolve_all_safe();
|
||||
m_ssp_out.resolve_safe();
|
||||
}
|
||||
|
||||
void sa1110_periphs_device::device_reset()
|
||||
@ -1504,6 +1757,21 @@ void sa1110_periphs_device::device_reset()
|
||||
m_mcp_regs.telecom_tx_fifo_count = 0;
|
||||
m_mcp_regs.telecom_tx_timer->adjust(attotime::never);
|
||||
|
||||
// init SSP regs
|
||||
m_ssp_regs.sscr0 = 0;
|
||||
m_ssp_regs.sscr1 = 0;
|
||||
m_ssp_regs.sssr = (1 << SSSR_TNF_BIT);
|
||||
memset(m_ssp_regs.rx_fifo, 0, sizeof(uint16_t) * ARRAY_LENGTH(m_ssp_regs.rx_fifo));
|
||||
m_ssp_regs.rx_fifo_read_idx = 0;
|
||||
m_ssp_regs.rx_fifo_write_idx = 0;
|
||||
m_ssp_regs.rx_fifo_count = 0;
|
||||
m_ssp_regs.rx_timer->adjust(attotime::never);
|
||||
memset(m_ssp_regs.tx_fifo, 0, sizeof(uint16_t) * ARRAY_LENGTH(m_ssp_regs.tx_fifo));
|
||||
m_ssp_regs.tx_fifo_read_idx = 0;
|
||||
m_ssp_regs.tx_fifo_write_idx = 0;
|
||||
m_ssp_regs.tx_fifo_count = 0;
|
||||
m_ssp_regs.tx_timer->adjust(attotime::never);
|
||||
|
||||
// init OS timers
|
||||
memset(m_ostmr_regs.osmr, 0, sizeof(uint32_t) * 4);
|
||||
m_ostmr_regs.ower = 0;
|
||||
|
@ -41,10 +41,15 @@ public:
|
||||
template <unsigned Line> void gpio_in(int state) { gpio_in(Line, state); }
|
||||
template <unsigned Line> auto gpio_out() { return m_gpio_out[Line].bind(); }
|
||||
|
||||
void ssp_in(uint16_t data) { ssp_rx_fifo_push(data); }
|
||||
auto ssp_out() { return m_ssp_out.bind(); }
|
||||
|
||||
uint32_t uart3_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void uart3_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t mcp_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void mcp_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t ssp_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void ssp_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t ostimer_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
void ostimer_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
|
||||
uint32_t rtc_r(offs_t offset, uint32_t mem_mask = ~0);
|
||||
@ -92,6 +97,15 @@ protected:
|
||||
void mcp_codec_read(offs_t offset);
|
||||
void mcp_codec_write(offs_t offset, uint16_t data);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(ssp_rx_callback);
|
||||
TIMER_CALLBACK_MEMBER(ssp_tx_callback);
|
||||
void ssp_update_enable_state();
|
||||
void ssp_update_rx_level();
|
||||
void ssp_update_tx_level();
|
||||
void ssp_rx_fifo_push(const uint16_t data);
|
||||
void ssp_tx_fifo_push(const uint16_t data);
|
||||
uint16_t ssp_rx_fifo_pop();
|
||||
|
||||
TIMER_CALLBACK_MEMBER(ostimer_tick_cb);
|
||||
void ostimer_update_count();
|
||||
void ostimer_update_match_timer(int channel);
|
||||
@ -126,6 +140,12 @@ protected:
|
||||
REG_MCDR2 = (0x00000010 >> 2),
|
||||
REG_MCSR = (0x00000018 >> 2),
|
||||
|
||||
SSP_BASE_ADDR = 0x80070000,
|
||||
REG_SSCR0 = (0x00000060 >> 2),
|
||||
REG_SSCR1 = (0x00000064 >> 2),
|
||||
REG_SSDR = (0x0000006c >> 2),
|
||||
REG_SSSR = (0x00000074 >> 2),
|
||||
|
||||
OSTMR_BASE_ADDR = 0x90000000,
|
||||
REG_OSMR0 = (0x00000000 >> 2),
|
||||
REG_OSMR1 = (0x00000004 >> 2),
|
||||
@ -241,6 +261,28 @@ protected:
|
||||
MCSR_ACE_BIT = 14,
|
||||
MCSR_TCE_BIT = 15,
|
||||
|
||||
SSCR0_DSS_BIT = 0,
|
||||
SSCR0_DSS_MASK = 0x0000000f,
|
||||
SSCR0_FRF_BIT = 4,
|
||||
SSCR0_FRF_MASK = 0x00000030,
|
||||
SSCR0_SSE_BIT = 7,
|
||||
SSCR0_SCR_BIT = 8,
|
||||
SSCR0_SCR_MASK = 0x0000ff00,
|
||||
|
||||
SSCR1_RIE_BIT = 0,
|
||||
SSCR1_TIE_BIT = 1,
|
||||
SSCR1_LBM_BIT = 2,
|
||||
SSCR1_SPO_BIT = 3,
|
||||
SSCR1_SPH_BIT = 4,
|
||||
SSCR1_ECS_BIT = 5,
|
||||
|
||||
SSSR_TNF_BIT = 1,
|
||||
SSSR_RNE_BIT = 2,
|
||||
SSSR_BSY_BIT = 3,
|
||||
SSSR_TFS_BIT = 4,
|
||||
SSSR_RFS_BIT = 5,
|
||||
SSSR_ROR_BIT = 6,
|
||||
|
||||
RTSR_AL_BIT = 0,
|
||||
RTSR_AL_MASK = (1 << RTSR_AL_BIT),
|
||||
RTSR_HZ_BIT = 1,
|
||||
@ -360,6 +402,25 @@ protected:
|
||||
emu_timer *telecom_tx_timer;
|
||||
};
|
||||
|
||||
struct ssp_regs
|
||||
{
|
||||
uint32_t sscr0;
|
||||
uint32_t sscr1;
|
||||
uint32_t sssr;
|
||||
|
||||
uint16_t rx_fifo[8];
|
||||
int rx_fifo_read_idx;
|
||||
int rx_fifo_write_idx;
|
||||
int rx_fifo_count;
|
||||
emu_timer *rx_timer;
|
||||
|
||||
uint16_t tx_fifo[8];
|
||||
int tx_fifo_read_idx;
|
||||
int tx_fifo_write_idx;
|
||||
int tx_fifo_count;
|
||||
emu_timer *tx_timer;
|
||||
};
|
||||
|
||||
struct ostimer_regs
|
||||
{
|
||||
uint32_t osmr[4];
|
||||
@ -423,6 +484,7 @@ protected:
|
||||
|
||||
uart_regs m_uart_regs;
|
||||
mcp_regs m_mcp_regs;
|
||||
ssp_regs m_ssp_regs;
|
||||
ostimer_regs m_ostmr_regs;
|
||||
rtc_regs m_rtc_regs;
|
||||
power_regs m_power_regs;
|
||||
@ -436,6 +498,7 @@ protected:
|
||||
optional_device<ucb1200_device> m_codec;
|
||||
|
||||
devcb_write_line::array<28> m_gpio_out;
|
||||
devcb_write16 m_ssp_out;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SA1110_PERIPHERALS, sa1110_periphs_device)
|
||||
|
1733
src/devices/machine/sa1111.cpp
Normal file
1733
src/devices/machine/sa1111.cpp
Normal file
File diff suppressed because it is too large
Load Diff
591
src/devices/machine/sa1111.h
Normal file
591
src/devices/machine/sa1111.h
Normal file
@ -0,0 +1,591 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/***************************************************************************
|
||||
|
||||
Intel SA1111 Microprocessor Companion Chip skeleton
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_SA1111
|
||||
#define MAME_MACHINE_SA1111
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/input_merger.h"
|
||||
|
||||
class sa1111_device : public device_t
|
||||
{
|
||||
public:
|
||||
sa1111_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
|
||||
template <unsigned Line> void pa_in(int state) { gpio_in(0 + Line, state); }
|
||||
template <unsigned Line> void pb_in(int state) { gpio_in(8 + Line, state); }
|
||||
template <unsigned Line> void pc_in(int state) { gpio_in(16 + Line, state); }
|
||||
template <unsigned Line> auto pa_out() { return m_gpio_out[0 + Line].bind(); }
|
||||
template <unsigned Line> auto pb_out() { return m_gpio_out[8 + Line].bind(); }
|
||||
template <unsigned Line> auto pc_out() { return m_gpio_out[16 + Line].bind(); }
|
||||
|
||||
void ssp_in(uint16_t data) { ssp_rx_fifo_push(data); }
|
||||
auto ssp_out() { return m_ssp_out.bind(); }
|
||||
|
||||
void map(address_map &map);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
|
||||
TIMER_CALLBACK_MEMBER(ssp_rx_callback);
|
||||
TIMER_CALLBACK_MEMBER(ssp_tx_callback);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(audio_rx_callback);
|
||||
TIMER_CALLBACK_MEMBER(audio_tx_callback);
|
||||
|
||||
uint32_t unknown_r(offs_t offset, uint32_t mem_mask);
|
||||
void unknown_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t skcr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t smcr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skid_r(offs_t offset, uint32_t mem_mask);
|
||||
void skcr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void smcr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t skpcr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skcdr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skaud_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skpmc_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skptc_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skpen0_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skpwm0_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skpen1_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t skpwm1_r(offs_t offset, uint32_t mem_mask);
|
||||
void skpcr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skcdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skaud_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skpmc_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skptc_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skpen0_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skpwm0_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skpen1_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void skpwm1_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t ohci_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t usb_status_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t usb_reset_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t usb_fifo_r(offs_t offset, uint32_t mem_mask);
|
||||
void ohci_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void usb_reset_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void usb_int_test_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t sacr0_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sacr1_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sacr2_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sasr0_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sasr1_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t l3car_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t l3cdr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t accar_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t accdr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t acsar_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t acsdr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadtcs_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadtsa_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadtca_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadtsb_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadtcb_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadrcs_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadrsa_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadrca_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadrsb_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadrcb_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sadr_r(offs_t offset, uint32_t mem_mask);
|
||||
void sacr0_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sacr1_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sacr2_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sascr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void l3car_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void l3cdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void accar_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void accdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void acsar_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void acsdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadtcs_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadtsa_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadtca_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadtsb_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadtcb_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadrcs_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadrsa_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadrca_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadrsb_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadrcb_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void saitr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sadr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t sspcr0_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sspcr1_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sspsr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t sspdr_r(offs_t offset, uint32_t mem_mask);
|
||||
void sspcr0_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sspcr1_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sspsr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sspitr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void sspdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t track_kbdcr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t track_kbdstat_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t track_kbddata_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t track_kbdclkdiv_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t track_kbdprecnt_r(offs_t offset, uint32_t mem_mask);
|
||||
void track_kbdcr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void track_kbdstat_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void track_kbddata_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void track_kbdclkdiv_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void track_kbdprecnt_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void track_kbditr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t mouse_kbdcr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t mouse_kbdstat_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t mouse_kbddata_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t mouse_kbdclkdiv_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t mouse_kbdprecnt_r(offs_t offset, uint32_t mem_mask);
|
||||
void mouse_kbdcr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void mouse_kbdstat_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void mouse_kbddata_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void mouse_kbdclkdiv_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void mouse_kbdprecnt_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void mouse_kbditr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
template <unsigned Block> uint32_t ddr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> uint32_t drr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> uint32_t sdr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> uint32_t ssr_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Block> void ddr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Block> void dwr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Block> void sdr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Block> void ssr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
template <unsigned Set> uint32_t inttest_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t inten_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t intpol_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t inttstsel_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t intstat_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t wake_en_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> uint32_t wake_pol_r(offs_t offset, uint32_t mem_mask);
|
||||
template <unsigned Set> void inttest_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void inten_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void intpol_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void inttstsel_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void intclr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void intset_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void wake_en_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
template <unsigned Set> void wake_pol_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
uint32_t pccr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t pcssr_r(offs_t offset, uint32_t mem_mask);
|
||||
uint32_t pcsr_r(offs_t offset, uint32_t mem_mask);
|
||||
void pccr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
void pcssr_w(offs_t offset, uint32_t data, uint32_t mem_mask);
|
||||
|
||||
void ssp_update_enable_state();
|
||||
void ssp_update_rx_level();
|
||||
void ssp_update_tx_level();
|
||||
void ssp_rx_fifo_push(const uint16_t data);
|
||||
void ssp_tx_fifo_push(const uint16_t data);
|
||||
uint16_t ssp_rx_fifo_pop();
|
||||
|
||||
void gpio_in(const uint32_t line, const int state);
|
||||
void gpio_update_direction(const uint32_t block, const uint32_t old_dir);
|
||||
void gpio_update_outputs(const uint32_t block, const uint32_t old_latch);
|
||||
|
||||
// register contents
|
||||
enum : uint32_t
|
||||
{
|
||||
SKCR_PLLB_BIT = 0,
|
||||
SKCR_RCLK_BIT = 1,
|
||||
SKCR_SLEEP_BIT = 2,
|
||||
SKCR_DOZE_BIT = 3,
|
||||
SKCR_VCO_BIT = 4,
|
||||
SKCR_SCANTST_BIT = 5,
|
||||
SKCR_CLKTST_BIT = 6,
|
||||
SKCR_RDY_BIT = 7,
|
||||
SKCR_SLAC_BIT = 8,
|
||||
SKCR_OPPC_BIT = 9,
|
||||
SKCR_PII_BIT = 10,
|
||||
SKCR_UIOTEN_BIT = 11,
|
||||
SKCR_OEEN_BIT = 12,
|
||||
|
||||
SMCR_DTIM_BIT = 0,
|
||||
SMCR_MBGE_BIT = 1,
|
||||
SMCR_DRAC_BIT = 2,
|
||||
SMCR_DRAC_MASK = 0x0000001c,
|
||||
SMCR_CLAT_BIT = 5,
|
||||
|
||||
SKPCR_UCLKE_BIT = 0,
|
||||
SKPCR_ACCLKE_BIT = 1,
|
||||
SKPCR_ISCLKE_BIT = 2,
|
||||
SKPCR_L3CLKE_BIT = 3,
|
||||
SKPCR_SCLKE_BIT = 4,
|
||||
SKPCR_PMCLKE_BIT = 5,
|
||||
SKPCR_PTCLKE_BIT = 6,
|
||||
SKPCR_DCLKE_BIT = 7,
|
||||
SKPCR_PWMCLKE_BIT = 8,
|
||||
|
||||
SKCDR_FBD_BIT = 0,
|
||||
SKCDR_FBD_MASK = 0x0000007f,
|
||||
SKCDR_IPD_BIT = 7,
|
||||
SKCDR_IPD_MASK = 0x00000f80,
|
||||
SKCDR_OPD_BIT = 12,
|
||||
SKCDR_OPD_MASK = 0x00003000,
|
||||
SKCDR_OPS_BIT = 14,
|
||||
|
||||
SKAUD_ACD_BIT = 0,
|
||||
SKAUD_ACD_MASK = 0x0000007f,
|
||||
|
||||
SKPMC_PMCD_BIT = 0,
|
||||
SKPMC_PMCD_MASK = 0x000000ff,
|
||||
|
||||
SKPTC_PTCD_BIT = 0,
|
||||
SKPTC_PTCD_MASK = 0x000000ff,
|
||||
|
||||
SKPEN0_PWM0EN_BIT = 0,
|
||||
|
||||
SKPWM0_PWM0CK_BIT = 0,
|
||||
SKPWM0_PWM0CK_MASK = 0x000000ff,
|
||||
|
||||
SKPEN1_PWM1EN_BIT = 0,
|
||||
|
||||
SKPWM1_PWM1CK_BIT = 0,
|
||||
SKPWM1_PWM1CK_MASK = 0x000000ff,
|
||||
|
||||
USBSTAT_IHRW_BIT = 7,
|
||||
USBSTAT_IHBA_BIT = 8,
|
||||
USBSTAT_NHT_BIT = 9,
|
||||
USBSTAT_NHFCT_BIT = 10,
|
||||
USBSTAT_UPRT_BIT = 11,
|
||||
|
||||
USBRST_FIR_BIT = 0,
|
||||
USBRST_FHR_BIT = 1,
|
||||
USBRST_CGR_BIT = 2,
|
||||
USBRST_SSDC_BIT = 3,
|
||||
USBRST_UIT_BIT = 4,
|
||||
USBRST_SSE_BIT = 5,
|
||||
USBRST_PSPL_BIT = 6,
|
||||
USBRST_PCPL_BIT = 7,
|
||||
|
||||
USBINT_IHRWT_BIT = 7,
|
||||
USBINT_IHBAT_BIT = 8,
|
||||
USBINT_NHT_BIT = 9,
|
||||
USBINT_NHFCT_BIT = 10,
|
||||
USBINT_UPRT_BIT = 11,
|
||||
|
||||
SACR0_ENB_BIT = 0,
|
||||
SACR0_BCKD_BIT = 2,
|
||||
SACR0_RST_BIT = 3,
|
||||
SACR0_TFTH_BIT = 8,
|
||||
SACR0_TFTH_MASK = 0x00000f00,
|
||||
SACR0_RFTH_BIT = 12,
|
||||
SACR0_RFTH_MASK = 0x0000f000,
|
||||
|
||||
SACR1_AMSL_BIT = 0,
|
||||
SACR1_L3EN_BIT = 1,
|
||||
SACR1_L3MB_BIT = 2,
|
||||
SACR1_DREC_BIT = 3,
|
||||
SACR1_DRPL_BIT = 4,
|
||||
SACR1_ENLBF_BIT = 5,
|
||||
|
||||
SACR2_TS3V_BIT = 0,
|
||||
SACR2_TS4V_BIT = 1,
|
||||
SACR2_WKUP_BIT = 2,
|
||||
SACR2_DREC_BIT = 3,
|
||||
SACR2_DRPL_BIT = 4,
|
||||
SACR2_ENLBF_BIT = 5,
|
||||
SACR2_RESET_BIT = 6,
|
||||
|
||||
SASCR_TUR_BIT = 5,
|
||||
SASCR_ROR_BIT = 6,
|
||||
SASCR_DTS_BIT = 16,
|
||||
SASCR_RDD_BIT = 17,
|
||||
SASCR_STO_BIT = 18,
|
||||
|
||||
SASR0_TNF_BIT = 0,
|
||||
SASR0_RNE_BIT = 1,
|
||||
SASR0_BSY_BIT = 2,
|
||||
SASR0_TFS_BIT = 3,
|
||||
SASR0_RFS_BIT = 4,
|
||||
SASR0_TUR_BIT = 5,
|
||||
SASR0_ROR_BIT = 6,
|
||||
SASR0_TFL_BIT = 7,
|
||||
SASR0_TFL_MASK = 0x00000f00,
|
||||
SASR0_RFL_BIT = 12,
|
||||
SASR0_RFL_MASK = 0x0000f000,
|
||||
SASR0_L3WD_BIT = 16,
|
||||
SASR0_L3RD_BIT = 17,
|
||||
|
||||
SASR1_TNF_BIT = 0,
|
||||
SASR1_RNE_BIT = 1,
|
||||
SASR1_BSY_BIT = 2,
|
||||
SASR1_TFS_BIT = 3,
|
||||
SASR1_RFS_BIT = 4,
|
||||
SASR1_TUR_BIT = 5,
|
||||
SASR1_ROR_BIT = 6,
|
||||
SASR1_TFL_BIT = 8,
|
||||
SASR1_TFL_MASK = 0x00000f00,
|
||||
SASR1_RFL_BIT = 12,
|
||||
SASR1_RFL_MASK = 0x0000f000,
|
||||
SASR1_CADT_BIT = 16,
|
||||
SASR1_SADR_BIT = 17,
|
||||
SASR1_RSTO_BIT = 18,
|
||||
SASR1_CLPM_BIT = 19,
|
||||
SASR1_CRDY_BIT = 20,
|
||||
SASR1_RS3V_BIT = 21,
|
||||
SASR1_RS4V_BIT = 22,
|
||||
|
||||
SADTCS_TDEN_BIT = 0,
|
||||
SADTCS_TDBDA_BIT = 3,
|
||||
SADTCS_TDSTA_BIT = 4,
|
||||
SADTCS_TDBDB_BIT = 5,
|
||||
SADTCS_TDSTB_BIT = 6,
|
||||
|
||||
SADRCS_RDEN_BIT = 0,
|
||||
SADRCS_RDBDA_BIT = 3,
|
||||
SADRCS_RDSTA_BIT = 4,
|
||||
SADRCS_RDBDB_BIT = 5,
|
||||
SADRCS_RDSTB_BIT = 6,
|
||||
|
||||
SAITR_TFS_BIT = 0,
|
||||
SAITR_RFS_BIT = 1,
|
||||
SAITR_TUR_BIT = 2,
|
||||
SAITR_ROR_BIT = 3,
|
||||
SAITR_CADT_BIT = 4,
|
||||
SAITR_SADR_BIT = 5,
|
||||
SAITR_RSTO_BIT = 6,
|
||||
SAITR_TDBDA_BIT = 8,
|
||||
SAITR_TDBDB_BIT = 9,
|
||||
SAITR_RDBDA_BIT = 10,
|
||||
SAITR_RDBDB_BIT = 11,
|
||||
|
||||
SSPCR0_DSS_BIT = 0,
|
||||
SSPCR0_DSS_MASK = 0x0000000f,
|
||||
SSPCR0_FRF_BIT = 4,
|
||||
SSPCR0_FRF_MASK = 0x00000030,
|
||||
SSPCR0_FRF_SPI = 0,
|
||||
SSPCR0_FRF_SSP = 1,
|
||||
SSPCR0_FRF_MWIRE = 2,
|
||||
SSPCR0_FRF_RESV = 3,
|
||||
SSPCR0_SSPEN_BIT = 7,
|
||||
SSPCR0_SCR_BIT = 8,
|
||||
SSPCR0_SCR_MASK = 0x0000ff00,
|
||||
|
||||
SSPCR1_LBM_BIT = 2,
|
||||
SSPCR1_SPO_BIT = 3,
|
||||
SSPCR1_SPH_BIT = 4,
|
||||
SSPCR1_TFT_BIT = 7,
|
||||
SSPCR1_TFT_MASK = 0x00000780,
|
||||
SSPCR1_RFT_BIT = 11,
|
||||
SSPCR1_RFT_MASK = 0x00007800,
|
||||
|
||||
SSPSR_TNF_BIT = 2,
|
||||
SSPSR_RNE_BIT = 3,
|
||||
SSPSR_BSY_BIT = 4,
|
||||
SSPSR_TFS_BIT = 5,
|
||||
SSPSR_RFS_BIT = 6,
|
||||
SSPSR_ROR_BIT = 7,
|
||||
SSPSR_TFL_BIT = 8,
|
||||
SSPSR_TFL_MASK = 0x00000f00,
|
||||
SSPSR_RFL_BIT = 12,
|
||||
SSPSR_RFL_MASK = 0x0000f000,
|
||||
|
||||
SSPITR_TFS_BIT = 2,
|
||||
SSPITR_RFS_BIT = 3,
|
||||
SSPITR_ROR_BIT = 4,
|
||||
|
||||
KBDCR_FKC_BIT = 0,
|
||||
KBDCR_FKD_BIT = 1,
|
||||
KBDCR_ENA_BIT = 3,
|
||||
|
||||
KBDSTAT_KBC_BIT = 0,
|
||||
KBDSTAT_KBD_BIT = 1,
|
||||
KBDSTAT_RXP_BIT = 2,
|
||||
KBDSTAT_ENA_BIT = 3,
|
||||
KBDSTAT_RXB_BIT = 4,
|
||||
KBDSTAT_RXF_BIT = 5,
|
||||
KBDSTAT_TXB_BIT = 6,
|
||||
KBDSTAT_TXE_BIT = 7,
|
||||
KBDSTAT_STP_BIT = 8,
|
||||
|
||||
KBDCLKDIV_DV_BIT = 0,
|
||||
KBDCLKDIV_DV_MASK = 0x00000003,
|
||||
|
||||
PCSR_S0R_BIT = 0,
|
||||
PCSR_S1R_BIT = 1,
|
||||
PCSR_S0CD_BIT = 2,
|
||||
PCSR_S1CD_BIT = 3,
|
||||
PCSR_S0VS1_BIT = 4,
|
||||
PCSR_S0VS2_BIT = 5,
|
||||
PCSR_S1VS1_BIT = 6,
|
||||
PCSR_S1VS2_BIT = 7,
|
||||
PCSR_S0WP_BIT = 8,
|
||||
PCSR_S1WP_BIT = 9,
|
||||
PCSR_S0BVD1_BIT = 10,
|
||||
PCSR_S0BVD2_BIT = 11,
|
||||
PCSR_S1BVD1_BIT = 12,
|
||||
PCSR_S1BVD2_BIT = 13,
|
||||
|
||||
PCCR_S0RST_BIT = 0,
|
||||
PCCR_S1RST_BIT = 1,
|
||||
PCCR_S0FLT_BIT = 2,
|
||||
PCCR_S1FLT_BIT = 3,
|
||||
PCCR_S0PWEN_BIT = 4,
|
||||
PCCR_S1PWEN_BIT = 5,
|
||||
PCCR_S0PSE_BIT = 6,
|
||||
PCCR_S1PSE_BIT = 7,
|
||||
|
||||
PCSSR_S0SLP_BIT = 0,
|
||||
PCSSR_S1SLP_BIT = 1
|
||||
};
|
||||
|
||||
struct sbi_regs
|
||||
{
|
||||
uint32_t skcr;
|
||||
uint32_t smcr;
|
||||
uint32_t skid;
|
||||
};
|
||||
|
||||
struct sysctrl_regs
|
||||
{
|
||||
uint32_t skpcr;
|
||||
uint32_t skcdr;
|
||||
uint32_t skaud;
|
||||
uint32_t skpmc;
|
||||
uint32_t skptc;
|
||||
uint32_t skpen0;
|
||||
uint32_t skpwm0;
|
||||
uint32_t skpen1;
|
||||
uint32_t skpwm1;
|
||||
};
|
||||
|
||||
struct usb_regs
|
||||
{
|
||||
uint32_t ohci[22];
|
||||
uint32_t status;
|
||||
uint32_t reset;
|
||||
uint32_t int_test;
|
||||
uint32_t fifo[12];
|
||||
};
|
||||
|
||||
struct audio_regs
|
||||
{
|
||||
uint32_t sacr0;
|
||||
uint32_t sacr1;
|
||||
uint32_t sacr2;
|
||||
uint32_t sasr0;
|
||||
uint32_t sasr1;
|
||||
uint32_t l3car;
|
||||
uint32_t l3cdr;
|
||||
uint32_t accar;
|
||||
uint32_t accdr;
|
||||
uint32_t acsar;
|
||||
uint32_t acsdr;
|
||||
uint32_t sadtcs;
|
||||
uint32_t sadtsa;
|
||||
uint32_t sadtca;
|
||||
uint32_t sadtsb;
|
||||
uint32_t sadtcb;
|
||||
uint32_t sadrcs;
|
||||
uint32_t sadrsa;
|
||||
uint32_t sadrca;
|
||||
uint32_t sadrsb;
|
||||
uint32_t sadrcb;
|
||||
uint32_t saitr;
|
||||
|
||||
uint32_t rx_fifo[16];
|
||||
int rx_fifo_read_idx;
|
||||
int rx_fifo_write_idx;
|
||||
int rx_fifo_count;
|
||||
emu_timer *rx_timer;
|
||||
|
||||
uint32_t tx_fifo[16];
|
||||
int tx_fifo_read_idx;
|
||||
int tx_fifo_write_idx;
|
||||
int tx_fifo_count;
|
||||
emu_timer *tx_timer;
|
||||
};
|
||||
|
||||
struct ssp_regs
|
||||
{
|
||||
uint32_t sspcr0;
|
||||
uint32_t sspcr1;
|
||||
uint32_t sspsr;
|
||||
uint32_t sspitr;
|
||||
|
||||
uint16_t rx_fifo[16];
|
||||
int rx_fifo_read_idx;
|
||||
int rx_fifo_write_idx;
|
||||
int rx_fifo_count;
|
||||
emu_timer *rx_timer;
|
||||
|
||||
uint16_t tx_fifo[16];
|
||||
int tx_fifo_read_idx;
|
||||
int tx_fifo_write_idx;
|
||||
int tx_fifo_count;
|
||||
emu_timer *tx_timer;
|
||||
};
|
||||
|
||||
struct ps2_regs
|
||||
{
|
||||
uint32_t kbdcr;
|
||||
uint32_t kbdstat;
|
||||
uint32_t kbddata_tx;
|
||||
uint32_t kbddata_rx;
|
||||
uint32_t kbdclkdiv;
|
||||
uint32_t kbdprecnt;
|
||||
uint32_t kbditr;
|
||||
};
|
||||
|
||||
struct gpio_regs
|
||||
{
|
||||
uint32_t ddr[3];
|
||||
uint32_t level[3];
|
||||
uint32_t sdr[3];
|
||||
uint32_t ssr[3];
|
||||
uint32_t out_latch[3];
|
||||
uint32_t in_latch[3];
|
||||
};
|
||||
|
||||
struct intc_regs
|
||||
{
|
||||
uint32_t inttest[2];
|
||||
uint32_t inten[2];
|
||||
uint32_t intpol[2];
|
||||
uint32_t inttstsel;
|
||||
uint32_t intstat[2];
|
||||
uint32_t wake_en[2];
|
||||
uint32_t wake_pol[2];
|
||||
};
|
||||
|
||||
struct card_regs
|
||||
{
|
||||
uint32_t pccr;
|
||||
uint32_t pcssr;
|
||||
uint32_t pcsr;
|
||||
};
|
||||
|
||||
sbi_regs m_sbi_regs;
|
||||
sysctrl_regs m_sk_regs;
|
||||
usb_regs m_usb_regs;
|
||||
audio_regs m_audio_regs;
|
||||
ssp_regs m_ssp_regs;
|
||||
ps2_regs m_track_regs;
|
||||
ps2_regs m_mouse_regs;
|
||||
gpio_regs m_gpio_regs;
|
||||
intc_regs m_intc_regs;
|
||||
card_regs m_card_regs;
|
||||
|
||||
devcb_write_line::array<24> m_gpio_out;
|
||||
devcb_write16 m_ssp_out;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(SA1111, sa1111_device)
|
||||
|
||||
#endif // MAME_MACHINE_SA1111
|
1579
src/devices/video/sed1356.cpp
Normal file
1579
src/devices/video/sed1356.cpp
Normal file
File diff suppressed because it is too large
Load Diff
547
src/devices/video/sed1356.h
Normal file
547
src/devices/video/sed1356.h
Normal file
@ -0,0 +1,547 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/**********************************************************************
|
||||
|
||||
Epson SED1356 LCD Controller emulation skeleton
|
||||
|
||||
Status:
|
||||
- Currently hard-coded for use with the Jornada 720 driver.
|
||||
- Register contents are correctly stored, logged and masked, but
|
||||
register handling is otherwise non-present.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_VIDEO_SED1356_H
|
||||
#define MAME_VIDEO_SED1356_H
|
||||
|
||||
#pragma once
|
||||
|
||||
class sed1356_device : public device_t,
|
||||
public device_video_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sed1356_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0);
|
||||
|
||||
void map(address_map &map);
|
||||
void vram_map(address_map &map);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
uint8_t revision_r(offs_t offset);
|
||||
|
||||
uint8_t misc_r(offs_t offset);
|
||||
void misc_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t gpio_config_r(offs_t offset);
|
||||
void gpio_config_w(offs_t offset, uint8_t data);
|
||||
uint8_t gpio_ctrl_r(offs_t offset);
|
||||
void gpio_ctrl_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t md_config_readback_r(offs_t offset);
|
||||
void md_config_readback_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t mem_clk_config_r(offs_t offset);
|
||||
uint8_t lcd_pclk_config_r(offs_t offset);
|
||||
uint8_t crt_pclk_config_r(offs_t offset);
|
||||
uint8_t mplug_clk_config_r(offs_t offset);
|
||||
void mem_clk_config_w(offs_t offset, uint8_t data);
|
||||
void lcd_pclk_config_w(offs_t offset, uint8_t data);
|
||||
void crt_pclk_config_w(offs_t offset, uint8_t data);
|
||||
void mplug_clk_config_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t mem_wait_select_r(offs_t offset);
|
||||
uint8_t mem_config_r(offs_t offset);
|
||||
uint8_t dram_refresh_select_r(offs_t offset);
|
||||
uint8_t dram_timing_ctrl_r(offs_t offset);
|
||||
void mem_wait_select_w(offs_t offset, uint8_t data);
|
||||
void mem_config_w(offs_t offset, uint8_t data);
|
||||
void dram_refresh_select_w(offs_t offset, uint8_t data);
|
||||
void dram_timing_ctrl0_w(offs_t offset, uint8_t data);
|
||||
void dram_timing_ctrl1_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t panel_type_r(offs_t offset);
|
||||
uint8_t mod_rate_r(offs_t offset);
|
||||
void panel_type_w(offs_t offset, uint8_t data);
|
||||
void mod_rate_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t lcd_display_width_r(offs_t offset);
|
||||
uint8_t lcd_hblank_period_r(offs_t offset);
|
||||
uint8_t tft_fpline_start_pos_r(offs_t offset);
|
||||
uint8_t tft_fpline_pulse_width_r(offs_t offset);
|
||||
uint8_t lcd_display_height_r(offs_t offset);
|
||||
uint8_t lcd_vblank_period_r(offs_t offset);
|
||||
uint8_t tft_fpframe_start_pos_r(offs_t offset);
|
||||
uint8_t tft_fpframe_pulse_width_r(offs_t offset);
|
||||
uint8_t lcd_display_mode_r(offs_t offset);
|
||||
uint8_t lcd_misc_r(offs_t offset);
|
||||
uint8_t lcd_display_start_addr_r(offs_t offset);
|
||||
uint8_t lcd_mem_addr_offset_r(offs_t offset);
|
||||
uint8_t lcd_pixel_pan_r(offs_t offset);
|
||||
uint8_t lcd_display_fifo_hi_thresh_r(offs_t offset);
|
||||
uint8_t lcd_display_fifo_lo_thresh_r(offs_t offset);
|
||||
void lcd_display_width_w(offs_t offset, uint8_t data);
|
||||
void lcd_hblank_period_w(offs_t offset, uint8_t data);
|
||||
void tft_fpline_start_pos_w(offs_t offset, uint8_t data);
|
||||
void tft_fpline_pulse_width_w(offs_t offset, uint8_t data);
|
||||
void lcd_display_height_w(offs_t offset, uint8_t data);
|
||||
void lcd_vblank_period_w(offs_t offset, uint8_t data);
|
||||
void tft_fpframe_start_pos_w(offs_t offset, uint8_t data);
|
||||
void tft_fpframe_pulse_width_w(offs_t offset, uint8_t data);
|
||||
void lcd_display_mode_w(offs_t offset, uint8_t data);
|
||||
void lcd_misc_w(offs_t offset, uint8_t data);
|
||||
void lcd_display_start_addr_w(offs_t offset, uint8_t data);
|
||||
void lcd_mem_addr_offset_w(offs_t offset, uint8_t data);
|
||||
void lcd_pixel_pan_w(offs_t offset, uint8_t data);
|
||||
void lcd_display_fifo_hi_thresh_w(offs_t offset, uint8_t data);
|
||||
void lcd_display_fifo_lo_thresh_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t crt_display_width_r(offs_t offset);
|
||||
uint8_t crt_hblank_period_r(offs_t offset);
|
||||
uint8_t crt_hrtc_start_pos_r(offs_t offset);
|
||||
uint8_t crt_hrtc_pulse_width_r(offs_t offset);
|
||||
uint8_t crt_display_height_r(offs_t offset);
|
||||
uint8_t crt_vblank_period_r(offs_t offset);
|
||||
uint8_t crt_vrtc_start_pos_r(offs_t offset);
|
||||
uint8_t crt_vrtc_pulse_width_r(offs_t offset);
|
||||
uint8_t crt_output_ctrl_r(offs_t offset);
|
||||
uint8_t crt_display_mode_r(offs_t offset);
|
||||
uint8_t crt_display_start_addr_r(offs_t offset);
|
||||
uint8_t crt_mem_addr_offset_r(offs_t offset);
|
||||
uint8_t crt_pixel_pan_r(offs_t offset);
|
||||
uint8_t crt_display_fifo_hi_thresh_r(offs_t offset);
|
||||
uint8_t crt_display_fifo_lo_thresh_r(offs_t offset);
|
||||
void crt_display_width_w(offs_t offset, uint8_t data);
|
||||
void crt_hblank_period_w(offs_t offset, uint8_t data);
|
||||
void crt_hrtc_start_pos_w(offs_t offset, uint8_t data);
|
||||
void crt_hrtc_pulse_width_w(offs_t offset, uint8_t data);
|
||||
void crt_display_height_w(offs_t offset, uint8_t data);
|
||||
void crt_vblank_period_w(offs_t offset, uint8_t data);
|
||||
void crt_vrtc_start_pos_w(offs_t offset, uint8_t data);
|
||||
void crt_vrtc_pulse_width_w(offs_t offset, uint8_t data);
|
||||
void crt_output_ctrl_w(offs_t offset, uint8_t data);
|
||||
void crt_display_mode_w(offs_t offset, uint8_t data);
|
||||
void crt_display_start_addr_w(offs_t offset, uint8_t data);
|
||||
void crt_mem_addr_offset_w(offs_t offset, uint8_t data);
|
||||
void crt_pixel_pan_w(offs_t offset, uint8_t data);
|
||||
void crt_display_fifo_hi_thresh_w(offs_t offset, uint8_t data);
|
||||
void crt_display_fifo_lo_thresh_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t lcd_cursor_ctrl_r(offs_t offset);
|
||||
uint8_t lcd_cursor_start_addr_r(offs_t offset);
|
||||
uint8_t lcd_cursor_x_r(offs_t offset);
|
||||
uint8_t lcd_cursor_y_r(offs_t offset);
|
||||
uint8_t lcd_cursor_color0_r(offs_t offset);
|
||||
uint8_t lcd_cursor_color1_r(offs_t offset);
|
||||
uint8_t lcd_cursor_fifo_thresh_r(offs_t offset);
|
||||
void lcd_cursor_ctrl_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_start_addr_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_x_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_y_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_color0_blu_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_color0_grn_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_color0_red_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_color1_blu_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_color1_grn_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_color1_red_w(offs_t offset, uint8_t data);
|
||||
void lcd_cursor_fifo_thresh_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t crt_cursor_ctrl_r(offs_t offset);
|
||||
uint8_t crt_cursor_start_addr_r(offs_t offset);
|
||||
uint8_t crt_cursor_x_r(offs_t offset);
|
||||
uint8_t crt_cursor_y_r(offs_t offset);
|
||||
uint8_t crt_cursor_color0_r(offs_t offset);
|
||||
uint8_t crt_cursor_color1_r(offs_t offset);
|
||||
uint8_t crt_cursor_fifo_thresh_r(offs_t offset);
|
||||
void crt_cursor_ctrl_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_start_addr_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_x_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_y_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_color0_blu_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_color0_grn_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_color0_red_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_color1_blu_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_color1_grn_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_color1_red_w(offs_t offset, uint8_t data);
|
||||
void crt_cursor_fifo_thresh_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t bitblt_ctrl0_r(offs_t offset);
|
||||
uint8_t bitblt_ctrl1_r(offs_t offset);
|
||||
uint8_t bitblt_rop_code_r(offs_t offset);
|
||||
uint8_t bitblt_operation_r(offs_t offset);
|
||||
uint8_t bitblt_src_start_addr_r(offs_t offset);
|
||||
uint8_t bitblt_dst_start_addr_r(offs_t offset);
|
||||
uint8_t bitblt_mem_addr_offset_r(offs_t offset);
|
||||
uint8_t bitblt_width_r(offs_t offset);
|
||||
uint8_t bitblt_height_r(offs_t offset);
|
||||
uint8_t bitblt_bgcolor_r(offs_t offset);
|
||||
uint8_t bitblt_fgcolor_r(offs_t offset);
|
||||
void bitblt_ctrl0_w(offs_t offset, uint8_t data);
|
||||
void bitblt_ctrl1_w(offs_t offset, uint8_t data);
|
||||
void bitblt_rop_code_w(offs_t offset, uint8_t data);
|
||||
void bitblt_operation_w(offs_t offset, uint8_t data);
|
||||
void bitblt_src_start_addr_w(offs_t offset, uint8_t data);
|
||||
void bitblt_dst_start_addr_w(offs_t offset, uint8_t data);
|
||||
void bitblt_mem_addr_offset_w(offs_t offset, uint8_t data);
|
||||
void bitblt_width_w(offs_t offset, uint8_t data);
|
||||
void bitblt_height_w(offs_t offset, uint8_t data);
|
||||
void bitblt_bgcolor_w(offs_t offset, uint8_t data);
|
||||
void bitblt_fgcolor_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t lut_mode_r(offs_t offset);
|
||||
uint8_t lut_addr_r(offs_t offset);
|
||||
uint8_t lut_data_r(offs_t offset);
|
||||
void lut_mode_w(offs_t offset, uint8_t data);
|
||||
void lut_addr_w(offs_t offset, uint8_t data);
|
||||
void lut_data_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t power_config_r(offs_t offset);
|
||||
uint8_t power_status_r(offs_t offset);
|
||||
void power_config_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t cpu_mem_watchdog_r(offs_t offset);
|
||||
void cpu_mem_watchdog_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t display_mode_r(offs_t offset);
|
||||
void display_mode_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t mplug_lcmd_r(offs_t offset);
|
||||
uint8_t mplug_resv_lcmd_r(offs_t offset);
|
||||
uint8_t mplug_cmd_r(offs_t offset);
|
||||
uint8_t mplug_resv_cmd_r(offs_t offset);
|
||||
uint8_t mplug_data_r(offs_t offset);
|
||||
void mplug_lcmd_w(offs_t offset, uint8_t data);
|
||||
void mplug_resv_lcmd_w(offs_t offset, uint8_t data);
|
||||
void mplug_cmd_w(offs_t offset, uint8_t data);
|
||||
void mplug_resv_cmd_w(offs_t offset, uint8_t data);
|
||||
void mplug_data_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint8_t bitblt_data_r(offs_t offset);
|
||||
void bitblt_data_w(offs_t offset, uint8_t data);
|
||||
|
||||
enum
|
||||
{
|
||||
MISC_RMS_BIT = 7,
|
||||
MISC_MASK = 0x80,
|
||||
|
||||
GPCFG_GPIO1_BIT = 1,
|
||||
GPCFG_GPIO2_BIT = 2,
|
||||
GPCFG_GPIO3_BIT = 3,
|
||||
GPCFG_MASK = 0x0e,
|
||||
|
||||
GPCTRL_GPIO1_BIT = 1,
|
||||
GPCTRL_GPIO2_BIT = 2,
|
||||
GPCTRL_GPIO3_BIT = 3,
|
||||
GPCTRL_MASK = 0x0e,
|
||||
|
||||
MEMCLK_SRC_BIT = 0,
|
||||
MEMCLK_DIV_BIT = 4,
|
||||
MEMCLK_MASK = 0x11,
|
||||
|
||||
LCDCLK_SRC_BIT = 0,
|
||||
LCDCLK_SRC_MASK = 0x03,
|
||||
LCDCLK_DIV_BIT = 4,
|
||||
LCDCLK_DIV_MASK = 0x30,
|
||||
LCDCLK_MASK = 0x33,
|
||||
|
||||
CRTCLK_SRC_BIT = 0,
|
||||
CRTCLK_SRC_MASK = 0x03,
|
||||
CRTCLK_DIV_BIT = 4,
|
||||
CRTCLK_DIV_MASK = 0x30,
|
||||
CRTCLK_2X_BIT = 7,
|
||||
CRTCLK_MASK = 0xb3,
|
||||
|
||||
PLUGCLK_SRC_BIT = 0,
|
||||
PLUGCLK_SRC_MASK = 0x03,
|
||||
PLUGCLK_DIV_BIT = 4,
|
||||
PLUGCLK_DIV_MASK = 0x30,
|
||||
PLUGCLK_MASK = 0x33,
|
||||
|
||||
CPUWAIT_SEL_BIT = 0,
|
||||
CPUWAIT_SEL_MASK = 0x03,
|
||||
CPUWAIT_MASK = 0x03,
|
||||
|
||||
MEMCFG_TYPE_BIT = 0,
|
||||
MEMCFG_TYPE_MASK = 0x03,
|
||||
MEMCFG_MASK = 0x03,
|
||||
|
||||
MEMRFSH_RATE_BIT = 0,
|
||||
MEMRFSH_RATE_MASK = 0x07,
|
||||
MEMRFSH_SEL_BIT = 6,
|
||||
MEMRFSH_SEL_MASK = 0xc0,
|
||||
MEMRFSH_MASK = 0xc7,
|
||||
|
||||
DRAMTIME1_MASK = 0x03,
|
||||
|
||||
PTYPE_TFT_PASS_BIT = 0,
|
||||
PTYPE_COUNT_BIT = 1,
|
||||
PTYPE_COLOR_BIT = 2,
|
||||
PTYPE_FORMAT_BIT = 3,
|
||||
PTYPE_WIDTH_BIT = 4,
|
||||
PTYPE_WIDTH_MASK = 0x30,
|
||||
PTYPE_EL_BIT = 7,
|
||||
PTYPE_MASK = 0xbf,
|
||||
|
||||
MODRATE_MASK = 0x3f,
|
||||
|
||||
LCDW_MASK = 0x7f,
|
||||
|
||||
LCDHBL_MASK = 0x1f,
|
||||
|
||||
TFTFPLS_MASK = 0x1f,
|
||||
|
||||
TFTFPLW_WIDTH_BIT = 0,
|
||||
TFTFPLW_WIDTH_MASK = 0x0f,
|
||||
TFTFPLW_POL_BIT = 7,
|
||||
TFTFPLW_MASK = 0x8f,
|
||||
|
||||
LCDH_MASK = 0x03ff,
|
||||
|
||||
LCDVBL_VALUE_BIT = 0,
|
||||
LCDVBL_VALUE_MASK = 0x3f,
|
||||
LCDVBL_STATUS_BIT = 7,
|
||||
LCDVBL_MASK = 0x3f,
|
||||
|
||||
TFTFPFS_MASK = 0x3f,
|
||||
|
||||
TFTFPFW_WIDTH_BIT = 0,
|
||||
TFTFPFW_WIDTH_MASK = 0x07,
|
||||
TFTFPFW_POL_BIT = 7,
|
||||
TFTFPFW_MASK = 0x87,
|
||||
|
||||
LCDMODE_BPP_BIT = 0,
|
||||
LCDMODE_BPP_MASK = 0x07,
|
||||
LCDMODE_SWIVEN1_BIT = 4,
|
||||
LCDMODE_BLANK_BIT = 7,
|
||||
LCDMODE_MASK = 0x97,
|
||||
|
||||
LCDMISC_DPDIS_BIT = 0,
|
||||
LCDMISC_DITHDIS_BIT = 1,
|
||||
LCDMISC_MASK = 0x03,
|
||||
|
||||
LCDDS_MASK = 0x000fffff,
|
||||
|
||||
LCDMOFS_MASK = 0x07ff,
|
||||
|
||||
LCDPAN_PAN_BIT = 0,
|
||||
LCDPAN_PAN_MASK = 0x03,
|
||||
LCDPAN_MASK = 0x03,
|
||||
|
||||
LCDFIFO_MASK = 0x3f,
|
||||
|
||||
CRTW_MASK = 0x7f,
|
||||
|
||||
CRTHBL_MASK = 0x3f,
|
||||
|
||||
CRTHRTS_MASK = 0x3f,
|
||||
|
||||
CRTHRTW_WIDTH_BIT = 0,
|
||||
CRTHRTW_WIDTH_MASK = 0x0f,
|
||||
CRTHRTW_POL_BIT = 7,
|
||||
CRTHRTW_MASK = 0x8f,
|
||||
|
||||
CRTH_MASK = 0x03ff,
|
||||
|
||||
CRTVBL_VALUE_BIT = 0,
|
||||
CRTVBL_VALUE_MASK = 0x7f,
|
||||
CRTVBL_STATUS_BIT = 7,
|
||||
CRTVBL_MASK = 0xff,
|
||||
|
||||
CRTVRTS_MASK = 0x7f,
|
||||
|
||||
CRTVRTW_WIDTH_BIT = 0,
|
||||
CRTVRTW_WIDTH_MASK = 0x07,
|
||||
CRTVRTW_POL_BIT = 7,
|
||||
CRTVRTW_MASK = 0x87,
|
||||
|
||||
CRTCTRL_PAL_BIT = 0,
|
||||
CRTCTRL_SVID_BIT = 1,
|
||||
CRTCTRL_DACLVL_BIT = 3,
|
||||
CRTCTRL_LUMF_BIT = 4,
|
||||
CRTCTRL_CHRF_BIT = 5,
|
||||
CRTCTRL_MASK = 0x3b,
|
||||
|
||||
CRTMODE_BPP_BIT = 0,
|
||||
CRTMODE_BPP_MASK = 0x07,
|
||||
CRTMODE_BLANK_BIT = 7,
|
||||
CRTMODE_MASK = 0x87,
|
||||
|
||||
CRTDS_MASK = 0x000fffff,
|
||||
|
||||
CRTMOFS_MASK = 0x07ff,
|
||||
|
||||
CRTPAN_PAN_BIT = 0,
|
||||
CRTPAN_PAN_MASK = 0x03,
|
||||
CRTPAN_MASK = 0x03,
|
||||
|
||||
CRTFIFO_MASK = 0x3f,
|
||||
|
||||
CURCTRL_MODE_BIT = 0,
|
||||
CURCTRL_MODE_MASK = 0x03,
|
||||
CURCTRL_MASK = 0x03,
|
||||
|
||||
CURX_SIGN_BIT = 15,
|
||||
CURX_MASK = 0x83ff,
|
||||
|
||||
CURY_SIGN_BIT = 15,
|
||||
CURY_MASK = 0x83ff,
|
||||
|
||||
CURB_MASK = 0x1f,
|
||||
CURG_MASK = 0x3f,
|
||||
CURR_MASK = 0x1f,
|
||||
|
||||
CUR_FIFO_MASK = 0x0f,
|
||||
|
||||
BBCTRL0_SRCLIN_BIT = 0,
|
||||
BBCTRL0_DSTLIN_BIT = 1,
|
||||
BBCTRL0_FULL_BIT = 4,
|
||||
BBCTRL0_HALF_BIT = 5,
|
||||
BBCTRL0_ANY_BIT = 6,
|
||||
BBCTRL0_ACTIVE_BIT = 7,
|
||||
BBCTRL0_WR_MASK = 0x03,
|
||||
|
||||
BBCTRL1_COLFMT_BIT = 0,
|
||||
BBCTRL1_FIFO_DEPTH_BIT = 4,
|
||||
BBCTRL1_WR_MASK = 0x11,
|
||||
|
||||
BBCODE_MASK = 0x0f,
|
||||
|
||||
BBOP_MASK = 0x0f,
|
||||
|
||||
BBSRC_MASK = 0x001fffff,
|
||||
BBDST_MASK = 0x001fffff,
|
||||
|
||||
BBMADR_MASK = 0x07ff,
|
||||
|
||||
BBWIDTH_MASK = 0x03ff,
|
||||
|
||||
BBHEIGHT_MASK = 0x03ff,
|
||||
|
||||
LUTMODE_MODE_BIT = 0,
|
||||
LUTMODE_MODE_MASK = 0x03,
|
||||
LUTMODE_MASK = 0x03,
|
||||
|
||||
LUTDATA_BIT = 4,
|
||||
LUTDATA_MASK = 0xf0,
|
||||
|
||||
PWRCFG_ENABLE_BIT = 0,
|
||||
PWRCFG_MASK = 0x01,
|
||||
|
||||
PWRSTAT_MCPSS_BIT = 0,
|
||||
PWRSTAT_LCDPSS_BIT = 1,
|
||||
PWRSTAT_MASK = 0x03,
|
||||
|
||||
WATCHDOG_MASK = 0x3f,
|
||||
|
||||
DISPMODE_MODE_BIT = 0,
|
||||
DISPMODE_MODE_MASK = 0x07,
|
||||
DISPMODE_SWIVEN0_BIT = 6,
|
||||
DISPMODE_MASK = 0x47
|
||||
};
|
||||
|
||||
uint8_t m_misc;
|
||||
uint8_t m_gpio_config;
|
||||
uint8_t m_gpio_ctrl;
|
||||
uint8_t m_md_config[2];
|
||||
|
||||
uint8_t m_memclk_config;
|
||||
uint8_t m_lcd_pclk_config;
|
||||
uint8_t m_crt_pclk_config;
|
||||
uint8_t m_mplug_clk_config;
|
||||
|
||||
uint8_t m_wait_state_sel;
|
||||
uint8_t m_mem_config;
|
||||
uint8_t m_dram_refresh;
|
||||
uint8_t m_dram_timing[2];
|
||||
|
||||
uint8_t m_panel_type;
|
||||
uint8_t m_mod_rate;
|
||||
|
||||
uint8_t m_lcd_width;
|
||||
uint8_t m_lcd_hblank_period;
|
||||
uint8_t m_tft_fpline_start;
|
||||
uint8_t m_tft_fpline_width;
|
||||
uint16_t m_lcd_height;
|
||||
uint8_t m_lcd_vblank_period;
|
||||
uint8_t m_tft_fpframe_start;
|
||||
uint8_t m_tft_fpframe_width;
|
||||
uint8_t m_lcd_mode;
|
||||
uint8_t m_lcd_misc;
|
||||
uint32_t m_lcd_addr;
|
||||
uint16_t m_lcd_mem_offset;
|
||||
uint8_t m_lcd_pan;
|
||||
uint8_t m_lcd_fifo_hi_thresh;
|
||||
uint8_t m_lcd_fifo_lo_thresh;
|
||||
|
||||
uint8_t m_crt_width;
|
||||
uint8_t m_crt_hblank_period;
|
||||
uint8_t m_crt_hrtc_start;
|
||||
uint8_t m_crt_hrtc_width;
|
||||
uint16_t m_crt_height;
|
||||
uint8_t m_crt_vblank_period;
|
||||
uint8_t m_crt_vrtc_start;
|
||||
uint8_t m_crt_vrtc_width;
|
||||
uint8_t m_crt_output_ctrl;
|
||||
uint8_t m_crt_mode;
|
||||
uint32_t m_crt_addr;
|
||||
uint16_t m_crt_mem_offset;
|
||||
uint8_t m_crt_pan;
|
||||
uint8_t m_crt_fifo_hi_thresh;
|
||||
uint8_t m_crt_fifo_lo_thresh;
|
||||
|
||||
uint8_t m_lcd_cursor_ctrl;
|
||||
uint8_t m_lcd_cursor_addr;
|
||||
uint16_t m_lcd_cursor_x;
|
||||
uint16_t m_lcd_cursor_y;
|
||||
uint8_t m_lcd_cursor_color0[3];
|
||||
uint8_t m_lcd_cursor_color1[3];
|
||||
uint8_t m_lcd_cursor_fifo_thresh;
|
||||
|
||||
uint8_t m_crt_cursor_ctrl;
|
||||
uint8_t m_crt_cursor_addr;
|
||||
uint16_t m_crt_cursor_x;
|
||||
uint16_t m_crt_cursor_y;
|
||||
uint8_t m_crt_cursor_color0[3];
|
||||
uint8_t m_crt_cursor_color1[3];
|
||||
uint8_t m_crt_cursor_fifo_thresh;
|
||||
|
||||
uint8_t m_bitblt_ctrl[2];
|
||||
uint8_t m_bitblt_rop;
|
||||
uint8_t m_bitblt_op;
|
||||
uint32_t m_bitblt_src_addr;
|
||||
uint32_t m_bitblt_dst_addr;
|
||||
uint16_t m_bitblt_mem_offset;
|
||||
uint16_t m_bitblt_width;
|
||||
uint16_t m_bitblt_height;
|
||||
uint16_t m_bitblt_bgcolor;
|
||||
uint16_t m_bitblt_fgcolor;
|
||||
|
||||
uint8_t m_lut_mode;
|
||||
uint8_t m_lut_addr;
|
||||
uint8_t m_lut_data;
|
||||
|
||||
uint8_t m_power_config;
|
||||
uint8_t m_power_status;
|
||||
|
||||
uint8_t m_watchdog;
|
||||
|
||||
uint8_t m_display_mode;
|
||||
|
||||
uint16_t m_mplug_lcmd;
|
||||
uint16_t m_mplug_resv_lcmd;
|
||||
uint16_t m_mplug_cmd;
|
||||
uint16_t m_mplug_resv_cmd;
|
||||
|
||||
required_shared_ptr<uint32_t> m_vram;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(SED1356, sed1356_device)
|
||||
|
||||
#endif // MAME_VIDEO_SED1356_H
|
301
src/mame/drivers/jornada.cpp
Normal file
301
src/mame/drivers/jornada.cpp
Normal file
@ -0,0 +1,301 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/***************************************************************************
|
||||
|
||||
HP Jornada PDA skeleton driver
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/arm7/arm7.h"
|
||||
#include "cpu/arm7/arm7core.h"
|
||||
#include "machine/sa1110.h"
|
||||
#include "machine/sa1111.h"
|
||||
#include "video/sed1356.h"
|
||||
#include "screen.h"
|
||||
#include "emupal.h"
|
||||
|
||||
#define LOG_MCU (1 << 1)
|
||||
#define LOG_ALL (LOG_MCU)
|
||||
|
||||
#define VERBOSE (LOG_ALL)
|
||||
#include "logmacro.h"
|
||||
|
||||
#define SA1110_CLOCK 206000000
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class jornada_state : public driver_device
|
||||
{
|
||||
public:
|
||||
jornada_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_ram(*this, "ram")
|
||||
, m_sa_periphs(*this, "onboard")
|
||||
, m_companion(*this, "companion")
|
||||
, m_eeprom_data(*this, "eeprom")
|
||||
, m_epson(*this, "epson")
|
||||
, m_kbd_port(*this, "KBD0")
|
||||
{ }
|
||||
|
||||
void jornada720(machine_config &config);
|
||||
|
||||
DECLARE_INPUT_CHANGED_MEMBER(key_changed);
|
||||
|
||||
enum
|
||||
{
|
||||
KEY_ON_OFF
|
||||
};
|
||||
|
||||
protected:
|
||||
// driver_device overrides
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void device_reset_after_children() override;
|
||||
|
||||
void main_map(address_map &map);
|
||||
|
||||
void mcu_byte_received(uint16_t data);
|
||||
void eeprom_cmd_received(uint16_t data);
|
||||
|
||||
enum mcu_state : int
|
||||
{
|
||||
MCU_IDLE,
|
||||
|
||||
MCU_KBD_SEND_COUNT,
|
||||
MCU_KBD_SEND_CODES
|
||||
};
|
||||
|
||||
// devices
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_shared_ptr<uint32_t> m_ram;
|
||||
required_device<sa1110_periphs_device> m_sa_periphs;
|
||||
required_device<sa1111_device> m_companion;
|
||||
required_region_ptr<uint8_t> m_eeprom_data;
|
||||
required_device<sed1356_device> m_epson;
|
||||
|
||||
required_ioport m_kbd_port;
|
||||
|
||||
// MCU-related members
|
||||
int m_mcu_state;
|
||||
uint8_t m_mcu_key_send_idx;
|
||||
uint8_t m_mcu_key_codes[2][8];
|
||||
uint8_t m_mcu_key_count[2];
|
||||
|
||||
// EEPROM-related members
|
||||
uint8_t m_eeprom_cmd;
|
||||
uint8_t m_eeprom_count;
|
||||
uint8_t m_eeprom_read_idx;
|
||||
};
|
||||
|
||||
void jornada_state::main_map(address_map &map)
|
||||
{
|
||||
map(0x00000000, 0x01ffffff).rom().region("firmware", 0);
|
||||
map(0x1a000000, 0x1a000fff).noprw();
|
||||
map(0x40000000, 0x40001fff).m(m_companion, FUNC(sa1111_device::map));
|
||||
map(0x48000000, 0x481fffff).m(m_epson, FUNC(sed1356_device::map));
|
||||
map(0x48200000, 0x4827ffff).m(m_epson, FUNC(sed1356_device::vram_map));
|
||||
map(0x80050000, 0x80050023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::uart3_r), FUNC(sa1110_periphs_device::uart3_w));
|
||||
map(0x80060000, 0x8006001b).rw(m_sa_periphs, FUNC(sa1110_periphs_device::mcp_r), FUNC(sa1110_periphs_device::mcp_w));
|
||||
map(0x80070000, 0x80070077).rw(m_sa_periphs, FUNC(sa1110_periphs_device::ssp_r), FUNC(sa1110_periphs_device::ssp_w));
|
||||
map(0x90000000, 0x9000001f).rw(m_sa_periphs, FUNC(sa1110_periphs_device::ostimer_r), FUNC(sa1110_periphs_device::ostimer_w));
|
||||
map(0x90010000, 0x9001000f).rw(m_sa_periphs, FUNC(sa1110_periphs_device::rtc_r), FUNC(sa1110_periphs_device::rtc_w));
|
||||
map(0x90020000, 0x9002001f).rw(m_sa_periphs, FUNC(sa1110_periphs_device::power_r), FUNC(sa1110_periphs_device::power_w));
|
||||
map(0x90030000, 0x90030007).rw(m_sa_periphs, FUNC(sa1110_periphs_device::reset_r), FUNC(sa1110_periphs_device::reset_w));
|
||||
map(0x90040000, 0x90040023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::gpio_r), FUNC(sa1110_periphs_device::gpio_w));
|
||||
map(0x90050000, 0x90050023).rw(m_sa_periphs, FUNC(sa1110_periphs_device::intc_r), FUNC(sa1110_periphs_device::intc_w));
|
||||
map(0xc0000000, 0xc1ffffff).ram().share("ram");
|
||||
}
|
||||
|
||||
void jornada_state::device_reset_after_children()
|
||||
{
|
||||
}
|
||||
|
||||
void jornada_state::mcu_byte_received(uint16_t data)
|
||||
{
|
||||
const uint8_t raw_value = (uint8_t)(data >> 8);
|
||||
const uint8_t value = bitswap<8>(raw_value, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
uint8_t response = 0x11;
|
||||
switch (m_mcu_state)
|
||||
{
|
||||
case MCU_IDLE:
|
||||
switch (value)
|
||||
{
|
||||
case 0x90:
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_IDLE: GetScanKeyCode, entering KBD_SEND_COUNT state\n");
|
||||
m_mcu_state = MCU_KBD_SEND_COUNT;
|
||||
m_mcu_key_send_idx = 1 - m_mcu_key_send_idx;
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_IDLE: Unknown (%02x), ignoring and sending TxDummy response\n", value);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MCU_KBD_SEND_COUNT:
|
||||
if (value == 0x11)
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_COUNT: TxDummy, entering KBD_SEND_CODES state\n");
|
||||
response = m_mcu_key_count[m_mcu_key_send_idx];
|
||||
m_mcu_state = MCU_KBD_SEND_CODES;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_COUNT: Unknown (%02x), sending ErrorCode response and returning to IDLE state\n");
|
||||
response = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MCU_KBD_SEND_CODES:
|
||||
if (value == 0x11)
|
||||
{
|
||||
m_mcu_key_count[m_mcu_key_send_idx]--;
|
||||
response = m_mcu_key_codes[m_mcu_key_send_idx][m_mcu_key_count[m_mcu_key_send_idx]];
|
||||
if (m_mcu_key_send_idx)
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_CODES: TxDummy, sending scan code %02x with %d remaining\n", response, m_mcu_key_count[m_mcu_key_send_idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_CODES: TxDummy, sending scan code %02x and returning to IDLE state\n", response);
|
||||
m_mcu_state = MCU_IDLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGMASKED(LOG_MCU, "mcu_byte_received in MCU_KBD_SEND_CODES: Unknown (%02x), sending ErrorCode response and returning to IDLE state\n");
|
||||
response = 0;
|
||||
}
|
||||
}
|
||||
|
||||
response = bitswap<8>(response, 0, 1, 2, 3, 4, 5, 6, 7);
|
||||
m_sa_periphs->ssp_in((uint16_t)response);
|
||||
}
|
||||
|
||||
void jornada_state::eeprom_cmd_received(uint16_t data)
|
||||
{
|
||||
bool reset_state = true;
|
||||
uint8_t response = 0;
|
||||
|
||||
if (m_eeprom_cmd == 0)
|
||||
{
|
||||
m_eeprom_cmd = (uint8_t)data;
|
||||
if (m_eeprom_cmd == 3)
|
||||
reset_state = false;
|
||||
}
|
||||
else if (m_eeprom_count == 0)
|
||||
{
|
||||
if (m_eeprom_cmd == 3)
|
||||
{
|
||||
m_eeprom_count = (uint8_t)data;
|
||||
m_eeprom_read_idx = 0;
|
||||
reset_state = false;
|
||||
}
|
||||
}
|
||||
else if (m_eeprom_read_idx < m_eeprom_count)
|
||||
{
|
||||
response = m_eeprom_data[m_eeprom_read_idx];
|
||||
m_eeprom_read_idx++;
|
||||
if (m_eeprom_read_idx < m_eeprom_count)
|
||||
reset_state = false;
|
||||
}
|
||||
|
||||
m_companion->ssp_in((uint16_t)response);
|
||||
|
||||
if (reset_state)
|
||||
{
|
||||
m_eeprom_cmd = 0;
|
||||
m_eeprom_count = 0;
|
||||
m_eeprom_read_idx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
INPUT_CHANGED_MEMBER(jornada_state::key_changed)
|
||||
{
|
||||
const uint8_t state = m_kbd_port->read();
|
||||
if (BIT(state, 0))
|
||||
{
|
||||
m_sa_periphs->gpio_in<0>(1);
|
||||
m_sa_periphs->gpio_in<0>(0);
|
||||
|
||||
const uint8_t key_recv_idx = 1 - m_mcu_key_send_idx;
|
||||
if (m_mcu_key_count[key_recv_idx] < 8)
|
||||
{
|
||||
m_mcu_key_codes[key_recv_idx][m_mcu_key_count[key_recv_idx]] = 0x7f;
|
||||
m_mcu_key_count[key_recv_idx]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( jornada720 )
|
||||
PORT_START("KBD0")
|
||||
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_OTHER) PORT_NAME("On/Off") PORT_CODE(KEYCODE_HOME) PORT_CHANGED_MEMBER(DEVICE_SELF, jornada_state, key_changed, jornada_state::KEY_ON_OFF)
|
||||
PORT_BIT(0xfe, IP_ACTIVE_HIGH, IPT_UNUSED)
|
||||
INPUT_PORTS_END
|
||||
|
||||
void jornada_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_mcu_state));
|
||||
save_item(NAME(m_mcu_key_send_idx));
|
||||
save_item(NAME(m_mcu_key_codes[0]));
|
||||
save_item(NAME(m_mcu_key_codes[1]));
|
||||
save_item(NAME(m_mcu_key_count));
|
||||
|
||||
save_item(NAME(m_eeprom_cmd));
|
||||
save_item(NAME(m_eeprom_count));
|
||||
save_item(NAME(m_eeprom_read_idx));
|
||||
}
|
||||
|
||||
void jornada_state::machine_reset()
|
||||
{
|
||||
m_mcu_state = MCU_IDLE;
|
||||
m_mcu_key_send_idx = 0;
|
||||
memset(m_mcu_key_codes[0], 0, 8);
|
||||
memset(m_mcu_key_codes[1], 0, 8);
|
||||
memset(m_mcu_key_count, 0, 2);
|
||||
|
||||
m_eeprom_cmd = 0;
|
||||
m_eeprom_count = 0;
|
||||
m_eeprom_read_idx = 0;
|
||||
}
|
||||
|
||||
void jornada_state::jornada720(machine_config &config)
|
||||
{
|
||||
SA1110(config, m_maincpu, SA1110_CLOCK);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &jornada_state::main_map);
|
||||
|
||||
SA1110_PERIPHERALS(config, m_sa_periphs, SA1110_CLOCK, m_maincpu);
|
||||
m_sa_periphs->ssp_out().set(FUNC(jornada_state::mcu_byte_received));
|
||||
|
||||
SA1111(config, m_companion);
|
||||
m_companion->ssp_out().set(FUNC(jornada_state::eeprom_cmd_received));
|
||||
|
||||
SED1356(config, m_epson);
|
||||
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
|
||||
screen.set_refresh_hz(60);
|
||||
screen.set_size(640, 240);
|
||||
screen.set_visarea(0, 640-1, 0, 240-1);
|
||||
screen.set_screen_update(m_epson, FUNC(sed1356_device::screen_update));
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
System driver(s)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
ROM_START( jorn720 )
|
||||
ROM_REGION32_LE( 0x2000000, "firmware", ROMREGION_ERASE00 )
|
||||
ROM_LOAD( "jornada720.bin", 0x0000000, 0x2000000, CRC(cb47d854) SHA1(d3664b748387026987ddc71f9840ee21e5753afd) )
|
||||
|
||||
ROM_REGION( 0x80, "eeprom", ROMREGION_ERASE00 )
|
||||
ROM_LOAD( "jorn720_eeprom.bin", 0x00, 0x80, CRC(12345678) SHA1(1234567812345678123456781234567812345678) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
COMP( 2000, jorn720, 0, 0, jornada720, jornada720, jornada_state, empty_init, "Hewlett Packard", "Jornada 720", MACHINE_IS_SKELETON )
|
@ -17299,6 +17299,9 @@ jongkyo // (c) 1985 Kiwako
|
||||
@source:jonos.cpp
|
||||
jonos //
|
||||
|
||||
@source:jornada.cpp
|
||||
jorn720 // (c) 2000 Hewlett Packard
|
||||
|
||||
@source:joystand.cpp
|
||||
joystand // 1997 Yuvo
|
||||
|
||||
|
@ -463,6 +463,7 @@ jade.cpp
|
||||
jazz.cpp
|
||||
jensen.cpp
|
||||
jonos.cpp
|
||||
jornada.cpp
|
||||
jr100.cpp
|
||||
jr200.cpp
|
||||
jtc.cpp
|
||||
|
Loading…
Reference in New Issue
Block a user