Exemplo n.º 1
0
void dsp16_device::execute_run()
{
	// HACK TO MAKE CPU DO NOTHING.
	// REMOVE IF DEVELOPING CPU CORE.
	m_icount = 0;
	return;

	do
	{
		// debugging
		m_ppc = m_pc;   // copy PC to previous PC
		debugger_instruction_hook(this, m_pc);

		// instruction fetch & execute
		UINT8 cycles;
		UINT8 pcAdvance;
		const UINT16 op = opcode_read();
		execute_one(op, cycles, pcAdvance);

		// step
		m_pc += pcAdvance;
		m_icount -= cycles;

		// The 16 bit PI "shadow" register gets set to PC on each instruction except
		// when an interrupt service routine is active (TODO: Interrupt check)  (page 2-4)
		m_pi = m_pc;

	} while (m_icount > 0);
}
Exemplo n.º 2
0
void dsp16_device::execute_one(const UINT16& op, UINT8& cycles, UINT8& pcAdvance)
{
    cycles = 1;
    pcAdvance = 0;

    const UINT8 opcode = (op >> 11) & 0x1f;
    switch(opcode)
    {
    // Format 1: Multiply/ALU Read/Write Group
    case 0x06:
    {
        // F1, Y  :  (page 3-38)
        const UINT8 Y = (op & 0x000f);
        const UINT8 S = (op & 0x0200) >> 9;
        const UINT8 D = (op & 0x0400) >> 10;
        const UINT8 F1 = (op & 0x01e0) >> 5;
        executeF1Field(F1, D, S);
        executeYFieldPost(Y);
        cycles = 1;
        pcAdvance = 1;
        break;
    }
    case 0x04:
    case 0x1c:
    {
        // F1 Y=a0[1] | F1 Y=a1[1]
        //const UINT8 Y = (op & 0x000f);
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 D = (op & 0x0400) >> 10;
        //const UINT8 F1 = (op & 0x01e0) >> 5;
        break;
    }
    case 0x16:
    {
        // F1, x = Y
        //const UINT8 Y = (op & 0x000f);
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 D = (op & 0x0400) >> 10;
        //const UINT8 F1 = (op & 0x01e0) >> 5;
        break;
    }
    case 0x17:
    {
        // F1, y[l] = Y  :  (page 3-44)
        const UINT8 Y = (op & 0x000f);
        const UINT8 X = (op & 0x0010) >> 4;
        const UINT8 S = (op & 0x0200) >> 9;
        const UINT8 D = (op & 0x0400) >> 10;
        const UINT8 F1 = (op & 0x01e0) >> 5;
        executeF1Field(F1, D, S);
        UINT16* sourceReg = (UINT16*)registerFromYFieldUpper(Y);
        UINT16 sourceValue = data_read(*sourceReg);
        switch (X)
        {
        case 0x00:
            writeRegister(addressYL(), sourceValue);
            break;
        case 0x01:
            writeRegister(&m_y, sourceValue);
            break;
        default:
            break;
        }
        executeYFieldPost(Y);
        cycles = 1;
        pcAdvance = 1;
        break;
    }
    case 0x1f:
    {
        // F1, y = Y, x = *pt++[i]
        //const UINT8 Y = (op & 0x000f);
        //const UINT8 X = (op & 0x0010) >> 4;
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 D = (op & 0x0400) >> 10;
        //const UINT8 F1 = (op & 0x01e0) >> 5;
        break;
    }
    case 0x19:
    case 0x1b:
    {
        // F1, y = a0|1, x = *pt++[i]
        //const UINT8 Y = (op & 0x000f);
        //const UINT8 X = (op & 0x0010) >> 4;
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 D = (op & 0x0400) >> 10;
        //const UINT8 F1 = (op & 0x01e0) >> 5;
        break;
    }
    case 0x14:
    {
        // F1, Y = y[1]  :  (page 3-53)
        const UINT8 Y = (op & 0x000f);
        const UINT8 X = (op & 0x0010) >> 4;
        const UINT8 S = (op & 0x0200) >> 9;
        const UINT8 D = (op & 0x0400) >> 10;
        const UINT8 F1 = (op & 0x01e0) >> 5;
        executeF1Field(F1, D, S);
        UINT16* destinationReg = (UINT16*)registerFromYFieldUpper(Y);
        UINT16 yRegValue = 0x0000;
        switch (X)
        {
        case 0x00:
            yRegValue = (m_y & 0x0000ffff);
            break;
        case 0x01:
            yRegValue = (m_y & 0xffff0000) >> 16;
            break;
        default:
            break;
        }
        data_write(*destinationReg, yRegValue);
        executeYFieldPost(Y);
        cycles = 2;
        pcAdvance = 1;
        break;
    }

    // Format 1a: Multiply/ALU Read/Write Group (TODO: Figure out major typo in docs on p3-51)
    case 0x07:
    {
        // F1, At[1] = Y  :  (page 3-50)
        const UINT8 Y = (op & 0x000f);
        const UINT8 S = (op & 0x0200) >> 9;
        const UINT8 aT = (op & 0x0400) >> 10;
        const UINT8 F1 = (op & 0x01e0) >> 5;
        executeF1Field(F1, !aT, S);
        UINT64* destinationReg = NULL;
        switch(aT)
        {
        case 0:
            destinationReg = &m_a1;
            break;
        case 1:
            destinationReg = &m_a0;
            break;
        default:
            break;
        }
        UINT16 sourceAddress = *((UINT16*)registerFromYFieldUpper(Y));
        INT64 sourceValueSigned = (INT16)data_read(sourceAddress);
        *destinationReg = sourceValueSigned & U64(0xffffffffff);
        executeYFieldPost(Y);
        cycles = 1;
        pcAdvance = 1;
        break;
    }

    // Format 2: Multiply/ALU Read/Write Group
    case 0x15:
    {
        // F1, Z : y[1]
        //const UINT8 Z = (op & 0x000f);
        //const UINT8 X = (op & 0x0010) >> 4;
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 D = (op & 0x0400) >> 10;
        //const UINT8 F1 = (op & 0x01e0) >> 5;
        break;
    }
    case 0x1d:
    {
        // F1, Z : y, x=*pt++[i]
        //const UINT8 Z = (op & 0x000f);
        //const UINT8 X = (op & 0x0010) >> 4;
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 D = (op & 0x0400) >> 10;
        //const UINT8 F1 = (op & 0x01e0) >> 5;
        break;
    }

    // Format 2a: Multiply/ALU Read/Write Group
    case 0x05:
    {
        // F1, Z : aT[1]
        //const UINT8 Z = (op & 0x000f);
        //const UINT8 X = (op & 0x0010) >> 4;
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 aT = (op & 0x0400) >> 10;
        //const UINT8 F1 = (op & 0x01e0) >> 5;
        break;
    }

    // Format 3: Special Functions
    case 0x12:
    case 0x13:
    {
        // if|ifc CON F2
        //const UINT8 CON = (op & 0x001f);
        //const UINT8 S = (op & 0x0200) >> 9;
        //const UINT8 D = (op & 0x0400) >> 10;
        //const UINT8 F2 = (op & 0x01e0) >> 5;
        break;
    }

    // Format 4: Branch Direct Group
    case 0x00:
    case 0x01:
    {
        // goto JA  :  (page 3-20)
        const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
        m_pc = JA;
        cycles = 2;
        pcAdvance = 0;
        break;
    }

    case 0x10:
    case 0x11:
    {
        // call JA  :  (page 3-23)
        const UINT16 JA = (op & 0x0fff) | (m_pc & 0xf000);
        m_pr = m_pc + 1;
        m_pc = JA;
        cycles = 2;
        pcAdvance = 0;
        break;
    }

    // Format 5: Branch Indirect Group
    case 0x18:
    {
        // goto B
        //const UINT8 B = (op & 0x0700) >> 8;
        break;
    }

    // Format 6: Contitional Branch Qualifier/Software Interrupt (icall)
    case 0x1a:
    {
        // if CON [goto/call/return]
        //const UINT8 CON = (op & 0x001f);
        break;
    }

    // Format 7: Data Move Group
    case 0x09:
    case 0x0b:
    {
        // R = aS
        //const UINT8 R = (op & 0x03f0) >> 4;
        //const UINT8 S = (op & 0x1000) >> 12;
        break;
    }
    case 0x08:
    {
        // aT = R
        //const UINT8 R  = (op & 0x03f0) >> 4;
        //const UINT8 aT = (op & 0x0400) >> 10;
        break;
    }
    case 0x0f:
    {
        // R = Y
        //const UINT8 Y = (op & 0x000f);
        //const UINT8 R = (op & 0x03f0) >> 4;
        break;
    }
    case 0x0c:
    {
        // Y = R  :  (page 3-33)
        const UINT8 Y = (op & 0x000f);
        const UINT8 R = (op & 0x03f0) >> 4;
        UINT16* destinationReg = (UINT16*)registerFromYFieldUpper(Y);
        UINT16* sourceReg = (UINT16*)registerFromRTable(R);
        data_write(*destinationReg, *sourceReg);
        executeYFieldPost(Y);
        cycles = 2;
        pcAdvance = 1;
        break;
    }
    case 0x0d:
    {
        // Z : R
        //const UINT8 Z = (op & 0x000f);
        //const UINT8 R = (op & 0x03f0) >> 4;
        break;
    }

    // Format 8: Data Move (immediate operand - 2 words)
    case 0x0a:
    {
        // R = N  :  (page 3-28)
        const UINT8 R = (op & 0x03f0) >> 4;
        const UINT16 iVal = opcode_read(1);
        void* reg = registerFromRTable(R);
        writeRegister(reg, iVal);
        cycles = 2;
        pcAdvance = 2;
        break;
    }

    // Format 9: Short Immediate Group
    case 0x02:
    case 0x03:
    {
        // R = M  :  (page 3-27)
        const INT8 M = (op & 0x00ff);
        const UINT8 R = (op & 0x0e00) >> 9;
        void* reg = registerFromRImmediateField(R);
        writeRegister(reg, (INT16)M);   // Sign extend 8 bit int
        cycles = 1;
        pcAdvance = 1;
        break;
    }

    // Format 10: do - redo
    case 0x0e:
    {
        // do|redo K  :  (pages 3-25 & 3-26)
        const UINT8 K = (op & 0x007f);
        const UINT8 NI = (op & 0x0780) >> 7;
        if (NI != 0)
        {
            // Do
            m_cacheStart = m_pc + 1;
            m_cacheEnd = m_pc + NI + 1;
            m_cacheIterations = K-1;    // -1 because we check the counter below
            cycles = 1;
            pcAdvance = 1;
        }
        else
        {
            // Redo
            m_cacheIterations = K-1;    // -1 because we check the counter below
            m_cacheRedoNextPC = m_pc + 1;
            m_pc = m_cacheStart;
            pcAdvance = 0;
            cycles = 2;
            pcAdvance = 1;
        }
        break;
    }

    // RESERVED
    case 0x1e:
    {
        break;
    }

    // UNKNOWN
    default:
    {
        break;
    }
    }

    // Handle end-of-cache conditions for do|redos
    if (m_cacheIterations == 0 && m_cacheRedoNextPC != CACHE_INVALID)
    {
        // You've reached the end of a cache loop after a redo opcode.
        m_pc = m_cacheRedoNextPC;
        m_cacheRedoNextPC = CACHE_INVALID;
        pcAdvance = 0;
    }
    if (m_cacheIterations > 0 && (m_pc+pcAdvance == m_cacheEnd))
    {
        // A regular iteration on a cached loop.
        m_cacheIterations--;
        m_pc = m_cacheStart;
        pcAdvance = 0;
    }
}