You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
2.8 KiB

6 years ago
6 years ago
  1. class Register:
  2. registers = []
  3. def __init__(self, n_bits, name=None):
  4. self.n_bits = n_bits
  5. if name is None:
  6. self.name = "r{}".format(len(Register.registers))
  7. else:
  8. self.name = name
  9. self.value = 0
  10. Register.registers.append(self)
  11. def truncate_val(self, value, bits=None):
  12. if bits is None:
  13. bits = self.n_bits
  14. return value & ((1 << bits) - 1)
  15. def truncate(self):
  16. self.value = self.truncate_val(self.value)
  17. def set(self, value):
  18. if value < 0:
  19. self.value = self.truncate_val(abs(value), self.n_bits - 1)
  20. self.negate()
  21. else:
  22. self.value = value
  23. self.truncate()
  24. def get(self):
  25. return self.value
  26. def get_signed(self):
  27. if self.value & (1 << (self.n_bits - 1)) == 0:
  28. return self.value
  29. else:
  30. return self.value - (1 << self.n_bits)
  31. def complement(self):
  32. self.value = self.value ^ ((1 << self.n_bits) - 1)
  33. def negate(self):
  34. self.complement()
  35. self.value += 1
  36. def __str__(self):
  37. return "{:08b}".format(self.value)
  38. def __repr__(self):
  39. return "{} ({})".format(self, self.n_bits)
  40. class Accumulator(Register):
  41. negative_flag = False
  42. zero_flag = False
  43. carry_flag = False
  44. parity_flag = False
  45. def set_flags(self):
  46. "Set accumulator flags after an arithmetic operation"
  47. self.negative_flag = False
  48. self.zero_flag = False
  49. if self.get_signed() < 0:
  50. self.negative_flag = True
  51. if self.get() == 0:
  52. self.zero_flag = True
  53. v = self.get()
  54. self.parity_flag = True
  55. while v > 0:
  56. if (v & 1) == 1:
  57. self.parity_flag = not self.parity_flag
  58. v >>= 1
  59. def add(self, register: Register):
  60. self.value += register.value
  61. if self.value.bit_length() > self.n_bits:
  62. self.carry_flag = True
  63. self.truncate()
  64. self.set_flags()
  65. def sub(self, register: Register):
  66. self.negate()
  67. self.add(register)
  68. self.negate()
  69. self.set_flags()
  70. def shift_right(self, through_carry=True):
  71. was_one = (self.get() & 1) == 1
  72. if through_carry:
  73. add_bit = self.carry_flag
  74. else:
  75. add_bit = was_one
  76. if add_bit:
  77. self.value |= 1 << (self.n_bits)
  78. self.value >>= 1
  79. self.carry_flag = was_one
  80. self.set_flags()
  81. def shift_left(self, through_carry=True):
  82. was_one = (self.get() & (1 << (self.n_bits - 1))) != 0
  83. if through_carry:
  84. add_bit = self.carry_flag
  85. else:
  86. add_bit = was_one
  87. self.value <<= 1
  88. if add_bit:
  89. self.value |= 1
  90. self.carry_flag = was_one
  91. self.set_flags()