mirror of
https://github.com/holub/mame
synced 2025-06-30 16:00:01 +03:00
Checkpoint
This commit is contained in:
parent
1905f52ac8
commit
ad030cc4f4
@ -165,6 +165,12 @@ void mb86901_device::device_stop()
|
||||
|
||||
void mb86901_device::device_reset()
|
||||
{
|
||||
m_queued_tt = 0;
|
||||
m_queued_priority = 0;
|
||||
m_asi = 0;
|
||||
MAE = false;
|
||||
HOLD_BUS = false;
|
||||
|
||||
PC = 0;
|
||||
nPC = 4;
|
||||
memset(m_r, 0, sizeof(UINT32) * 120);
|
||||
@ -699,7 +705,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
bool v = ((arg1 & 0x80000000) == (arg2 & 0x80000000) && (arg2 & 0x80000000) != (result & 0x80000000)) || ((arg1 & 3) != 0) || ((arg2 & 3) != 0);
|
||||
if (v)
|
||||
{
|
||||
queue_trap(sparc_tag_overflow);
|
||||
trap(SPARC_TAG_OVERFLOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -716,7 +722,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
bool v = ((arg1 & 0x80000000) == (arg2 & 0x80000000) && (arg2 & 0x80000000) != (result & 0x80000000)) || ((arg1 & 3) != 0) || ((arg2 & 3) != 0);
|
||||
if (v)
|
||||
{
|
||||
queue_trap(sparc_tag_overflow);
|
||||
trap(SPARC_TAG_OVERFLOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -795,7 +801,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
case 41: // rd psr
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -805,7 +811,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
case 42: // rd wim
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -815,7 +821,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
case 43: // rd tbr
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -837,14 +843,14 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
case 49: // wr psr
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 new_psr = (arg1 ^ arg2) & ~PSR_ZERO_MASK;
|
||||
if ((new_psr & PSR_CWP_MASK) >= WINDOW_COUNT)
|
||||
{
|
||||
queue_trap(sparc_illegal_instruction);
|
||||
trap(SPARC_ILLEGAL_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -856,7 +862,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
case 50: // wr wim
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -866,7 +872,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
case 51: // wr tbr
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -876,13 +882,13 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
case 52: // FPop1
|
||||
if (FPU_DISABLED)
|
||||
{
|
||||
queue_trap(sparc_floating_point_disabled);
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
}
|
||||
break;
|
||||
case 53: // FPop2
|
||||
if (FPU_DISABLED)
|
||||
{
|
||||
queue_trap(sparc_floating_point_disabled);
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
}
|
||||
break;
|
||||
case 56: // jmpl
|
||||
@ -891,7 +897,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
m_icount--;
|
||||
if (addr & 3)
|
||||
{
|
||||
queue_trap(sparc_mem_address_not_aligned);
|
||||
trap(SPARC_MEM_ADDRESS_NOT_ALIGNED);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -909,11 +915,11 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
{
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_trap(sparc_illegal_instruction);
|
||||
trap(SPARC_ILLEGAL_INSTRUCTION);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -921,17 +927,17 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
{
|
||||
if (IS_USER)
|
||||
{
|
||||
queue_trap(sparc_reset, sparc_privileged_instruction);
|
||||
trap(SPARC_RESET, SPARC_PRIVILEGED_INSTRUCTION);
|
||||
break;
|
||||
}
|
||||
else if (m_wim & (1 << new_cwp))
|
||||
{
|
||||
queue_trap(sparc_reset, sparc_window_underflow);
|
||||
trap(SPARC_RESET, SPARC_WINDOW_UNDERFLOW);
|
||||
break;
|
||||
}
|
||||
else if (ADDRESS & 3)
|
||||
{
|
||||
queue_trap(sparc_reset, sparc_mem_address_not_aligned);
|
||||
trap(SPARC_RESET, SPARC_MEM_ADDRESS_NOT_ALIGNED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -963,7 +969,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
UINT8 new_cwp = ((m_cwp + WINDOW_COUNT) - 1) % WINDOW_COUNT;
|
||||
if (m_wim & (1 << new_cwp))
|
||||
{
|
||||
queue_trap(sparc_window_overflow);
|
||||
trap(SPARC_WINDOW_OVERFLOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -976,7 +982,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
UINT8 new_cwp = (m_cwp + 1) % WINDOW_COUNT;
|
||||
if (m_wim & (1 << new_cwp))
|
||||
{
|
||||
queue_trap(sparc_window_overflow);
|
||||
trap(SPARC_WINDOW_UNDERFLOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -985,7 +991,7 @@ bool mb86901_device::execute_group2(UINT32 op)
|
||||
break;
|
||||
}
|
||||
default:
|
||||
queue_trap(sparc_illegal_instruction);
|
||||
trap(SPARC_ILLEGAL_INSTRUCTION);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1014,17 +1020,17 @@ bool mb86901_device::check_main_traps(UINT32 op, bool privileged, UINT32 alignme
|
||||
bool trap_queued = false;
|
||||
if (privileged && !m_s)
|
||||
{
|
||||
queue_trap(sparc_privileged_instruction);
|
||||
trap(SPARC_PRIVILEGED_INSTRUCTION);
|
||||
trap_queued = true;
|
||||
}
|
||||
if (alignment & ADDRESS)
|
||||
{
|
||||
queue_trap(sparc_mem_address_not_aligned);
|
||||
trap(SPARC_MEM_ADDRESS_NOT_ALIGNED);
|
||||
trap_queued = true;
|
||||
}
|
||||
if ((registeralign & RD) || (noimmediate && USEIMM))
|
||||
{
|
||||
queue_trap(sparc_illegal_instruction);
|
||||
trap(SPARC_ILLEGAL_INSTRUCTION);
|
||||
trap_queued = true;
|
||||
}
|
||||
return trap_queued;
|
||||
@ -1051,21 +1057,44 @@ void mb86901_device::execute_group3(UINT32 op)
|
||||
switch (OP3)
|
||||
{
|
||||
case 0: // ld
|
||||
{
|
||||
check_main_traps(op, false, 3, 0, false);
|
||||
SET_RDREG(read_word(m_data_asi, ADDRESS));
|
||||
UINT32 result = read_word(m_data_asi, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 1: // ldub
|
||||
SET_RDREG(read_byte(m_data_asi, ADDRESS));
|
||||
{
|
||||
UINT32 result = read_byte(m_data_asi, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 2: // lduh
|
||||
{
|
||||
check_main_traps(op, false, 1, 0, false);
|
||||
SET_RDREG(read_half(m_data_asi, ADDRESS));
|
||||
UINT32 result = read_half(m_data_asi, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 3: // ldd
|
||||
{
|
||||
check_main_traps(op, false, 7, 1, false);
|
||||
SET_RDREG(read_word(m_data_asi, ADDRESS));
|
||||
REG(RD+1) = read_word(m_data_asi, ADDRESS+4);
|
||||
UINT32 result = read_word(m_data_asi, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
result = read_word(m_data_asi, ADDRESS+4);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
REG(RD+1) = result;
|
||||
break;
|
||||
}
|
||||
case 4: // st
|
||||
check_main_traps(op, false, 3, 0, false);
|
||||
write_word(m_data_asi, ADDRESS, RDREG);
|
||||
@ -1080,38 +1109,78 @@ void mb86901_device::execute_group3(UINT32 op)
|
||||
case 7: // std
|
||||
check_main_traps(op, false, 7, 1, false);
|
||||
write_word(m_data_asi, ADDRESS, RDREG);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
write_word(m_data_asi, ADDRESS, REG(RD+1));
|
||||
break;
|
||||
case 9: // ldsb
|
||||
SET_RDREG(read_signed_byte(m_data_asi, ADDRESS));
|
||||
{
|
||||
UINT32 result = read_signed_byte(m_data_asi, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 10: // lsdh
|
||||
{
|
||||
check_main_traps(op, false, 1, 0, false);
|
||||
SET_RDREG(read_signed_half(m_data_asi, ADDRESS));
|
||||
UINT32 result = read_signed_half(m_data_asi, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 13: // ldstub
|
||||
SET_RDREG(read_byte(m_data_asi, ADDRESS));
|
||||
{
|
||||
UINT32 result = read_byte(m_data_asi, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
write_byte(m_data_asi, ADDRESS, 0xff);
|
||||
break;
|
||||
}
|
||||
case 15: // swap, SPARCv8
|
||||
break;
|
||||
case 16: // lda
|
||||
{
|
||||
check_main_traps(op, true, 3, 0, true);
|
||||
SET_RDREG(read_word(ASI, ADDRESS));
|
||||
UINT32 result = read_word(ASI, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 17: // lduba
|
||||
{
|
||||
check_main_traps(op, true, 0, 0, true);
|
||||
SET_RDREG(read_byte(ASI, ADDRESS));
|
||||
UINT32 result = read_byte(ASI, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 18: // lduha
|
||||
{
|
||||
check_main_traps(op, true, 1, 0, true);
|
||||
SET_RDREG(read_half(ASI, ADDRESS));
|
||||
UINT32 result = read_half(ASI, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 19: // ldda
|
||||
{
|
||||
check_main_traps(op, true, 7, 1, true);
|
||||
SET_RDREG(read_word(ASI, ADDRESS));
|
||||
REG(RD+1) = read_word(ASI, ADDRESS+4);
|
||||
UINT32 result = read_word(ASI, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
result = read_word(ASI, ADDRESS+4);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
REG(RD+1) = result;
|
||||
break;
|
||||
}
|
||||
case 20: // sta
|
||||
check_main_traps(op, true, 3, 0, true);
|
||||
write_word(ASI, ADDRESS, RDREG);
|
||||
@ -1127,36 +1196,67 @@ void mb86901_device::execute_group3(UINT32 op)
|
||||
case 23: // stda
|
||||
check_main_traps(op, true, 7, 1, true);
|
||||
write_word(ASI, ADDRESS, RDREG);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
write_word(ASI, ADDRESS+4, REG(RD+1));
|
||||
break;
|
||||
case 25: // ldsba
|
||||
{
|
||||
check_main_traps(op, true, 0, 0, true);
|
||||
SET_RDREG(read_signed_byte(ASI, ADDRESS));
|
||||
UINT32 result = read_signed_byte(ASI, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 26: // ldsha
|
||||
{
|
||||
check_main_traps(op, true, 1, 0, true);
|
||||
SET_RDREG(read_signed_half(ASI, ADDRESS));
|
||||
UINT32 result = read_signed_half(ASI, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
break;
|
||||
}
|
||||
case 29: // ldstuba
|
||||
{
|
||||
check_main_traps(op, true, 0, 0, true);
|
||||
SET_RDREG(read_byte(ASI, ADDRESS));
|
||||
UINT32 result = read_byte(ASI, ADDRESS);
|
||||
if (MAE || HOLD_BUS)
|
||||
break;
|
||||
SET_RDREG(result);
|
||||
write_byte(ASI, ADDRESS, 0xff);
|
||||
break;
|
||||
}
|
||||
case 31: // swapa, SPARCv8
|
||||
break;
|
||||
case 32: // ld fpr
|
||||
if (FPU_DISABLED)
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
break;
|
||||
case 33: // ld fsr
|
||||
if (FPU_DISABLED)
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
break;
|
||||
case 35: // ldd fpr
|
||||
if (FPU_DISABLED)
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
break;
|
||||
case 36: // st fpr
|
||||
if (FPU_DISABLED)
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
break;
|
||||
case 37: // st fsr
|
||||
if (FPU_DISABLED)
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
break;
|
||||
case 38: // std fq, SPARCv8
|
||||
if (FPU_DISABLED)
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
break;
|
||||
case 39: // std fpr
|
||||
if (FPU_DISABLED)
|
||||
trap(SPARC_FLOATING_POINT_DISABLED);
|
||||
break;
|
||||
case 40: // ld cpr, SPARCv8
|
||||
break;
|
||||
@ -1174,6 +1274,9 @@ void mb86901_device::execute_group3(UINT32 op)
|
||||
break;
|
||||
}
|
||||
|
||||
if (MAE || HOLD_BUS)
|
||||
m_icount--;
|
||||
else
|
||||
m_icount -= ldst_cycles[OP3];
|
||||
}
|
||||
|
||||
@ -1253,7 +1356,7 @@ bool mb86901_device::execute_ticc(UINT32 op)
|
||||
{
|
||||
UINT32 arg2 = USEIMM ? SIMM7 : RS2REG;
|
||||
UINT8 tt = 128 + ((RS1REG + arg2) & 0x7f);
|
||||
queue_trap(sparc_trap_instruction, tt);
|
||||
trap(SPARC_TRAP_INSTRUCTION, tt);
|
||||
m_icount -= 3;
|
||||
return false;
|
||||
}
|
||||
@ -1263,24 +1366,32 @@ bool mb86901_device::execute_ticc(UINT32 op)
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// queue_trap - flag an incoming trap of a given
|
||||
// trap - flag an incoming trap of a given
|
||||
// type
|
||||
//-------------------------------------------------
|
||||
|
||||
void mb86901_device::queue_trap(UINT8 type, UINT8 tt_override)
|
||||
void mb86901_device::trap(UINT8 type, UINT8 tt_override)
|
||||
{
|
||||
if (type == sparc_reset)
|
||||
if (type == SPARC_RESET)
|
||||
{
|
||||
m_queued_priority = m_trap_priorities[0];
|
||||
m_queued_tt = tt_override;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (type == sparc_trap_instruction)
|
||||
if (type == SPARC_TRAP_INSTRUCTION)
|
||||
{
|
||||
type = tt_override;
|
||||
}
|
||||
|
||||
if (type >= SPARC_INT1 && type <= SPARC_INT14)
|
||||
{
|
||||
if (!ET)
|
||||
return;
|
||||
int irl = (type - SPARC_INT1) + 1;
|
||||
if (irl <= PIL)
|
||||
return;
|
||||
}
|
||||
if (m_trap_priorities[type] < m_queued_priority)
|
||||
{
|
||||
m_queued_priority = m_trap_priorities[type];
|
||||
@ -1302,6 +1413,7 @@ bool mb86901_device::invoke_queued_traps()
|
||||
if (m_queued_priority > 0)
|
||||
{
|
||||
m_queued_priority = 0;
|
||||
m_queued_tt = 0;
|
||||
|
||||
m_et = false;
|
||||
m_ps = m_s;
|
||||
@ -1336,8 +1448,20 @@ void mb86901_device::execute_run()
|
||||
|
||||
while (m_icount > 0)
|
||||
{
|
||||
bool trap_was_queued = invoke_queued_traps();
|
||||
if (trap_was_queued)
|
||||
{
|
||||
m_icount -= 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
debugger_instruction_hook(this, m_pc);
|
||||
|
||||
if (HOLD_BUS)
|
||||
{
|
||||
m_icount--;
|
||||
continue;
|
||||
}
|
||||
UINT32 op = GET_OPCODE;
|
||||
|
||||
bool update_npc = true;
|
||||
@ -1390,7 +1514,7 @@ void mb86901_device::execute_run()
|
||||
REG(0) = 0;
|
||||
|
||||
bool trap_taken = invoke_queued_traps();
|
||||
if (!trap_taken && update_npc)
|
||||
if (!trap_taken && update_npc && !HOLD_BUS)
|
||||
{
|
||||
PC = nPC;
|
||||
nPC = PC + 4;
|
||||
|
@ -9,6 +9,34 @@
|
||||
#ifndef __SPARC_H__
|
||||
#define __SPARC_H__
|
||||
|
||||
#define SPARC_RESET 0
|
||||
#define SPARC_INSTRUCTION_ACCESS_EXCEPTION 1
|
||||
#define SPARC_ILLEGAL_INSTRUCTION 2
|
||||
#define SPARC_PRIVILEGED_INSTRUCTION 3
|
||||
#define SPARC_FLOATING_POINT_DISABLED 4
|
||||
#define SPARC_WINDOW_OVERFLOW 5
|
||||
#define SPARC_WINDOW_UNDERFLOW 6
|
||||
#define SPARC_MEM_ADDRESS_NOT_ALIGNED 7
|
||||
#define SPARC_FLOATING_POINT_EXCEPTION 8
|
||||
#define SPARC_DATA_ACCESS_EXCEPTION 9
|
||||
#define SPARC_TAG_OVERFLOW 10
|
||||
#define SPARC_INT1 17
|
||||
#define SPARC_INT2 18
|
||||
#define SPARC_INT3 19
|
||||
#define SPARC_INT4 20
|
||||
#define SPARC_INT5 21
|
||||
#define SPARC_INT6 22
|
||||
#define SPARC_INT7 23
|
||||
#define SPARC_INT8 24
|
||||
#define SPARC_INT9 25
|
||||
#define SPARC_INT10 26
|
||||
#define SPARC_INT11 27
|
||||
#define SPARC_INT12 28
|
||||
#define SPARC_INT13 29
|
||||
#define SPARC_INT14 30
|
||||
#define SPARC_INT15 31
|
||||
#define SPARC_TRAP_INSTRUCTION 128
|
||||
|
||||
class mb86901_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
@ -40,8 +68,12 @@ public:
|
||||
UINT8 get_asi() { return m_asi; }
|
||||
UINT32 pc() { return m_pc; }
|
||||
|
||||
void trap(UINT8 type, UINT8 tt_override = 0);
|
||||
void set_mae() { m_mae = true; }
|
||||
void hold_bus() { m_hold_bus = true; }
|
||||
void release_bus() { m_hold_bus = false; }
|
||||
|
||||
protected:
|
||||
void queue_trap(UINT8 type, UINT8 tt_override = 0);
|
||||
bool invoke_queued_traps();
|
||||
bool check_main_traps(UINT32 op, bool privileged, UINT32 alignment, UINT8 registeralign, bool noimmediate);
|
||||
|
||||
@ -103,6 +135,8 @@ protected:
|
||||
UINT8 m_trap_priorities[256];
|
||||
UINT8 m_queued_tt;
|
||||
UINT8 m_queued_priority;
|
||||
bool m_mae;
|
||||
bool m_hold_bus;
|
||||
int m_icount;
|
||||
|
||||
// debugger helpers
|
||||
|
@ -114,35 +114,9 @@
|
||||
|
||||
#define Y m_y
|
||||
|
||||
enum sparc_trap_type
|
||||
{
|
||||
sparc_reset = 0,
|
||||
sparc_instruction_access_exception = 1,
|
||||
sparc_illegal_instruction = 2,
|
||||
sparc_privileged_instruction = 3,
|
||||
sparc_floating_point_disabled = 4,
|
||||
sparc_window_overflow = 5,
|
||||
sparc_window_underflow = 6,
|
||||
sparc_mem_address_not_aligned = 7,
|
||||
sparc_floating_point_exception = 8,
|
||||
sparc_data_access_exception = 9,
|
||||
sparc_tag_overflow = 10,
|
||||
sparc_int1 = 17,
|
||||
sparc_int2 = 18,
|
||||
sparc_int3 = 19,
|
||||
sparc_int4 = 20,
|
||||
sparc_int5 = 21,
|
||||
sparc_int6 = 22,
|
||||
sparc_int7 = 23,
|
||||
sparc_int8 = 24,
|
||||
sparc_int9 = 25,
|
||||
sparc_int10 = 26,
|
||||
sparc_int11 = 27,
|
||||
sparc_int12 = 28,
|
||||
sparc_int13 = 29,
|
||||
sparc_int14 = 30,
|
||||
sparc_int15 = 31,
|
||||
sparc_trap_instruction = 128
|
||||
};
|
||||
#define ET m_et
|
||||
#define PIL m_pil
|
||||
|
||||
#define MAE m_mae
|
||||
#define HOLD_BUS m_hold_bus
|
||||
#endif // __MB86901_DEFS_H__
|
@ -447,7 +447,7 @@ void scc8530_t::set_reg_a(int reg, UINT8 data)
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
scc8530_set_reg_a
|
||||
scc8530_set_reg_b
|
||||
-------------------------------------------------*/
|
||||
|
||||
void scc8530_t::set_reg_b(int reg, UINT8 data)
|
||||
@ -457,46 +457,41 @@ void scc8530_t::set_reg_b(int reg, UINT8 data)
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
scc8530_r
|
||||
-------------------------------------------------*/
|
||||
//-------------------------------------------------
|
||||
// reg_r - read handler, trampolines into normal
|
||||
// getter
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER(scc8530_t::reg_r)
|
||||
{
|
||||
UINT8 result = 0;
|
||||
return read_reg(offset & 3);
|
||||
}
|
||||
|
||||
offset %= 4;
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// read_reg - reads either the control or data
|
||||
// port for either SCC channel.
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT8 scc8530_t::read_reg(int offset)
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case 0:
|
||||
/* Channel B (Printer Port) Control */
|
||||
case 0: /* Channel B (Printer Port) Control */
|
||||
case 1: /* Channel A (Modem Port) Control */
|
||||
|
||||
if (mode == 1)
|
||||
mode = 0;
|
||||
else
|
||||
reg = 0;
|
||||
|
||||
result = getbreg();
|
||||
result = (offset == 0) ? getbreg(); : getareg()
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* Channel A (Modem Port) Control */
|
||||
if (mode == 1)
|
||||
mode = 0;
|
||||
else
|
||||
reg = 0;
|
||||
|
||||
result = getareg();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Channel B (Printer Port) Data */
|
||||
result = channel[1].rxData;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Channel A (Modem Port) Data */
|
||||
result = channel[0].rxData;
|
||||
case 2: /* Channel B (Printer Port) Data */
|
||||
case 3:/* Channel A (Modem Port) Data */
|
||||
result = channel[offset == 2 ? 1 : 0].rxData;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
@ -504,22 +499,36 @@ READ8_MEMBER( scc8530_t::reg_r)
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
scc8530_w
|
||||
-------------------------------------------------*/
|
||||
//-------------------------------------------------
|
||||
// reg_w - write handler, trampolines into normal
|
||||
// setter
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE8_MEMBER( scc8530_t::reg_w )
|
||||
{
|
||||
Chan *pChan;
|
||||
write_reg(offset & 3, data);
|
||||
}
|
||||
|
||||
offset &= 3;
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_reg - writes either the control or data
|
||||
// port for either SCC channel.
|
||||
//-------------------------------------------------
|
||||
|
||||
void scc8530_t::write_reg(int offset, UINT8 data)
|
||||
{
|
||||
offset & 3;
|
||||
|
||||
// printf(" mode %d data %x offset %d \n", mode, data, offset);
|
||||
|
||||
Chan *pChan;
|
||||
switch(offset)
|
||||
{
|
||||
case 0:
|
||||
/* Channel B (Printer Port) Control */
|
||||
case 0: /* Channel B (Printer Port) Control */
|
||||
case 1: /* Channel A (Modem Port) Control */
|
||||
{
|
||||
int chan = ((offset == 2) ? 1 : 0);
|
||||
if (mode == 0)
|
||||
{
|
||||
if((data & 0xf0) == 0) // not a reset command
|
||||
@ -530,89 +539,44 @@ WRITE8_MEMBER( scc8530_t::reg_w )
|
||||
}
|
||||
else if (data == 0x10)
|
||||
{
|
||||
pChan = &channel[1];
|
||||
// clear ext. interrupts
|
||||
pChan->extIRQPending = 0;
|
||||
pChan->baudIRQPending = 0;
|
||||
channel[chan].extIRQPending = 0;
|
||||
channel[chan].baudIRQPending = 0;
|
||||
updateirqs();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = 0;
|
||||
putreg(1, data);
|
||||
putreg(chan, data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
/* Channel A (Modem Port) Control */
|
||||
if (mode == 0)
|
||||
case 2: /* Channel B (Printer Port) Data */
|
||||
case 3: /* Channel A (Modem Port) Data */
|
||||
{
|
||||
if((data & 0xf0) == 0) // not a reset command
|
||||
int chan = ((offset == 2) ? 1 : 0);
|
||||
if (channel[chan].txEnable)
|
||||
{
|
||||
mode = 1;
|
||||
reg = data & 0x0f;
|
||||
// putareg(data & 0xf0);
|
||||
}
|
||||
else if (data == 0x10)
|
||||
{
|
||||
pChan = &channel[0];
|
||||
// clear ext. interrupts
|
||||
pChan->extIRQPending = 0;
|
||||
pChan->baudIRQPending = 0;
|
||||
updateirqs();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = 0;
|
||||
putreg(0, data);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* Channel B (Printer Port) Data */
|
||||
pChan = &channel[1];
|
||||
|
||||
if (pChan->txEnable)
|
||||
{
|
||||
pChan->txData = data;
|
||||
channel[chan].txData = data;
|
||||
// local loopback?
|
||||
if (pChan->reg_val[14] & 0x10)
|
||||
if (channel[chan].reg_val[14] & 0x10)
|
||||
{
|
||||
pChan->rxData = data;
|
||||
pChan->reg_val[0] |= 0x01; // Rx character available
|
||||
channel[chan].rxData = data;
|
||||
channel[chan].reg_val[0] |= 0x01; // Rx character available
|
||||
}
|
||||
pChan->reg_val[1] |= 0x01; // All sent
|
||||
pChan->reg_val[0] |= 0x04; // Tx empty
|
||||
pChan->txUnderrun = 1;
|
||||
pChan->txIRQPending = 1;
|
||||
updateirqs();
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
/* Channel A (Modem Port) Data */
|
||||
pChan = &channel[0];
|
||||
|
||||
if (pChan->txEnable)
|
||||
{
|
||||
pChan->txData = data;
|
||||
// local loopback?
|
||||
if (pChan->reg_val[14] & 0x10)
|
||||
{
|
||||
pChan->rxData = data;
|
||||
pChan->reg_val[0] |= 0x01; // Rx character available
|
||||
}
|
||||
pChan->reg_val[1] |= 0x01; // All sent
|
||||
pChan->reg_val[0] |= 0x04; // Tx empty
|
||||
pChan->txUnderrun = 1;
|
||||
pChan->txIRQPending = 1;
|
||||
channel[chan].reg_val[1] |= 0x01; // All sent
|
||||
channel[chan].reg_val[0] |= 0x04; // Tx empty
|
||||
channel[chan].txUnderrun = 1;
|
||||
channel[chan].txIRQPending = 1;
|
||||
updateirqs();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
@ -43,6 +43,9 @@ public:
|
||||
DECLARE_READ8_MEMBER(reg_r);
|
||||
DECLARE_WRITE8_MEMBER(reg_w);
|
||||
|
||||
void write_reg(int offset, UINT8 data);
|
||||
UINT8 read_reg(int offset);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
@ -387,6 +387,8 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/sparc/sparc.h"
|
||||
#include "machine/z80scc.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
|
||||
#define ENA_NOTBOOT 0x80
|
||||
#define ENA_SDVMA 0x20
|
||||
@ -394,6 +396,22 @@
|
||||
#define ENA_RESET 0x04
|
||||
#define ENA_DIAG 0x01
|
||||
|
||||
#define SCC1_TAG "kbdmouse"
|
||||
#define SCC2_TAG "uart"
|
||||
#define RS232A_TAG "rs232a"
|
||||
#define RS232B_TAG "rs232b"
|
||||
|
||||
#define ASI_SYSTEM_SPACE 2
|
||||
#define ASI_SEGMENT_MAP 3
|
||||
#define ASI_PAGE_MAP 4
|
||||
#define ASI_USER_INSN 8
|
||||
#define ASI_SUPER_INSN 9
|
||||
#define ASI_USER_DATA 10
|
||||
#define ASI_SUPER_DATA 11
|
||||
#define ASI_FLUSH_SEGMENT 12
|
||||
#define ASI_FLUSH_PAGE 13
|
||||
#define ASI_FLUSH_CONTEXT 14
|
||||
|
||||
class sun4_state : public driver_device
|
||||
{
|
||||
public:
|
||||
@ -401,7 +419,10 @@ public:
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_rom(*this, "user1")
|
||||
, m_kbdmouse(*this, SCC1_TAG)
|
||||
, m_uart(*this, SCC2_TAG)
|
||||
, m_rom_ptr(nullptr)
|
||||
, m_context(0)
|
||||
, m_system_enable(0)
|
||||
{
|
||||
}
|
||||
@ -416,50 +437,179 @@ protected:
|
||||
|
||||
required_device<mb86901_device> m_maincpu;
|
||||
required_memory_region m_rom;
|
||||
required_device<z80scc_device> m_kbdmouse;
|
||||
required_device<z80scc_device> m_uart;
|
||||
|
||||
UINT32 read_supervisor_data(UINT32 vaddr, UINT32 mem_mask);
|
||||
void write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask);
|
||||
|
||||
UINT32 *m_rom_ptr;
|
||||
UINT32 m_context;
|
||||
UINT16 m_segmap[8][4096];
|
||||
UINT32 m_pagemap[8192];
|
||||
UINT32 m_system_enable;
|
||||
};
|
||||
|
||||
#define SEGMENT(vaddr) m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff]
|
||||
#define PAGE(vaddr) m_pagemap[((m_segmap[m_context & 7][((vaddr) >> 18) & 0xfff] & 0x7f) << 6) | (((vaddr) >> 12) & 0x3f)]
|
||||
#define PADDR(vaddr) (((PAGE(vaddr) << 12) & 0x0ffff000) | ((vaddr) & 0xfff))
|
||||
|
||||
UINT32 sun4_state::read_supervisor_data(UINT32 vaddr, UINT32 mem_mask)
|
||||
{
|
||||
UINT32 page = PAGE(vaddr);
|
||||
bool v = (page & 0x80000000) ? true : false;
|
||||
bool w = (page & 0x40000000) ? true : false;
|
||||
bool s = (page & 0x20000000) ? true : false;
|
||||
bool x = (page & 0x10000000) ? true : false;
|
||||
int t = (page & 0x0c000000) >> 26;
|
||||
bool a = (page & 0x02000000) ? true : false;
|
||||
bool m = (page & 0x01000000) ? true : false;
|
||||
char mode[4] = { 'M', 'S', '0', '1' };
|
||||
|
||||
logerror("supervisor data read: vaddr %08x, paddr %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), m_context, SEGMENT(vaddr), PAGE(vaddr)
|
||||
, v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm');
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sun4_state::write_supervisor_data(UINT32 vaddr, UINT32 data, UINT32 mem_mask)
|
||||
{
|
||||
UINT32 page = PAGE(vaddr);
|
||||
bool v = (page & 0x80000000) ? true : false;
|
||||
bool w = (page & 0x40000000) ? true : false;
|
||||
bool s = (page & 0x20000000) ? true : false;
|
||||
bool x = (page & 0x10000000) ? true : false;
|
||||
int t = (page & 0x0c000000) >> 26;
|
||||
bool a = (page & 0x02000000) ? true : false;
|
||||
bool m = (page & 0x01000000) ? true : false;
|
||||
char mode[4] = { 'M', 'S', '0', '1' };
|
||||
|
||||
logerror("supervisor data write: vaddr %08x, paddr %08x, data %08x, mem_mask %08x, context %d, segment entry %02x, page entry %08x, %c%c%c%c%c%c%c\n", vaddr, PADDR(vaddr), data, mem_mask,
|
||||
m_context, SEGMENT(vaddr), PAGE(vaddr), v ? 'V' : 'v', w ? 'W' : 'w', s ? 'S' : 's', x ? 'X' : 'x', mode[t], a ? 'A' : 'a', m ? 'M' : 'm');
|
||||
}
|
||||
|
||||
READ32_MEMBER( sun4_state::sun4_mmu_r )
|
||||
{
|
||||
UINT8 asi = m_maincpu->get_asi();
|
||||
|
||||
if (asi == 2 && !space.debugger_access())
|
||||
if (!space.debugger_access())
|
||||
{
|
||||
switch(asi)
|
||||
{
|
||||
case ASI_SYSTEM_SPACE:
|
||||
switch (offset >> 26)
|
||||
{
|
||||
case 3: // context reg
|
||||
return m_context;
|
||||
logerror("sun4: read context register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_context << 24, mem_mask, offset << 2, m_maincpu->pc());
|
||||
return m_context << 24;
|
||||
|
||||
case 4: // system enable reg
|
||||
return m_system_enable;
|
||||
|
||||
case 6: // bus error register
|
||||
return 0;
|
||||
logerror("sun4: read system enable register %08x (& %08x) asi 2, offset %x, PC = %x\n", m_system_enable << 24, mem_mask, offset << 2, m_maincpu->pc());
|
||||
return m_system_enable << 24;
|
||||
|
||||
case 8: // (d-)cache tags
|
||||
logerror("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc());
|
||||
logerror("sun4: read dcache tags %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc());
|
||||
return 0xffffffff;
|
||||
|
||||
case 9: // (d-)cache data
|
||||
logerror("sun4: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc());
|
||||
logerror("sun4: read dcache data %08x (& %08x) asi 2, offset %x, PC = %x\n", 0xffffffff, mem_mask, offset << 2, m_maincpu->pc());
|
||||
return 0xffffffff;
|
||||
|
||||
case 15: // Type 1 space passthrough
|
||||
switch ((offset >> 22) & 15)
|
||||
{
|
||||
case 0: // keyboard/mouse
|
||||
switch (offset & 1)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
if (mem_mask & 0xffff0000)
|
||||
ret |= m_kbdmouse->cb_r(space, 0) << 24;
|
||||
if (mem_mask & 0x0000ffff)
|
||||
ret |= m_kbdmouse->db_r(space, 0) << 8;
|
||||
return ret;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
if (mem_mask & 0xffff0000)
|
||||
ret |= m_kbdmouse->ca_r(space, 0) << 24;
|
||||
if (mem_mask & 0x0000ffff)
|
||||
ret |= m_kbdmouse->da_r(space, 0) << 8;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: // serial ports
|
||||
switch (offset & 1)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
if (mem_mask & 0xffff0000)
|
||||
ret |= m_uart->cb_r(space, 0) << 24;
|
||||
if (mem_mask & 0x0000ffff)
|
||||
ret |= m_uart->db_r(space, 0) << 8;
|
||||
return ret;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
if (mem_mask & 0xffff0000)
|
||||
ret |= m_uart->ca_r(space, 0) << 24;
|
||||
if (mem_mask & 0x0000ffff)
|
||||
ret |= m_uart->da_r(space, 0) << 8;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("sun4: read unknown type 1 space at address %x (& %08x) asi 2, offset %x, PC = %x\n", offset << 2, mem_mask, offset << 2, m_maincpu->pc());
|
||||
}
|
||||
break;
|
||||
|
||||
case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur.
|
||||
default:
|
||||
logerror("sun4: read unknown register (& %08x) asi 2, offset %x, PC = %x\n", mem_mask, offset << 2, m_maincpu->pc());
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ASI_SEGMENT_MAP:
|
||||
{
|
||||
logerror("sun4: read m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 24 & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), mem_mask);
|
||||
UINT32 result = SEGMENT(offset << 2);
|
||||
while (!(mem_mask & 1))
|
||||
{
|
||||
mem_mask >>= 1;
|
||||
result <<= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
case ASI_PAGE_MAP: // page map
|
||||
{
|
||||
logerror("sun4: read m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, PAGE(offset << 2), mem_mask);
|
||||
return PAGE(offset << 2);
|
||||
}
|
||||
|
||||
case ASI_SUPER_INSN: // supervisor instruction space
|
||||
return m_rom_ptr[offset & 0x1ffff]; // wrong, but works for now
|
||||
|
||||
case ASI_SUPER_DATA:
|
||||
return read_supervisor_data(offset << 2, mem_mask);
|
||||
|
||||
default:
|
||||
logerror("sun4: read (& %08x) asi %d byte offset %x, PC = %x\n", mem_mask, asi, offset << 2, m_maincpu->pc());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(m_system_enable & ENA_NOTBOOT))
|
||||
{
|
||||
return m_rom_ptr[offset & 0x1ffff];
|
||||
}
|
||||
else if (asi < 8 || asi > 11)
|
||||
{
|
||||
logerror("sun4: read asi %d byte offset %x, PC = %x\n", asi, offset << 2, m_maincpu->pc());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -468,34 +618,107 @@ WRITE32_MEMBER( sun4_state::sun4_mmu_w )
|
||||
{
|
||||
UINT8 asi = m_maincpu->get_asi();
|
||||
|
||||
if (asi == 2)
|
||||
switch (asi)
|
||||
{
|
||||
case 2:
|
||||
switch (offset >> 26)
|
||||
{
|
||||
case 3: // context reg
|
||||
m_context = (UINT8)data;
|
||||
logerror("sun4: %08x (& %08x) asi 2 to context register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
|
||||
m_context = (UINT8)(data >> 24) & 7;
|
||||
return;
|
||||
|
||||
case 4: // system enable reg
|
||||
logerror("sun4: write %08x (& %08x) asi 2 to system enable register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
|
||||
m_system_enable = (UINT8)data;
|
||||
return;
|
||||
|
||||
case 8: // cache tags
|
||||
logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc());
|
||||
logerror("sun4: write %08x (& %08x) asi 2 to cache tags @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
|
||||
return;
|
||||
|
||||
case 9: // cache data
|
||||
logerror("sun4: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc());
|
||||
logerror("sun4: write %08x (& %08x) asi 2 to cache data @ %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
|
||||
return;
|
||||
|
||||
case 15: // Type 1 space passthrough
|
||||
switch ((offset >> 22) & 15)
|
||||
{
|
||||
case 0: // keyboard/mouse
|
||||
switch (offset & 1)
|
||||
{
|
||||
case 0:
|
||||
if (mem_mask & 0xffff0000)
|
||||
m_kbdmouse->cb_w(space, 0, data >> 24);
|
||||
if (mem_mask & 0x0000ffff)
|
||||
m_kbdmouse->db_w(space, 0, data >> 24);
|
||||
break;
|
||||
case 1:
|
||||
if (mem_mask & 0xffff0000)
|
||||
m_kbdmouse->ca_w(space, 0, data >> 24);
|
||||
if (mem_mask & 0x0000ffff)
|
||||
m_kbdmouse->da_w(space, 0, data >> 24);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: // serial ports
|
||||
switch (offset & 1)
|
||||
{
|
||||
case 0:
|
||||
if (mem_mask & 0xffff0000)
|
||||
m_uart->cb_w(space, 0, data >> 24);
|
||||
if (mem_mask & 0x0000ffff)
|
||||
m_uart->db_w(space, 0, data >> 24);
|
||||
break;
|
||||
case 1:
|
||||
if (mem_mask & 0xffff0000)
|
||||
m_uart->ca_w(space, 0, data >> 24);
|
||||
if (mem_mask & 0x0000ffff)
|
||||
m_uart->da_w(space, 0, data >> 24);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
logerror("sun4: write unknown type 1 space %08x (& %08x) asi 2, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
|
||||
}
|
||||
break;
|
||||
|
||||
case 0: // IDPROM
|
||||
default:
|
||||
logerror("sun4: write %08x (& %08x) asi 2 to unknown register, offset %x, PC = %x\n", data, mem_mask, offset << 2, m_maincpu->pc());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (asi < 8 || asi > 11)
|
||||
break;
|
||||
|
||||
case 3: // segment map
|
||||
offset <<= 2;
|
||||
while (!(mem_mask & 1))
|
||||
{
|
||||
logerror("sun4: %08x to asi %d byte offset %x, PC = %x\n", data, asi, offset << 2, m_maincpu->pc());
|
||||
mem_mask >>= 1;
|
||||
data >>= 1;
|
||||
}
|
||||
SEGMENT(offset) = data;
|
||||
//m_segmap[m_context & 7][(offset >> 18) & 0xfff] &= ~(mem_mask >> 16);
|
||||
//m_segmap[m_context & 7][(offset >> 18) & 0xfff] |= (data >> 16) & (mem_mask >> 16);
|
||||
logerror("sun4: write m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x & %08x\n", m_context & 7, offset << 2, (offset >> 16) & 0xfff, data, mem_mask);
|
||||
break;
|
||||
|
||||
case ASI_PAGE_MAP: // page map
|
||||
{
|
||||
logerror("sun4: write m_pagemap[(m_segmap[%d][(%08x >> 18) & 0xfff = %03x] = %08x << 6) | ((%08x >> 12) & 0x3f)]] = %08x & %08x\n", m_context & 7, offset << 2,
|
||||
(offset >> 16) & 0xfff, SEGMENT(offset << 2), offset << 2, data, mem_mask);
|
||||
COMBINE_DATA(&PAGE(offset << 2));
|
||||
PAGE(offset << 2) &= 0xff00ffff;
|
||||
break;
|
||||
}
|
||||
|
||||
case ASI_SUPER_DATA:
|
||||
write_supervisor_data(offset << 2, data, mem_mask);
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("sun4: write %08x (& %08x) to asi %d byte offset %x, PC = %x\n", data, mem_mask, asi, offset << 2, m_maincpu->pc());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -521,6 +744,21 @@ static MACHINE_CONFIG_START( sun4, sun4_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", MB86901, 16670000)
|
||||
MCFG_DEVICE_ADDRESS_MAP(AS_PROGRAM, sun4_mem)
|
||||
|
||||
MCFG_SCC8530_ADD(SCC1_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
|
||||
MCFG_SCC8530_ADD(SCC2_TAG, XTAL_4_9152MHz, 0, 0, 0, 0)
|
||||
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd))
|
||||
MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_txd))
|
||||
|
||||
MCFG_RS232_PORT_ADD(RS232A_TAG, default_rs232_devices, nullptr)
|
||||
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, rxa_w))
|
||||
MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcda_w))
|
||||
MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsa_w))
|
||||
|
||||
MCFG_RS232_PORT_ADD(RS232B_TAG, default_rs232_devices, nullptr)
|
||||
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, rxb_w))
|
||||
MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, dcdb_w))
|
||||
MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC2_TAG, z80scc_device, ctsb_w))
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user