Skip to content
Snippets Groups Projects
emulate.c 1.86 KiB
Newer Older
iftach's avatar
iftach committed
#include <math.h>
#include <stdint.h>
#include <stdio.h>

#define MEMORY_SIZE 65536

// Helpful stuff (things that will probably be used to implement more than one instruction type)

// struct representing a processor:
struct ProcessorState
{
  int32_t registers[17];
  int32_t memory[MEMORY_SIZE];
};

// Reads bits from source in the range [start, end] (inclusive). Returns a uint32_t with the result as its least significant bits.
// (e.g. getBits(8, 2, 3) == 2)
int32_t getBits(int source, int start, int end)
{
  return (source & ((2 << end) - (1 << start))) >> start;
}

// Shorthand for getBits(source, index, index)
int isSet(int source, int index)
{
  return (source & (1 << index));
}

// Returns 1 if the condition code 'cond' is satisfied by the processor's current state, and 0 otherwise.
// Any condition code not listed in the spec will cause this to return 0.
int validCond(int32_t cond, struct ProcessorState *processor)
{
  int32_t cprs = (*processor).registers[16];
  int n = isSet(cprs, 31);
  int z = isSet(cprs, 30);
  int c = isSet(cprs, 29);
  int v = isSet(cprs, 28);

  switch (cond)
  {
  case 0:
    return z != 0;
  case 1:
    return z == 0;
  case 10:
    return n == z;
  case 11:
    return n != z;
  case 12:
    return !z && (n == v);
  case 13:
    return z || (n != v);
  case 14:
    return 1;
  default:
    return 0;
  }
}

/*  (not finished):
int32_t barrelShift(int immediate, int32_t operand, int *carry, struct ProcessorState *processor)
{
  if (immediate)
  {
    unsigned int rotate = (unsigned int)getBits(operand, 8, 11);
    uint32_t imm = (uint32_t)getBits(operand, 0, 7);
    return (imm >> (2 * rotate)) | (imm << (32 - 2 * rotate));
  }
  uint32_t reg = (uint32_t)(*processor).registers[getBits(operand, 8, 11)];
  unsigned int shift = getBits(operand, 5, 6);



}
*/

// TODO: applyOperation(int opcode, int32_t operator1, int32_t operator2, int *carry)