mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
f2mc16: More opcodes and more robust IRQ handling [R. Belmont]
mb9061x: Implemented timers 0 and 1, including external event counter mode [R. Belmont]
This commit is contained in:
parent
8b78bdff01
commit
61c288efdb
@ -225,6 +225,8 @@ void f2mc16_device::execute_run()
|
||||
}
|
||||
}
|
||||
|
||||
//m_icount--;
|
||||
|
||||
u8 opcode = read_8((m_pcb<<16) | m_pc);
|
||||
|
||||
debugger_instruction_hook((m_pcb<<16) | m_pc);
|
||||
@ -319,8 +321,14 @@ void f2mc16_device::execute_run()
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// NEGW A
|
||||
case 0x0b:
|
||||
// stream << "NEGW A";
|
||||
m_tmp32 = doSUB_32(0, m_acc&0xffff);
|
||||
m_acc &= 0xffff0000;
|
||||
m_acc |= m_tmp32 & 0xffff;
|
||||
setNZ_16(m_acc & 0xffff);
|
||||
m_pc++;
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// LSLW A
|
||||
@ -516,8 +524,11 @@ void f2mc16_device::execute_run()
|
||||
// stream << "ADDC A";
|
||||
break;
|
||||
|
||||
// CMP A
|
||||
case 0x23:
|
||||
// stream << "CMP A";
|
||||
doCMP_16(m_acc>>16, m_acc&0xffff);
|
||||
m_pc++;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
// AND CCR, #imm8
|
||||
@ -633,12 +644,24 @@ void f2mc16_device::execute_run()
|
||||
m_pc++;
|
||||
break;
|
||||
|
||||
// ADD A, #imm8
|
||||
case 0x30:
|
||||
// util::stream_format(stream, "ADD A, #$%02x", operand);
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
|
||||
m_tmp8 = doADD_8(m_acc & 0xff, m_tmp8);
|
||||
m_acc &= ~0xff;
|
||||
m_acc |= m_tmp8;
|
||||
m_pc += 2;
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// SUB A, #imm8
|
||||
case 0x31:
|
||||
// util::stream_format(stream, "SUB A, #$%02x", operand);
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
|
||||
m_tmp8 = doSUB_8(m_acc & 0xff, m_tmp8);
|
||||
m_acc &= ~0xff;
|
||||
m_acc |= m_tmp8;
|
||||
m_pc += 2;
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
case 0x32:
|
||||
@ -700,8 +723,14 @@ void f2mc16_device::execute_run()
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// SUBW A, #imm16
|
||||
case 0x39:
|
||||
// util::stream_format(stream, "SUBW A, #$%04x", opcodes.r16(pc+1));
|
||||
m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
|
||||
m_tmp16 = doSUB_16(m_acc & 0xffff, m_tmp16);
|
||||
m_acc &= 0xffff0000;
|
||||
m_acc |= m_tmp16;
|
||||
m_pc += 3;
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// CWBNE A, #imm16, disp8
|
||||
@ -750,6 +779,16 @@ void f2mc16_device::execute_run()
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// XORW A, #imm16
|
||||
case 0x3e:
|
||||
m_tmp16 = read_16((m_pcb<<16) | (m_pc+1));
|
||||
m_acc ^= m_tmp16;
|
||||
setNZ_16(m_acc & 0xffff);
|
||||
m_ps &= ~F_V;
|
||||
m_pc += 3;
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// NOTW A
|
||||
case 0x3f:
|
||||
m_acc ^= 0xffff;
|
||||
@ -1002,7 +1041,7 @@ void f2mc16_device::execute_run()
|
||||
// POPW register list
|
||||
case 0x5f:
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+1));
|
||||
for (int i = 7; i <= 0; i--)
|
||||
for (int i = 7; i >= 0; i--)
|
||||
{
|
||||
if (m_tmp8 & (1<<i))
|
||||
{
|
||||
@ -1064,41 +1103,48 @@ void f2mc16_device::execute_run()
|
||||
|
||||
// RETI
|
||||
case 0x6b:
|
||||
// there's an IRQ chaining facility, let's do it
|
||||
if (m_outstanding_irqs)
|
||||
{
|
||||
int cpulevel = m_ps >> 13;
|
||||
bool bFoundVec = false;
|
||||
|
||||
for (int irq = 0; irq < 256; irq++)
|
||||
// there's an IRQ chaining facility, let's do it
|
||||
if (m_outstanding_irqs)
|
||||
{
|
||||
if (m_vector_level[irq] < cpulevel)
|
||||
int cpulevel = peek_stack_16() >> 13;
|
||||
for (int irq = 0; irq < 256; irq++)
|
||||
{
|
||||
m_ps = read_16((m_ssb << 16) | m_ssp);
|
||||
m_ps |= F_S;
|
||||
m_ps &= ~0x7000;
|
||||
m_ps |= (m_vector_level[irq] & 7) << 13;
|
||||
if (m_vector_level[irq] < cpulevel)
|
||||
{
|
||||
m_ps = read_16((m_ssb << 16) | m_ssp);
|
||||
m_ps |= F_S;
|
||||
m_ps &= ~0x7000;
|
||||
m_ps |= (m_vector_level[irq] & 7) << 13;
|
||||
|
||||
u32 uVecAddr = 0xfffffc - (irq * 4);
|
||||
m_pc = read_16(uVecAddr);
|
||||
m_pcb = read_8(uVecAddr + 2);
|
||||
break;
|
||||
u32 uVecAddr = 0xfffffc - (irq * 4);
|
||||
m_pc = read_16(uVecAddr);
|
||||
m_pcb = read_8(uVecAddr + 2);
|
||||
bFoundVec = true;
|
||||
printf("RETI vector chain to %02x%04x\n", m_pcb, m_pc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ps = pull_16_ssp();
|
||||
m_pc = pull_16_ssp();
|
||||
m_tmp16 = pull_16_ssp();
|
||||
m_pcb = m_tmp16 & 0xff;
|
||||
m_dtb = m_tmp16 >> 8;
|
||||
m_tmp16 = pull_16_ssp();
|
||||
m_adb = m_tmp16 & 0xff;
|
||||
m_dpr = m_tmp16 >> 8;
|
||||
m_acc = 0;
|
||||
m_acc = pull_16_ssp();
|
||||
m_acc |= (pull_16_ssp() << 16);
|
||||
m_icount -= 17;
|
||||
|
||||
// if no new IRQ was found or could be dispatched by the level
|
||||
if (!bFoundVec)
|
||||
{
|
||||
m_ps = pull_16_ssp();
|
||||
m_pc = pull_16_ssp();
|
||||
m_tmp16 = pull_16_ssp();
|
||||
m_pcb = m_tmp16 & 0xff;
|
||||
m_dtb = m_tmp16 >> 8;
|
||||
m_tmp16 = pull_16_ssp();
|
||||
m_adb = m_tmp16 & 0xff;
|
||||
m_dpr = m_tmp16 >> 8;
|
||||
m_acc = 0;
|
||||
m_acc = pull_16_ssp();
|
||||
m_acc |= (pull_16_ssp() << 16);
|
||||
m_icount -= 17;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1566,6 +1612,23 @@ void f2mc16_device::opcodes_bo6c(u8 operand)
|
||||
m_icount -= 7;
|
||||
break;
|
||||
|
||||
// BBC dir8, bit, disp8
|
||||
case 0x88: case 0x89: case 0x8a: case 0x8b: case 0x8c: case 0x8d: case 0x8e: case 0x8f:
|
||||
m_tmp32 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
m_tmp32 |= (m_dpr<<8) | (m_dtb<<8);
|
||||
m_tmp8 = read_8(m_tmp32);
|
||||
m_tmp8 = read_8((m_pcb << 16) | (m_pc + 4));
|
||||
m_ps &= ~F_Z;
|
||||
m_pc += 4;
|
||||
if (!(read_8(m_tmp32) & (1 << (operand & 7))))
|
||||
{
|
||||
m_ps |= F_Z;
|
||||
m_pc += (s8)m_tmp8;
|
||||
m_icount--;
|
||||
}
|
||||
m_icount -= 7;
|
||||
break;
|
||||
|
||||
// BBC adr16, bit, disp8
|
||||
case 0x98: case 0x99: case 0x9a: case 0x9b: case 0x9c: case 0x9d: case 0x9e: case 0x9f:
|
||||
m_tmp16 = read_16((m_pcb << 16) | (m_pc + 2));
|
||||
@ -1823,6 +1886,29 @@ void f2mc16_device::opcodes_2b6f(u8 operand)
|
||||
m_icount -= 1;
|
||||
break;
|
||||
|
||||
// LSLL A, R0
|
||||
case 0x1c:
|
||||
m_tmp8 = read_rX(0);
|
||||
m_icount -= 6; // 6 cycles base
|
||||
if (m_tmp8 == 0)
|
||||
{
|
||||
m_ps &= ~F_C;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_icount -= 6;
|
||||
for (u8 count = 0; count < m_tmp8; count++)
|
||||
{
|
||||
m_ps &= ~F_C;
|
||||
m_ps |= (m_acc & 0x80000000) ? F_C : 0;
|
||||
m_acc <<= 1;
|
||||
m_icount --; // 1 additional cycle per iteration
|
||||
}
|
||||
setNZ_32(m_acc);
|
||||
}
|
||||
m_pc += 2;
|
||||
break;
|
||||
|
||||
// MOV @RLx + #disp8, A
|
||||
case 0x30: case 0x32: case 0x34: case 0x36:
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
@ -1932,7 +2018,7 @@ void f2mc16_device::opcodes_ea70(u8 operand)
|
||||
m_acc &= m_tmp32;
|
||||
setNZ_32(m_acc);
|
||||
m_ps &= ~F_V;
|
||||
m_pc += 3;
|
||||
m_pc += 2;
|
||||
m_icount -= 7;
|
||||
break;
|
||||
|
||||
@ -1970,6 +2056,21 @@ void f2mc16_device::opcodes_ea71(u8 operand)
|
||||
m_icount -= 11;
|
||||
break;
|
||||
|
||||
// INCL RLx
|
||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
m_tmp64 = read_rlX((operand>>1) & 3);
|
||||
m_tmp64++;
|
||||
write_rlX((operand>>1) & 3, m_tmp64&0xffffffff);
|
||||
setNZ_32(m_tmp64 & 0xffffffff);
|
||||
m_ps &= ~F_V;
|
||||
if (m_tmp64 & 0x100000000)
|
||||
{
|
||||
m_ps |= F_V;
|
||||
}
|
||||
m_pc += 2;
|
||||
m_icount -= 7;
|
||||
break;
|
||||
|
||||
// INCL @RWx + disp8
|
||||
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
@ -2070,6 +2171,17 @@ void f2mc16_device::opcodes_ea71(u8 operand)
|
||||
m_icount -= 2;
|
||||
break;
|
||||
|
||||
// MOVEA A, @RWx + disp8
|
||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
||||
m_acc <<= 16;
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
m_tmp16 = read_rwX(operand & 7);
|
||||
m_tmp16 += (s8)m_tmp8;
|
||||
m_acc |= m_tmp16;
|
||||
m_pc += 3;
|
||||
m_icount -= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unknown F2MC EA71 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
|
||||
break;
|
||||
@ -2145,6 +2257,31 @@ void f2mc16_device::opcodes_ea73(u8 operand)
|
||||
m_icount -= 5;
|
||||
break;
|
||||
|
||||
// INCW addr16
|
||||
case 0x5f:
|
||||
m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
|
||||
if (m_prefix_valid)
|
||||
{
|
||||
m_prefix_valid = false;
|
||||
m_tmp32 |= (m_prefix << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tmp32 |= (m_dtb << 16);
|
||||
}
|
||||
m_tmp32aux = read_16(m_tmp32);
|
||||
m_tmp32aux++;
|
||||
write_16(m_tmp32, m_tmp32aux & 0xffff);
|
||||
setNZ_16(m_tmp32aux & 0xffff);
|
||||
m_ps &= ~F_V;
|
||||
if (m_tmp32aux & 0x10000)
|
||||
{
|
||||
m_ps |= F_V;
|
||||
}
|
||||
m_pc += 4;
|
||||
m_icount -= 5;
|
||||
break;
|
||||
|
||||
// DECW addr16
|
||||
case 0x7f:
|
||||
m_tmp32 = read_16((m_pcb<<16) | (m_pc+2));
|
||||
@ -2171,6 +2308,16 @@ void f2mc16_device::opcodes_ea73(u8 operand)
|
||||
m_icount -= 5;
|
||||
break;
|
||||
|
||||
// MOVW @RWx + disp8, #imm16
|
||||
case 0xd0: case 0xd1: case 0xd2: case 0xd3: case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
||||
m_tmp8 = read_16((m_pcb<<16) | (m_pc+2));
|
||||
m_tmp16 = read_16((m_pcb<<16) | (m_pc+3));
|
||||
m_tmpea = read_rwX(operand & 7) + (s8)m_tmp8;
|
||||
write_16(getRWbank(operand & 7, m_tmpea), m_tmp16);
|
||||
m_pc += 5;
|
||||
m_icount -= 4;
|
||||
break;
|
||||
|
||||
// MOVW @RWx + disp16, #imm16
|
||||
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
||||
m_tmp16 = read_16((m_pcb<<16) | (m_pc+2));
|
||||
@ -2218,6 +2365,31 @@ void f2mc16_device::opcodes_ea74(u8 operand)
|
||||
m_icount -= 10;
|
||||
break;
|
||||
|
||||
// DBNZ Rx, disp8
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
m_tmp16 = read_rX(operand & 7);
|
||||
m_tmp16aux = m_tmp16;
|
||||
m_tmp16--;
|
||||
write_rX(operand & 7, m_tmp16 & 0xff);
|
||||
setNZ_8(m_tmp16 & 0xff);
|
||||
m_ps &= ~F_V;
|
||||
if ((m_tmp16aux ^ 0x01) & (m_tmp16aux ^ m_tmp16) & 0x80)
|
||||
{
|
||||
m_ps |= F_V;
|
||||
}
|
||||
if (m_tmp16 & 0xff)
|
||||
{
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
m_pc = (m_pc + 3) + (s8)m_tmp8;
|
||||
m_icount -= 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pc += 3;
|
||||
m_icount -= 6;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unknown F2MC EA74 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
|
||||
break;
|
||||
@ -2247,6 +2419,18 @@ void f2mc16_device::opcodes_ea76(u8 operand)
|
||||
m_icount -= 3;
|
||||
break;
|
||||
|
||||
// ADDW A, @RWx + disp8
|
||||
case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
|
||||
m_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
|
||||
m_tmp16aux = doADD_16(m_acc & 0xffff, m_tmp16);
|
||||
m_acc &= 0xffff0000;
|
||||
m_acc |= m_tmp16aux;
|
||||
m_pc += 3;
|
||||
m_icount -= 3;
|
||||
break;
|
||||
|
||||
// SUBW A, RWx
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
m_tmp16 = doSUB_16(m_acc & 0xffff, read_rwX(operand & 7));
|
||||
@ -2256,6 +2440,18 @@ void f2mc16_device::opcodes_ea76(u8 operand)
|
||||
m_icount -= 3;
|
||||
break;
|
||||
|
||||
// SUBW A, @RWx + disp8
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
|
||||
m_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
|
||||
m_tmp16aux = doSUB_16(m_acc & 0xffff, m_tmp16);
|
||||
m_acc &= 0xffff0000;
|
||||
m_acc |= m_tmp16aux;
|
||||
m_pc += 3;
|
||||
m_icount -= 3;
|
||||
break;
|
||||
|
||||
// CMPW A, RWx
|
||||
case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
|
||||
doCMP_16(m_acc & 0xffff, read_rwX(operand & 7));
|
||||
@ -2283,6 +2479,18 @@ void f2mc16_device::opcodes_ea76(u8 operand)
|
||||
m_icount -= 4;
|
||||
break;
|
||||
|
||||
// ORW A, @RWx + disp8
|
||||
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
m_tmp16 = read_rwX(operand & 7) + (s8)m_tmp8;
|
||||
m_tmp16 = read_16(getRWbank(operand & 7, m_tmp16));
|
||||
m_acc |= m_tmp16;
|
||||
setNZ_16(m_acc & 0xffff);
|
||||
m_ps &= ~F_V;
|
||||
m_pc += 3;
|
||||
m_icount -= 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unknown F2MC EA76 opcode %02x (PC=%x)\n", operand, (m_pcb<<16) | m_pc);
|
||||
break;
|
||||
@ -2303,6 +2511,22 @@ void f2mc16_device::opcodes_ea78(u8 operand)
|
||||
{
|
||||
switch (operand)
|
||||
{
|
||||
// MULUW A, RWx
|
||||
case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
|
||||
m_tmp16 = read_rwX(operand & 7);
|
||||
if (m_tmp16 == 0)
|
||||
{
|
||||
m_icount -= 4;
|
||||
m_acc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_icount -= 12;
|
||||
m_acc = m_tmp16 * (m_acc & 0xffff);
|
||||
}
|
||||
m_pc += 2;
|
||||
break;
|
||||
|
||||
// MULUW A, @RWx + disp8
|
||||
case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
|
||||
m_tmp8 = read_8((m_pcb<<16) | (m_pc+2));
|
||||
@ -2311,7 +2535,7 @@ void f2mc16_device::opcodes_ea78(u8 operand)
|
||||
if (m_tmp16 == 0)
|
||||
{
|
||||
m_icount -= 4;
|
||||
m_acc <<= 16;
|
||||
m_acc = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2333,22 +2557,28 @@ void f2mc16_device::execute_set_input(int inputnum, int state)
|
||||
|
||||
void f2mc16_device::set_irq(int vector, int level)
|
||||
{
|
||||
m_outstanding_irqs++;
|
||||
m_vector_level[vector] = level;
|
||||
//printf("set_irq: vec %d level %d\n", vector, level);
|
||||
if (m_vector_level[vector] != level)
|
||||
{
|
||||
m_outstanding_irqs++;
|
||||
m_vector_level[vector] = level;
|
||||
// printf("set_irq: vec %d, level %d, %d outstanding\n", vector, level, m_outstanding_irqs);
|
||||
}
|
||||
}
|
||||
|
||||
void f2mc16_device::clear_irq(int vector)
|
||||
{
|
||||
m_outstanding_irqs--;
|
||||
m_vector_level[vector] = 7;
|
||||
//printf("clear_irq: vec %d\n", vector);
|
||||
if (m_vector_level[vector] < 7)
|
||||
{
|
||||
m_outstanding_irqs--;
|
||||
m_vector_level[vector] = 7;
|
||||
//printf("clear_irq: vec %d, %d outstanding\n", vector, m_outstanding_irqs);
|
||||
}
|
||||
}
|
||||
|
||||
// note: this function must not use m_tmp16 unless you change RETI
|
||||
void f2mc16_device::take_irq(int vector, int level)
|
||||
{
|
||||
//printf("take_irq: vector %d, level %d, old PC = %02x%04x\n", vector, level, m_pcb, m_pc);
|
||||
// printf("take_irq: vector %d, level %d, old PC = %02x%04x\n", vector, level, m_pcb, m_pc);
|
||||
push_16_ssp(m_acc>>16);
|
||||
push_16_ssp(m_acc & 0xffff);
|
||||
push_16_ssp((m_dpr<<8) | m_adb);
|
||||
@ -2357,11 +2587,11 @@ void f2mc16_device::take_irq(int vector, int level)
|
||||
push_16_ssp(m_ps);
|
||||
|
||||
m_ps |= F_S;
|
||||
m_ps &= ~0x7000;
|
||||
m_ps &= ~0xe000;
|
||||
m_ps |= (level & 7) << 13;
|
||||
|
||||
u32 uVecAddr = 0xfffffc - (vector * 4);
|
||||
m_pc = read_16(uVecAddr);
|
||||
m_pcb = read_8(uVecAddr + 2);
|
||||
//printf("New PC = %02x%04x\n", m_pcb, m_pc);
|
||||
//printf("New PC = %02x%04x, new level=%d\n", m_pcb, m_pc, m_ps>>13);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ private:
|
||||
|
||||
u16 m_pc, m_usp, m_ssp, m_ps, m_tmp16, m_tmpea, m_tmp16aux;
|
||||
u8 m_pcb, m_dtb, m_usb, m_ssb, m_adb, m_dpr, m_tmp8, m_prefix;
|
||||
u32 m_acc, m_temp, m_tmp32;
|
||||
u32 m_acc, m_temp, m_tmp32, m_tmp32aux;
|
||||
s32 m_icount;
|
||||
u64 m_tmp64;
|
||||
bool m_prefix_valid;
|
||||
@ -279,6 +279,21 @@ private:
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline u16 peek_stack_16()
|
||||
{
|
||||
u16 rv = 0;
|
||||
if (m_ps & F_S)
|
||||
{
|
||||
rv = read_16((m_ssb << 16) | m_ssp);
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = read_16((m_usb << 16) | m_usp);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
inline u16 pull_16_ssp()
|
||||
{
|
||||
u16 rv = read_16((m_ssb << 16) | m_ssp);
|
||||
@ -395,6 +410,22 @@ private:
|
||||
|
||||
return m_tmp64 & 0xffffffff;
|
||||
}
|
||||
inline u8 doADD_8(u8 lhs, u8 rhs)
|
||||
{
|
||||
m_tmp16 = lhs + rhs;
|
||||
m_ps &= ~(F_C|F_V);
|
||||
if ((m_tmp16 ^ lhs) & (m_tmp16 ^ rhs) & 0x80)
|
||||
{
|
||||
m_ps |= F_V;
|
||||
}
|
||||
if (m_tmp16 > 0xff)
|
||||
{
|
||||
m_ps |= F_C;
|
||||
}
|
||||
setNZ_8(m_tmp16 & 0xff);
|
||||
|
||||
return m_tmp16 & 0xff;
|
||||
}
|
||||
inline u16 doADD_16(u16 lhs, u16 rhs)
|
||||
{
|
||||
m_tmp32 = lhs + rhs;
|
||||
|
@ -396,6 +396,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
bytes = 3;
|
||||
break;
|
||||
|
||||
case 0x3e:
|
||||
util::stream_format(stream, "XORW A, #$%04x", opcodes.r16(pc+1));
|
||||
bytes = 3;
|
||||
break;
|
||||
|
||||
case 0x3f:
|
||||
stream << "NOTW A";
|
||||
break;
|
||||
@ -778,6 +783,20 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
switch (operand & 0xf)
|
||||
{
|
||||
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
|
||||
util::stream_format(stream, "ANDL A, RL%d", (operand & 0x6)>>1);
|
||||
bytes = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "UNK ea-type 70 8x";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "UNK ea-type 70";
|
||||
break;
|
||||
@ -792,6 +811,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
bytes = ea_form1_helper_noA(stream, "CALLP @", pc, operand, opcodes.r16(pc+2));
|
||||
break;
|
||||
|
||||
case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
|
||||
util::stream_format(stream, "INCL RL%d", ((operand>>1) & 0x3));
|
||||
bytes = 2;
|
||||
break;
|
||||
|
||||
case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
|
||||
util::stream_format(stream, "INCL @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2));
|
||||
bytes = 3;
|
||||
@ -887,6 +911,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
bytes = 3;
|
||||
break;
|
||||
|
||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
||||
util::stream_format(stream, "MOVEA A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2));
|
||||
bytes = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "UNK ea-type 71";
|
||||
break;
|
||||
@ -1069,6 +1098,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
bytes = 4;
|
||||
break;
|
||||
|
||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||
util::stream_format(stream, "DBNZ R%d, $%04x", (operand & 0x7), (s8)opcodes.r8(pc+2) + (pc & 0xffff) + 3);
|
||||
bytes = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "UNK ea-type 74";
|
||||
break;
|
||||
@ -1197,6 +1231,11 @@ offs_t f2mc16_disassembler::disassemble(std::ostream &stream, offs_t pc, const d
|
||||
bytes = 2;
|
||||
break;
|
||||
|
||||
case 0xb0: case 0xb1: case 0xb2: case 0xb3: case 0xb4: case 0xb5: case 0xb6: case 0xb7:
|
||||
util::stream_format(stream, "ORW A, @RW%d + #$%02x", (operand & 0x7), opcodes.r8(pc+2));
|
||||
bytes = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
stream << "UNK ea-type 76";
|
||||
break;
|
||||
|
@ -42,6 +42,10 @@ void mb9061x_device::device_start()
|
||||
|
||||
m_tbtc_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mb9061x_device::tbtc_tick), this));
|
||||
m_tbtc_timer->adjust(attotime::never);
|
||||
m_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mb9061x_device::timer0_tick), this));
|
||||
m_timer[0]->adjust(attotime::never);
|
||||
m_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(mb9061x_device::timer1_tick), this));
|
||||
m_timer[1]->adjust(attotime::never);
|
||||
}
|
||||
|
||||
|
||||
@ -59,6 +63,10 @@ device_memory_interface::space_config_vector mb9061x_device::memory_space_config
|
||||
void mb9061x_device::device_reset()
|
||||
{
|
||||
f2mc16_device::device_reset();
|
||||
m_tbtc = 0;
|
||||
memset(m_timer_regs, 0, sizeof(m_timer_regs));
|
||||
memset(m_event_count, 0, sizeof(m_event_count));
|
||||
m_event_state[0] = m_event_state[1] = CLEAR_LINE;
|
||||
}
|
||||
|
||||
void mb9061x_device::execute_set_input(int inputnum, int state)
|
||||
@ -83,6 +91,220 @@ mb90610_device::mb90610_device(const machine_config &mconfig, device_type type,
|
||||
{
|
||||
}
|
||||
|
||||
/* 16-bit preload timers with event count function */
|
||||
enum
|
||||
{
|
||||
TCTH_CSL1 = 0x08, // clock source select bit 1
|
||||
TCTH_CSL0 = 0x04, // clock source select bit 0
|
||||
TCTH_MOD2 = 0x02, // mode bit 2
|
||||
TCTH_MOD1 = 0x01, // mode bit 1
|
||||
|
||||
TCTL_MOD0 = 0x80, // mode bit 0
|
||||
TCTL_OUTE = 0x40, // output enable
|
||||
TCTL_OUTL = 0x20, // output level
|
||||
TCTL_RELD = 0x10, // reload
|
||||
TCTL_INTE = 0x08, // IRQ enable
|
||||
TCTL_UF = 0x04, // expire flag
|
||||
TCTL_CNTE = 0x02, // enable counting
|
||||
TCTL_TRG = 0x01 // force a reload and start counting
|
||||
};
|
||||
|
||||
TIMER_CALLBACK_MEMBER(mb9061x_device::timer0_tick)
|
||||
{
|
||||
u8 ctl = m_timer_regs[0];
|
||||
m_timer_regs[0] |= TCTL_UF;
|
||||
if (ctl & TCTL_INTE)
|
||||
{
|
||||
// printf("timer 0 IRQ\n");
|
||||
intc_trigger_irq(9, 0x1d);
|
||||
}
|
||||
|
||||
if (ctl & TCTL_RELD)
|
||||
{
|
||||
recalc_timer(0);
|
||||
m_timer[0]->adjust(attotime::from_hz(m_timer_hz[0]));
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(mb9061x_device::timer1_tick)
|
||||
{
|
||||
u8 ctl = m_timer_regs[4];
|
||||
m_timer_regs[4] |= TCTL_UF;
|
||||
if (ctl & TCTL_INTE)
|
||||
{
|
||||
// printf("timer 1 IRQ\n");
|
||||
intc_trigger_irq(9, 0x1e);
|
||||
}
|
||||
|
||||
if (ctl & TCTL_RELD)
|
||||
{
|
||||
recalc_timer(0);
|
||||
m_timer[1]->adjust(attotime::from_hz(m_timer_hz[1]));
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER(mb9061x_device::timer_r)
|
||||
{
|
||||
//printf("timer_r: offset %d = %02x\n", offset, m_timer_regs[offset]);
|
||||
return m_timer_regs[offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(mb9061x_device::timer_w)
|
||||
{
|
||||
int timer = offset / 4;
|
||||
int reg = offset % 4;
|
||||
|
||||
//printf("timer_w: %x to %d\n", data, offset);
|
||||
#if 0
|
||||
switch (reg)
|
||||
{
|
||||
case 0: // control/status, lower
|
||||
printf("%02x to timer %d lower control\n", data, timer);
|
||||
break;
|
||||
|
||||
case 1: // control/status, upper
|
||||
printf("%02x to timer %d upper control\n", data, timer);
|
||||
break;
|
||||
|
||||
case 2: // timer/reload, lower
|
||||
printf("%02x to timer %d lower reload\n", data, timer);
|
||||
break;
|
||||
|
||||
case 3: // timer/reload, upper
|
||||
printf("%02x to timer %d upper reload\n", data, timer);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (reg == 0)
|
||||
{
|
||||
m_timer_regs[offset] &= (TCTL_TRG|TCTL_UF);
|
||||
m_timer_regs[offset] |= data;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_timer_regs[offset] = data;
|
||||
}
|
||||
|
||||
int rbase = timer << 2;
|
||||
u8 csl = (m_timer_regs[rbase+1] >> 2) & 3;
|
||||
if (reg == 0)
|
||||
{
|
||||
if (data & TCTL_TRG)
|
||||
{
|
||||
//printf("Got TRG\n");
|
||||
recalc_timer(timer);
|
||||
if ((m_timer_regs[rbase] & TCTL_CNTE) && (csl != 3))
|
||||
{
|
||||
m_timer[timer]->adjust(attotime::from_hz(m_timer_hz[timer]));
|
||||
}
|
||||
}
|
||||
|
||||
if ((data & TCTL_CNTE) && (csl != 3))
|
||||
{
|
||||
//printf("CNTE set, starting timer at %d Hz\n", m_timer_hz[timer]);
|
||||
m_timer[timer]->adjust(attotime::from_hz(m_timer_hz[timer]));
|
||||
}
|
||||
|
||||
if ((data & TCTL_CNTE) && (csl == 3))
|
||||
{
|
||||
m_event_count[timer] = m_timer_regs[2] | (m_timer_regs[3]<<8);
|
||||
//printf("CNTE set in event counter mode, reseeding count to %04x\n", m_event_count[timer]);
|
||||
}
|
||||
|
||||
if (!(data & TCTL_UF))
|
||||
{
|
||||
intc_clear_irq(9, 0x1d + timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(mb9061x_device::tin0_w)
|
||||
{
|
||||
tin_common(0, 0, state);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(mb9061x_device::tin1_w)
|
||||
{
|
||||
tin_common(1, 4, state);
|
||||
}
|
||||
|
||||
void mb9061x_device::tin_common(int timer, int base, int state)
|
||||
{
|
||||
// emsure event counter mode
|
||||
if ((m_timer_regs[base + 1] & (TCTH_CSL0|TCTH_CSL1)) == (TCTH_CSL0|TCTH_CSL1) &&
|
||||
(m_timer_regs[base] & TCTL_CNTE))
|
||||
{
|
||||
bool bTickIt = false;
|
||||
|
||||
// rising edge
|
||||
if ((state && !m_event_state[base/4]) && (m_timer_regs[base] & TCTL_MOD0) && !(m_timer_regs[base+1] & TCTH_MOD1))
|
||||
{
|
||||
bTickIt = true;
|
||||
}
|
||||
|
||||
// falling edge
|
||||
if ((!state && m_event_state[base/4]) && !(m_timer_regs[base] & TCTL_MOD0) && (m_timer_regs[base+1] & TCTH_MOD1))
|
||||
{
|
||||
bTickIt = true;
|
||||
}
|
||||
|
||||
// any edge
|
||||
if ((state != m_event_state[base/4]) && !(m_timer_regs[base] & TCTL_MOD0) && (m_timer_regs[base+1] & TCTH_MOD1))
|
||||
{
|
||||
bTickIt = true;
|
||||
}
|
||||
|
||||
if (bTickIt)
|
||||
{
|
||||
m_event_count[timer]--;
|
||||
//printf("Tick timer %d, new value %04x\n", timer, m_event_count[timer]);
|
||||
|
||||
if (m_event_count[timer] == 0xffff)
|
||||
{
|
||||
u8 ctl = m_timer_regs[base];
|
||||
m_timer_regs[base] |= TCTL_UF;
|
||||
if (ctl & TCTL_INTE)
|
||||
{
|
||||
//printf("timer %d IRQ\n", timer);
|
||||
intc_trigger_irq(9, 0x1d + timer);
|
||||
}
|
||||
|
||||
if (m_timer_regs[timer * 4] & TCTL_RELD)
|
||||
{
|
||||
m_event_count[timer] = m_timer_regs[2] | (m_timer_regs[3]<<8);
|
||||
//printf("timer %d reload to %04x\n", timer, m_event_count[timer]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_event_state[timer] = state;
|
||||
}
|
||||
}
|
||||
|
||||
void mb9061x_device::recalc_timer(int tnum)
|
||||
{
|
||||
int rbase = tnum << 2;
|
||||
u32 divider = 1;
|
||||
u8 csl = (m_timer_regs[rbase+1] >> 2) & 3;
|
||||
|
||||
// check clock select
|
||||
switch (csl)
|
||||
{
|
||||
case 0: divider = 2; break;
|
||||
case 1: divider = 16; break;
|
||||
case 2: divider = 64; break;
|
||||
|
||||
case 3: // event counter mode
|
||||
return;
|
||||
}
|
||||
|
||||
u32 tclk = clock() / divider;
|
||||
u32 tval = m_timer_regs[rbase+2] | (m_timer_regs[rbase+3]<<8);
|
||||
//printf("CSL %d, tclk %d, tval %d\n", csl, tclk, tval);
|
||||
//printf("Timer is %d Hz\n", tclk / tval);
|
||||
m_timer_hz[tnum] = tclk / tval;
|
||||
}
|
||||
|
||||
/* TBTC: timebase counter */
|
||||
enum
|
||||
{
|
||||
@ -182,6 +404,7 @@ void mb9061x_device::intc_clear_irq(int icr, int vector)
|
||||
/* MB90611 - Production version of this series */
|
||||
void mb90611_device::mb90611_map(address_map &map)
|
||||
{
|
||||
map(0x0038, 0x003f).rw(FUNC(mb9061x_device::timer_r), FUNC(mb9061x_device::timer_w));
|
||||
map(0x00a9, 0x00a9).rw(FUNC(mb9061x_device::tbtc_r), FUNC(mb9061x_device::tbtc_w));
|
||||
map(0x00b0, 0x00bf).rw(FUNC(mb9061x_device::intc_r), FUNC(mb9061x_device::intc_w));
|
||||
map(0x0100, 0x04ff).ram(); // 1K of internal RAM from 0x100 to 0x500
|
||||
|
@ -31,6 +31,10 @@ public:
|
||||
ICR0 = 0, ICR1, ICR2, ICR3, ICR4, ICR5, ICR6, ICR7, ICR8, ICR9, ICR10, ICR11, ICR12, ICR13, ICR14, ICR15
|
||||
};
|
||||
|
||||
// timer external counter tick functions
|
||||
DECLARE_WRITE_LINE_MEMBER(tin0_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(tin1_w);
|
||||
|
||||
protected:
|
||||
// construction/destruction
|
||||
mb9061x_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, address_map_constructor internal_map);
|
||||
@ -53,6 +57,20 @@ private:
|
||||
void intc_trigger_irq(int icr, int vector);
|
||||
void intc_clear_irq(int icr, int vector);
|
||||
|
||||
// TIMERS
|
||||
TIMER_CALLBACK_MEMBER(timer0_tick);
|
||||
TIMER_CALLBACK_MEMBER(timer1_tick);
|
||||
READ8_MEMBER(timer_r);
|
||||
WRITE8_MEMBER(timer_w);
|
||||
void recalc_timer(int tnum);
|
||||
void tin_common(int timer, int base, int state);
|
||||
|
||||
u8 m_timer_regs[8];
|
||||
u32 m_timer_hz[2];
|
||||
emu_timer *m_timer[2];
|
||||
int m_event_state[2];
|
||||
u16 m_event_count[2];
|
||||
|
||||
u8 m_tbtc;
|
||||
emu_timer *m_tbtc_timer;
|
||||
|
||||
|
@ -5,11 +5,51 @@
|
||||
|
||||
Prin-C use a Fujitsu MB90611A MCU (F2MC-16L)
|
||||
|
||||
[:maincpu] ':maincpu' (FFC431): unmapped program memory write to 0000A1 = 00 & FF CKSCR
|
||||
[:maincpu] ':maincpu' (FFC437): unmapped program memory write to 000048 = 04 & FF CS control 0 (Enable out, region is 1 MByte @ F00000)
|
||||
[:maincpu] ':maincpu' (FFC43D): unmapped program memory write to 000049 = 04 & FF CS control 1 (Enable out, region is 1 MByte @ E00000)
|
||||
[:maincpu] ':maincpu' (FFC443): unmapped program memory write to 00004A = 07 & FF CS control 2 (Enable out, region is 128 byte @ 68FF80)
|
||||
[:maincpu] ':maincpu' (FFC449): unmapped program memory write to 00004B = 00 & FF CS control 3 (No out, region is reserved)
|
||||
[:maincpu] ':maincpu' (FFC44F): unmapped program memory write to 0000A5 = D3 & FF ARSR (3 cycle wait state from addrs 002000 to 7FFFFF, 3 waits from C0 to FF, 1 cycle wait on addresses > 800000)
|
||||
[:maincpu] ':maincpu' (FFC455): unmapped program memory write to 0000A6 = 00 & FF HACR ()
|
||||
[:maincpu] ':maincpu' (FFC45B): unmapped program memory write to 0000A7 = 7F & FF ECSR
|
||||
[:maincpu] ':maincpu' (FFC461): unmapped program memory write to 000011 = 00 & FF Port 1 DDR
|
||||
[:maincpu] ':maincpu' (FFC467): unmapped program memory write to 000012 = FF & FF 2
|
||||
[:maincpu] ':maincpu' (FFC46D): unmapped program memory write to 000013 = FF & FF 3
|
||||
[:maincpu] ':maincpu' (FFC473): unmapped program memory write to 000014 = FF & FF 4
|
||||
[:maincpu] ':maincpu' (FFC479): unmapped program memory write to 000015 = 01 & FF 5
|
||||
[:maincpu] ':maincpu' (FFC47F): unmapped program memory write to 000016 = 1F & FF Analog input enable
|
||||
[:maincpu] ':maincpu' (FFC485): unmapped program memory write to 000016 = E0 & FF 7
|
||||
[:maincpu] ':maincpu' (FFC48B): unmapped program memory write to 000017 = 30 & FF 8
|
||||
[:maincpu] ':maincpu' (FFC491): unmapped program memory write to 000018 = 0C & FF 9
|
||||
[:maincpu] ':maincpu' (FFC497): unmapped program memory write to 00001A = FF & FF A
|
||||
[:maincpu] ':maincpu' (FFC189): unmapped program memory write to 00000A = 00 & FF port A
|
||||
[:maincpu] ':maincpu' (FFC257): unmapped program memory write to 00000A = 80 & FF port A
|
||||
[:maincpu] ':maincpu' (FE2C08): unmapped program memory write to 0000A9 = 96 & FF TBTC - IRQ enabled, 16.384 ms timebase
|
||||
[:maincpu] ':maincpu' (FE2C11): unmapped program memory write to 0000BB = 06 & FF ICR11 - level 6 interrupt, no intelligent I/O
|
||||
[:maincpu] ':maincpu' (FE2959): unmapped program memory write to 000017 = 30 & FF port 7 DDR
|
||||
[:maincpu] ':maincpu' (FE2963): unmapped program memory write to 0000A9 = 96 & FF TBTC
|
||||
[:maincpu] ':maincpu' (FE296C): unmapped program memory write to 0000BB = 06 & FF ICR11
|
||||
[:maincpu] ':maincpu' (FE29CC): unmapped program memory write to 000007 = 00 & FF port 7 out
|
||||
[:maincpu] ':maincpu' (FE2A69): unmapped program memory write to 0000A9 = 96 & FF TBTC
|
||||
[:maincpu] ':maincpu' (FE2A72): unmapped program memory write to 0000BB = 06 & FF ICR11
|
||||
[:maincpu] ':maincpu' (FC2AD5): unmapped program memory write to 000018 = 0C & FF port 8 DDR
|
||||
[:maincpu] ':maincpu' (FC2ADE): unmapped program memory write to 000039 = 0C & FF TMCSR0 (clock = phase 16 MHz / 2^1, trigger input, rising edge)
|
||||
[:maincpu] ':maincpu' (FC2AE8): unmapped program memory write to 000038 = F0 & FF TMCSR0 (toggle output, H Level at start, no count or interrupt enable)
|
||||
[:maincpu] ':maincpu' (FC2AF1): unmapped program memory write to 00003D = 0C & FF TMCSR1
|
||||
[:maincpu] ':maincpu' (FC2AFB): unmapped program memory write to 00003C = F0 & FF TMCSR1
|
||||
[:maincpu] ':maincpu' (FE2B89): unmapped program memory write to 000007 = 00 & FF port 7 out
|
||||
[:maincpu] ':maincpu' (FCE68D): unmapped program memory write to 000007 = 10 & FF port 7 out
|
||||
[:maincpu] ':maincpu' (FCE6BA): unmapped program memory write to 000034 = 73 & FF PRL0 (PPG0 reload)
|
||||
[:maincpu] ':maincpu' (FCE6D3): unmapped program memory write to 000036 = 0D & FF PRL1 (PPG1 reload)
|
||||
[:maincpu] ':maincpu' (FCE6DE): unmapped program memory write to 000030 = 85 & FF PPG0C0 (PPG0 control) (PPG Enabled, 16 MHz / 16, no interrupts)
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "machine/timer.h"
|
||||
#include "cpu/f2mc16/mb9061x.h"
|
||||
#include "bus/generic/slot.h"
|
||||
#include "bus/generic/carts.h"
|
||||
@ -22,6 +62,7 @@ public:
|
||||
, m_cart(*this, "cartslot")
|
||||
, m_screen(*this, "screen")
|
||||
, m_maincpu(*this, "maincpu")
|
||||
, m_scantimer(*this, "scantimer")
|
||||
{ }
|
||||
|
||||
void tomy_princ(machine_config &config);
|
||||
@ -31,13 +72,21 @@ protected:
|
||||
private:
|
||||
required_device<generic_slot_device> m_cart;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<f2mc16_device> m_maincpu;
|
||||
required_device<mb90611_device> m_maincpu;
|
||||
required_device<timer_device> m_scantimer;
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(scan_interrupt);
|
||||
|
||||
void princ_map(address_map &map);
|
||||
|
||||
uint32_t screen_update_tomy_princ(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
};
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(tomy_princ_state::scan_interrupt)
|
||||
{
|
||||
m_maincpu->tin0_w(ASSERT_LINE);
|
||||
m_maincpu->tin0_w(CLEAR_LINE);
|
||||
}
|
||||
|
||||
uint32_t tomy_princ_state::screen_update_tomy_princ(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
@ -46,7 +95,7 @@ uint32_t tomy_princ_state::screen_update_tomy_princ(screen_device &screen, bitma
|
||||
|
||||
void tomy_princ_state::princ_map(address_map &map)
|
||||
{
|
||||
map(0x68ff44, 0x68ff44).lr8("free0", [this]() -> u8 { return m_screen->vblank() ? 1 : 0; });
|
||||
map(0x68ff44, 0x68ff44).lr8("free0", [this]() -> u8 { return m_screen->vblank() ? 0x11 : 0x10; });
|
||||
map(0xe00000, 0xe07fff).ram(); // stacks are placed here
|
||||
map(0xf00000, 0xffffff).rom().region("maincpu", 0x00000);
|
||||
}
|
||||
@ -67,6 +116,9 @@ void tomy_princ_state::tomy_princ(machine_config &config)
|
||||
m_screen->set_size(256, 256);
|
||||
m_screen->set_visarea(0, 256-1, 0, 256-1);
|
||||
|
||||
TIMER(config, m_scantimer, 0);
|
||||
m_scantimer->configure_scanline(FUNC(tomy_princ_state::scan_interrupt), "screen", 0, 1);
|
||||
|
||||
GENERIC_CARTSLOT(config, m_cart, generic_plain_slot, "princ_cart");
|
||||
SOFTWARE_LIST(config, "cart_list").set_original("princ");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user