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
109 lines
2.8 KiB
class Register:
|
|
registers = []
|
|
|
|
def __init__(self, n_bits, name=None):
|
|
self.n_bits = n_bits
|
|
if name is None:
|
|
self.name = "r{}".format(len(Register.registers))
|
|
else:
|
|
self.name = name
|
|
self.value = 0
|
|
Register.registers.append(self)
|
|
|
|
def truncate_val(self, value, bits=None):
|
|
if bits is None:
|
|
bits = self.n_bits
|
|
return value & ((1 << bits) - 1)
|
|
|
|
def truncate(self):
|
|
self.value = self.truncate_val(self.value)
|
|
|
|
def set(self, value):
|
|
if value < 0:
|
|
self.value = self.truncate_val(abs(value), self.n_bits - 1)
|
|
self.negate()
|
|
else:
|
|
self.value = value
|
|
self.truncate()
|
|
|
|
def get(self):
|
|
return self.value
|
|
|
|
def get_signed(self):
|
|
if self.value & (1 << (self.n_bits - 1)) == 0:
|
|
return self.value
|
|
else:
|
|
return self.value - (1 << self.n_bits)
|
|
|
|
def complement(self):
|
|
self.value = self.value ^ ((1 << self.n_bits) - 1)
|
|
|
|
def negate(self):
|
|
self.complement()
|
|
self.value += 1
|
|
|
|
def __str__(self):
|
|
return "{:08b}".format(self.value)
|
|
|
|
def __repr__(self):
|
|
return "{} ({})".format(self, self.n_bits)
|
|
|
|
|
|
class Accumulator(Register):
|
|
negative_flag = False
|
|
zero_flag = False
|
|
carry_flag = False
|
|
parity_flag = False
|
|
|
|
def set_flags(self):
|
|
"Set accumulator flags after an arithmetic operation"
|
|
self.negative_flag = False
|
|
self.zero_flag = False
|
|
|
|
if self.get_signed() < 0:
|
|
self.negative_flag = True
|
|
if self.get() == 0:
|
|
self.zero_flag = True
|
|
v = self.get()
|
|
self.parity_flag = True
|
|
while v > 0:
|
|
if (v & 1) == 1:
|
|
self.parity_flag = not self.parity_flag
|
|
v >>= 1
|
|
|
|
def add(self, register: Register):
|
|
self.value += register.value
|
|
if self.value.bit_length() > self.n_bits:
|
|
self.carry_flag = True
|
|
self.truncate()
|
|
self.set_flags()
|
|
|
|
def sub(self, register: Register):
|
|
self.negate()
|
|
self.add(register)
|
|
self.negate()
|
|
self.set_flags()
|
|
|
|
def shift_right(self, through_carry=True):
|
|
was_one = (self.get() & 1) == 1
|
|
if through_carry:
|
|
add_bit = self.carry_flag
|
|
else:
|
|
add_bit = was_one
|
|
if add_bit:
|
|
self.value |= 1 << (self.n_bits)
|
|
self.value >>= 1
|
|
self.carry_flag = was_one
|
|
self.set_flags()
|
|
|
|
def shift_left(self, through_carry=True):
|
|
was_one = (self.get() & (1 << (self.n_bits - 1))) != 0
|
|
if through_carry:
|
|
add_bit = self.carry_flag
|
|
else:
|
|
add_bit = was_one
|
|
self.value <<= 1
|
|
if add_bit:
|
|
self.value |= 1
|
|
self.carry_flag = was_one
|
|
self.set_flags()
|