Updated emulator and assembler to updated ISA

This commit is contained in:
Kyler 2024-02-24 23:46:15 -07:00
parent 4ebf74a04d
commit 26ae9ab526
3 changed files with 100 additions and 92 deletions

View File

@ -5,7 +5,7 @@ from typing import BinaryIO
ROM_SIZE = 0x700
MAX_INT = 0x1000
MAX_IMMEDIATE = 0x80
MAX_IMMEDIATE = 0x40
class ConfigurationError(Exception): pass
@ -126,11 +126,9 @@ class Computer:
_running: bool
_halted: bool
_interrupt_flag: list[int]
_pc_last: int
_zero_flag: bool
_interruptable: bool
_negative_flag: bool
_pc: int
_sp: int
@ -145,11 +143,10 @@ class Computer:
self._running = True
self._halted = False
self._interrupt_flag = []
self._pc_last = 0
self._zero_flag = False
self._interruptable = False
self._negative_flag = False
self._pc = 0
self._sp = 0
@ -244,8 +241,10 @@ class Computer:
elif index == 6: self._d2 = value
elif index == 7: self._d3 = value
def interrupt(self, index: int):
self._interrupt_flag.append(index % MAX_INT)
def _update_flags(self, value: int):
value %= MAX_INT
self._zero_flag = value == 0
self._negative_flag = (value & 0x800) == 1
def step(self, verbose: bool = False):
instruction = self._mem[self.program_counter]
@ -258,17 +257,17 @@ class Computer:
if instruction == 0: self.NOP()
elif instruction == 1: self.HLT()
elif instruction == 2: self.INT()
elif instruction == 3: self.BNZ()
elif instruction == 4: self.BLK()
elif instruction == 5: self.ENB()
elif instruction & 0xFF8 == 0x10: self.GLA(instruction & 0x7)
elif instruction & 0xFF8 == 0x18: self.GET(instruction & 0x7)
elif instruction == 2: self.BNZ()
elif instruction == 3: self.BNA()
elif instruction == 4: self.BNP()
elif instruction == 5: self.BNN()
elif instruction & 0xFF8 == 0x20: self.LOD(instruction & 0x7)
elif instruction & 0xFF8 == 0x28: self.STR(instruction & 0x7)
elif instruction & 0xFF8 == 0x30: self.PSH(instruction & 0x7)
elif instruction & 0xFF8 == 0x38: self.POP(instruction & 0x7)
elif instruction & 0xF80 == 0x80: self.LDI(instruction & 0x7F)
elif instruction & 0xFF8 == 0x30: self.POP(instruction & 0x7)
elif instruction & 0xFF8 == 0x38: self.PSH(instruction & 0x7)
elif instruction & 0xFC0 == 0x40: self.LIU(instruction & 0x3F)
elif instruction & 0xFC0 == 0x80: self.LDI(instruction & 0x3F)
elif instruction & 0xFC0 == 0xC0: self.LIL(instruction & 0x3F)
elif instruction & 0xFC0 == 0x100:
self.LSH((instruction & 0x38) >> 3, instruction & 0x7)
elif instruction & 0xFC0 == 0x140:
@ -290,29 +289,29 @@ class Computer:
(instruction & 0x1C0) >> 6,
)
elif instruction & 0xE00 == 0x600:
self.NAD(
instruction & 0x7,
(instruction & 0x38) >> 3,
(instruction & 0x1C0) >> 6,
)
elif instruction & 0xE00 == 0x800:
self.SUB(
instruction & 0x7,
(instruction & 0x38) >> 3,
(instruction & 0x1C0) >> 6,
)
elif instruction & 0xE00 == 0xA00:
elif instruction & 0xE00 == 0x800:
self.XOR(
instruction & 0x7,
(instruction & 0x38) >> 3,
(instruction & 0x1C0) >> 6,
)
elif instruction & 0xE00 == 0xC00:
elif instruction & 0xE00 == 0xA00:
self.NOR(
instruction & 0x7,
(instruction & 0x38) >> 3,
(instruction & 0x1C0) >> 6,
)
elif instruction & 0xE00 == 0xC00:
self.NAD(
instruction & 0x7,
(instruction & 0x38) >> 3,
(instruction & 0x1C0) >> 6,
)
elif instruction & 0xE00 == 0xE00:
self.ADD(
instruction & 0x7,
@ -330,17 +329,19 @@ class Computer:
if instruction == 0: print("NOP")
elif instruction == 1: print("HLT")
elif instruction == 2: print("INT")
elif instruction == 3: print("BNZ")
elif instruction == 4: print("BLK")
elif instruction == 5: print("ENB")
elif instruction == 2: print("BNZ")
elif instruction == 3: print("BNA")
elif instruction == 4: print("BNP")
elif instruction == 5: print("BNN")
elif instruction & 0xFF8 == 0x10: print(f"GLA {instruction & 0x7}")
elif instruction & 0xFF8 == 0x18: print(f"GET {instruction & 0x7}")
elif instruction & 0xFF8 == 0x20: print(f"LOD {instruction & 0x7}")
elif instruction & 0xFF8 == 0x28: print(f"STR {instruction & 0x7}")
elif instruction & 0xFF8 == 0x30: print(f"PSH {instruction & 0x7}")
elif instruction & 0xFF8 == 0x38: print(f"POP {instruction & 0x7}")
elif instruction & 0xF80 == 0x80: print(f"LDI {instruction & 0x7F}")
elif instruction & 0xFF8 == 0x30: print(f"POP {instruction & 0x7}")
elif instruction & 0xFF8 == 0x38: print(f"PSH {instruction & 0x7}")
elif instruction & 0xFC0 == 0x40: print(f"LIU {instruction & 0x3F}")
elif instruction & 0xFC0 == 0x80: print(f"LDI {instruction & 0x3F}")
elif instruction & 0xFC0 == 0xC0: print(f"LIL {instruction & 0x3F}")
elif instruction & 0xFC0 == 0x100:
print(f"LSH {instruction & 0x7} {(instruction & 0x38) >> 3}")
elif instruction & 0xFC0 == 0x140:
@ -361,22 +362,22 @@ class Computer:
)
elif instruction & 0xE00 == 0x600:
print(
f"NAD {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"SUB {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"{(instruction & 0x38) >> 3}"
)
elif instruction & 0xE00 == 0x800:
print(
f"SUB {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"XOR {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"{(instruction & 0x38) >> 3}"
)
elif instruction & 0xE00 == 0xA00:
print(
f"XOR {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"NOR {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"{(instruction & 0x38) >> 3}"
)
elif instruction & 0xE00 == 0xC00:
print(
f"NOR {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"NAD {instruction & 0x7} {(instruction & 0x1C0) >> 6} "
f"{(instruction & 0x38) >> 3}"
)
elif instruction & 0xE00 == 0xE00:
@ -399,30 +400,24 @@ class Computer:
self._halted = True
self.program_counter += 1
def INT(self):
self.interrupt(self.pointer)
self.program_counter += 1
def BNZ(self):
if self.zero_flag:
self.program_counter = self.pointer
self.program_counter += 1
def BLK(self):
self._interruptable = False
def BNA(self):
if not self.zero_flag:
self.program_counter = self.pointer
self.program_counter += 1
def ENB(self):
self._interruptable = True
def BNP(self):
if not self._negative_flag:
self.program_counter = self.pointer
self.program_counter += 1
def GLA(self, REG: int):
self.set_reg(REG, self._pc_last)
self.program_counter += 1
def GET(self, REG: int):
if self._interrupt_flag: self.set_reg(REG, self._interrupt_flag.pop())
else: self.set_reg(REG, 0)
def BNN(self):
if self._negative_flag:
self.program_counter = self.pointer
self.program_counter += 1
def LOD(self, REG: int):
@ -433,92 +428,100 @@ class Computer:
self._mem[self.pointer] = self.get_reg(REG)
self.program_counter += 1
def POP(self, REG: int):
self._mem[self.stack_pointer] = self.get_reg(REG)
self.program_counter += 1
def PSH(self, REG: int):
self.set_reg(REG, self._mem[self.stack_pointer])
self.program_counter += 1
def POP(self, REG: int):
self._mem[self.stack_pointer] = self.get_reg(REG)
def LIU(self, Immediate: int):
self.pointer = (Immediate % MAX_IMMEDIATE) << 6
self.program_counter += 1
def LDI(self, Immediate: int):
self.pointer = Immediate % MAX_IMMEDIATE
self.program_counter += 1
def LIL(self, Immediate: int):
self.pointer |= (Immediate % MAX_IMMEDIATE)
self.program_counter += 1
def LSH(self, REG_D: int, REG_A: int):
result = self.get_reg(REG_A) << 1
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def RSH(self, REG_D: int, REG_A: int):
result = self.get_reg(REG_A) >> 1
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def INC(self, REG_D: int, REG_A: int):
result = self.get_reg(REG_A) + 1
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def DEC(self, REG_D: int, REG_A: int):
result = self.get_reg(REG_A) - 1
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def AND(self, REG_D: int, REG_A: int, REG_B: int):
result = self.get_reg(REG_A) & self.get_reg(REG_B)
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def OR(self, REG_D: int, REG_A: int, REG_B: int):
result = self.get_reg(REG_A) | self.get_reg(REG_B)
result %= MAX_INT
self._zero_flag = result == 0
self.set_reg(REG_D, result)
self.program_counter += 1
def NAD(self, REG_D: int, REG_A: int, REG_B: int):
result = (MAX_INT - 1) ^ (self.get_reg(REG_A) & self.get_reg(REG_B))
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def SUB(self, REG_D: int, REG_A: int, REG_B: int):
result = self.get_reg(REG_A) + ((MAX_INT - 1) ^ self.get_reg(REG_B)) + 1
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def XOR(self, REG_D: int, REG_A: int, REG_B: int):
result = self.get_reg(REG_A) ^ self.get_reg(REG_B)
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def NOR(self, REG_D: int, REG_A: int, REG_B: int):
result = (MAX_INT - 1) ^ (self.get_reg(REG_A) | self.get_reg(REG_B))
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def NAD(self, REG_D: int, REG_A: int, REG_B: int):
result = (MAX_INT - 1) ^ (self.get_reg(REG_A) & self.get_reg(REG_B))
result %= MAX_INT
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1
def ADD(self, REG_D: int, REG_A: int, REG_B: int):
result = self.get_reg(REG_A) + self.get_reg(REG_B)
result %= MAX_INT
self._zero_flag = result == 0
self._update_flags(result)
self.set_reg(REG_D, result)
self.program_counter += 1

View File

@ -5,7 +5,7 @@ from collections import namedtuple
from typing import TypeVar, Generic, Iterable, Sequence
INSTRUCTIONS_COUNT = 0x700
MAX_IMMEDIATE = 0x80
MAX_IMMEDIATE = 0x40
class AssemblerError(Exception): pass
class LinkerError(Exception): pass
@ -175,19 +175,21 @@ class Program:
instruction_set = {
"NOP": lambda *_: Instruction(0, 0, 0, 0),
"HLT": lambda *_: Instruction(0, 0, 0, 1),
"INT": lambda *_: Instruction(0, 0, 0, 2),
"BNZ": lambda *_: Instruction(0, 0, 0, 3),
"BLK": lambda *_: Instruction(0, 0, 0, 4),
"ENB": lambda *_: Instruction(0, 0, 0, 5),
"BNZ": lambda *_: Instruction(0, 0, 0, 2),
"BNA": lambda *_: Instruction(0, 0, 0, 3),
"BNP": lambda *_: Instruction(0, 0, 0, 4),
"BNN": lambda *_: Instruction(0, 0, 0, 5),
"GLA": lambda l, i: Instruction(0, 0, 2, reg1(l, i)),
"GET": lambda l, i: Instruction(0, 0, 3, reg1(l, i)),
"LOD": lambda l, i: Instruction(0, 0, 4, reg1(l, i)),
"STR": lambda l, i: Instruction(0, 0, 5, reg1(l, i)),
"PSH": lambda l, i: Instruction(0, 0, 6, reg1(l, i)),
"POP": lambda l, i: Instruction(0, 0, 7, reg1(l, i)),
"POP": lambda l, i: Instruction(0, 0, 6, reg1(l, i)),
"PSH": lambda l, i: Instruction(0, 0, 7, reg1(l, i)),
"LIU": lambda l, i: Instruction(0, 1, *immediate_value(l, i)),
"LDI": lambda l, i: immediate(l, i),
"LIL": lambda l, i: Instruction(0, 3, *immediate_value(l, i)),
"LSH": lambda l, i: Instruction(0, 4, *reg2(l, i)),
"RSH": lambda l, i: Instruction(0, 5, *reg2(l, i)),
@ -196,10 +198,10 @@ class Program:
"AND": lambda l, i: Instruction(1, *reg3(l, i)),
"OR": lambda l, i: Instruction(2, *reg3(l, i)),
"NAD": lambda l, i: Instruction(3, *reg3(l, i)),
"SUB": lambda l, i: Instruction(4, *reg3(l, i)),
"XOR": lambda l, i: Instruction(5, *reg3(l, i)),
"NOR": lambda l, i: Instruction(6, *reg3(l, i)),
"SUB": lambda l, i: Instruction(3, *reg3(l, i)),
"XOR": lambda l, i: Instruction(4, *reg3(l, i)),
"NOR": lambda l, i: Instruction(5, *reg3(l, i)),
"NAD": lambda l, i: Instruction(6, *reg3(l, i)),
"ADD": lambda l, i: Instruction(7, *reg3(l, i)),
}
@ -385,6 +387,18 @@ def reg3(line: str, line_number: int) -> tuple[int, int, int]:
raise AssemblerError(
f"Invalid number of arguments on line {line_number}: {args[0]}")
def immediate_value(line: str, line_number: int) -> tuple[int, int]:
args = line.split(' ')
if len(args) == 2:
value = int(args[1], base=0)
if value >= MAX_IMMEDIATE:
raise AssemblerError(
f"Immediate value too large {line_number}: {args[1]}")
return ((value & 0x038) >> 3, value & 0x007)
else:
raise AssemblerError(
f"Invalid number of arguments on line {line_number}: {args[0]}")
def immediate(line: str, line_number: int) -> Instruction | Immediate:
args = line.split(' ')
if len(args) == 2:

View File

@ -4,16 +4,6 @@
; .0x5
main:
; Load Output Device Address
ldi 0x7F
or D3 MP ZR
lsh D3 D3
lsh D3 D3
lsh D3 D3
lsh D3 D3
ldi 0xE
or D3 MP D3
; Initialize Fibonacci values
ldi 1
or D0 MP ZR
@ -22,7 +12,8 @@ main:
loop:
; Output current value
or MP D3 ZR
liu 0x1f
lil 0x3E
str D0
; Move values down