#include "include/reg_access.h"
#include "include/aliases.h"
#include <stdio.h>

static u16 registers[REGISTER_COUNT] = {0};

#define BIT_PER_BYTE 8

void set_register(register_access reg, u16 new_value) {
  if (reg.Count == 2) {
    registers[reg.Index] = new_value;
    return;
  }

  u16 shift = (u16)(reg.Offset) * BIT_PER_BYTE;
  u16 mask = 0xff00;

  registers[reg.Index] &= (mask >> shift);
  registers[reg.Index] |= (new_value << shift);
}

u16 get_register(register_access reg) {
  if (reg.Count == 2) {
    return registers[reg.Index];
  }

  u16 shift = (u16)(reg.Offset) * BIT_PER_BYTE;
  u16 mask = 0x00ff;

  return (registers[reg.Index] >> shift) & mask;
}

const char *get_register_name(register_access reg) {
  // clang-format off
  static const char *register_names[REGISTER_COUNT][3] = {
      {"NONE", "NONE", "NONE"},
			{"al", "ah", "ax"},
      {"bl", "bh", "bx"},
      {"cl", "ch", "cx"},
      {"dl", "dh", "dx"},
			{"sp", "sp", "sp"},
			{"bp", "bp", "bp"},
			{"si", "si", "si"},
			{"di", "di", "di"},
			{"es", "es", "es"},
			{"cs", "cs", "cs"},
			{"ss", "ss", "ss"},
			{"ds", "ds", "ds"},
  };
  // clang-format on

  return register_names[reg.Index]
                       [(reg.Count == 2) ? 2 : (reg.Offset & reg.Count)];
}