[patinho] implementation of the shift/rotate instructions (DE, GE, DEV, GEV, DD, GD, DDV, GDV and DDS)

This commit is contained in:
Felipe Corrêa da Silva Sanches 2015-11-30 12:33:27 -02:00
parent b1960f2360
commit 5c4e4a375d
3 changed files with 108 additions and 14 deletions

View File

@ -93,6 +93,7 @@ void patinho_feio_cpu_device::execute_instruction()
debugger_instruction_hook(this, PC);
offs_t addr;
bool skip;
unsigned int tmp;
unsigned char value, channel, function;
unsigned char opcode = READ_BYTE_PATINHO(PC);
INCREMENT_PC_4K;
@ -150,7 +151,7 @@ void patinho_feio_cpu_device::execute_instruction()
return;
case 0x87:
//LIMP1:
// Clear accumulator and sets V=1
// Clear accumulator, reset T and set V
ACC = 0;
FLAGS = V;
return;
@ -189,6 +190,7 @@ void patinho_feio_cpu_device::execute_instruction()
//Executes I/O functions
//TODO: Implement-me!
value = READ_BYTE_PATINHO(PC);
INCREMENT_PC_4K;
channel = opcode & 0x0F;
function = value & 0x0F;
switch(value & 0xF0){
@ -227,7 +229,99 @@ void patinho_feio_cpu_device::execute_instruction()
printf("Unimplemented SAI /%X0 instruction\n", channel);
break;
}
return;
case 0xD1:
//Bit-Shift/Bit-Rotate instructions
value = READ_BYTE_PATINHO(PC);
INCREMENT_PC_4K;
for (int i=0; i<4; i++){
if (value & (1<<i)){
/* The number of shifts or rotations is determined by the
ammount of 1 bits in the lower 4 bits of 'value' */
switch(value & 0xF0)
{
case 0x00:
//DD="Deslocamento para a Direita"
// Shift right
FLAGS &= ~V;
if (ACC & 1)
FLAGS |= V;
ACC >>= 1;
break;
case 0x20:
//GD="Giro para a Direita"
// Rotate right
FLAGS &= ~V;
if (ACC & 1)
FLAGS |= V;
ACC = ((ACC & 1) << 7) | (ACC >> 1);
break;
case 0x10: //DDV="Deslocamento para a Direita com Vai-um"
// Shift right with Carry
case 0x30: //GDV="Giro para a Direita com Vai-um"
// Rotate right with Carry
//both instructions are equivalent
if (FLAGS & V)
tmp = 0x100 | ACC;
else
tmp = ACC;
FLAGS &= ~V;
if (ACC & 1)
FLAGS |= V;
ACC = tmp >> 1;
break;
case 0x40: //DE="Deslocamento para a Esquerda"
// Shift left
FLAGS &= ~V;
if (ACC & (1<<7))
FLAGS |= V;
ACC <<= 1;
break;
case 0x60: //GE="Giro para a Esquerda"
// Rotate left
FLAGS &= ~V;
if (ACC & (1<<7))
FLAGS |= V;
ACC = (ACC << 1) | ((ACC >> 7) & 1);
break;
case 0x50: //DEV="Deslocamento para a Esquerda com Vai-um"
// Shift left with Carry
case 0x70: //GEV="Giro para a Esquerda com Vai-um"
// Rotate left with Carry
//both instructions are equivalent
if (FLAGS & V)
tmp = (ACC << 1) | 1;
else
tmp = (ACC << 1);
FLAGS &= ~V;
if (tmp & (1<<8))
FLAGS |= V;
ACC = tmp & 0xFF;
break;
case 0x80: //DDS="Deslocamento para a Direita com duplicacao de Sinal"
// Rotate right with signal duplication
FLAGS &= ~V;
if (ACC & 1)
FLAGS |= V;
ACC = (ACC & (1 << 7)) | ACC >> 1;
break;
default:
printf("Illegal instruction: %02X %02X\n", opcode, value);
return;
}
}
}
return;
}

View File

@ -29,10 +29,10 @@ protected:
address_space_config m_program_config;
/* processor registers */
int m_acc; /* accumulator (8 bits) */
int m_pc; /* program counter (12 bits)
unsigned char m_acc; /* accumulator (8 bits) */
unsigned int m_pc; /* program counter (12 bits)
(CI stands for "Contador de Instrucao") */
int m_idx;
unsigned char m_idx;
/* processor state flip-flops */
bool m_run; /* processor is running */

View File

@ -111,21 +111,21 @@ CPU_DISASSEMBLE( patinho_feio )
}
break;
case 0xD0:
value = oprom[1];
value = oprom[1] & 0x0F;
switch (oprom[0] & 0x0F)
{
case 0x01:
switch (oprom[1] & 0xF0)
{
case 0x00: sprintf (buffer, "DD /%02X", value); return 2; //DD = "Deslocamento para a direita": Shift right
case 0x10: sprintf (buffer, "DDV /%02X", value); return 2; //DDV = "Deslocamento para a direita c/ V": Shift right with carry
case 0x20: sprintf (buffer, "GD /%02X", value); return 2; //GD = "Giro para a direita": Rotate right
case 0x30: sprintf (buffer, "GDV /%02X", value); return 2; //GDV = "Giro para a direita c/ V": Rotate right with carry
case 0x40: sprintf (buffer, "DE /%02X", value); return 2; //DE = "Deslocamento para a esquerda": Shift right
case 0x50: sprintf (buffer, "DEV /%02X", value); return 2; //DEV = "Deslocamento para a esquerda c/ V": Shift right with carry
case 0x60: sprintf (buffer, "GE /%02X", value); return 2; //GE = "Giro para a esquerda": Rotate right
case 0x70: sprintf (buffer, "GEV /%02X", value); return 2; //GEV = "Giro para a esquerda c/ V": Rotate right with carry
case 0x80: sprintf (buffer, "DDS /%02X", value); return 2; //DDS = "Deslocamento para a direita com duplicacao de sinal": Shift right with sign duplication
case 0x00: sprintf (buffer, "DD /%01X", value); return 2; //DD = "Deslocamento para a direita": Shift right
case 0x10: sprintf (buffer, "DDV /%01X", value); return 2; //DDV = "Deslocamento para a direita c/ V": Shift right with carry
case 0x20: sprintf (buffer, "GD /%01X", value); return 2; //GD = "Giro para a direita": Rotate right
case 0x30: sprintf (buffer, "GDV /%01X", value); return 2; //GDV = "Giro para a direita c/ V": Rotate right with carry
case 0x40: sprintf (buffer, "DE /%01X", value); return 2; //DE = "Deslocamento para a esquerda": Shift right
case 0x50: sprintf (buffer, "DEV /%01X", value); return 2; //DEV = "Deslocamento para a esquerda c/ V": Shift right with carry
case 0x60: sprintf (buffer, "GE /%01X", value); return 2; //GE = "Giro para a esquerda": Rotate right
case 0x70: sprintf (buffer, "GEV /%01X", value); return 2; //GEV = "Giro para a esquerda c/ V": Rotate right with carry
case 0x80: sprintf (buffer, "DDS /%01X", value); return 2; //DDS = "Deslocamento para a direita com duplicacao de sinal": Shift right with sign duplication
}
break;
case 0x02: sprintf (buffer, "XOR /%02X", value); return 2; //Logical XOR