Skip to content

Commit

Permalink
V2.3.2, Singlethreaded and IO
Browse files Browse the repository at this point in the history
Many changes.
  • Loading branch information
LightslicerGP committed Nov 6, 2024
1 parent 5f9369e commit dabc884
Show file tree
Hide file tree
Showing 21 changed files with 1,539 additions and 69 deletions.
35 changes: 28 additions & 7 deletions Assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
line = ""
main_file.write(line)
print("constants:", constants) if debug else None
constants = dict(
sorted(constants.items(), key=lambda item: len(item[0]), reverse=True)
) # so when replacing it checks longest first in case like "set" gets checked before "reset"
print("constants sorted:", constants) if debug else None

# keep track of function names, and the line number, then delete the lines
(
Expand All @@ -78,15 +82,28 @@
line_number += 1
main_file.write(line)
print("jumps:", jumps) if debug else None
jumps = dict(
sorted(jumps.items(), key=lambda item: len(item[0]), reverse=True)
) # same reasoning as before
print("jumps sorted:", jumps) if debug else None

# Replace all constants names with their values
print("replacing all constants names with their values") if debug else None
with open("Instructions Compiled", "r") as instruction_file:
lines = instruction_file.readlines()
with open("Instructions Compiled", "w") as main_file:
for line in lines:
for key, value in constants.items():
line = line.replace(key, str(value))

if not line.lower().startswith(("cal", "jmp", "jiz")):
for key, value in constants.items():
line = line[:4] + line[4:].replace(key, str(value))

elif line.lower().startswith("jiz"):
split_line = line.split()
for key, value in constants.items():
split_line[1] = split_line[1].replace(key, str(value))
line = f"{split_line[0]} {split_line[1]} {split_line[2]}\n"

main_file.write(line)

# replace all function names with function line numbers
Expand All @@ -97,7 +114,7 @@
for line in lines:
if line.lower().startswith(("cal", "jmp", "jiz")):
for key, value in jumps.items():
line = line.replace(key, str(value))
line = line[:4] + line[4:].replace(key, str(value))
main_file.write(line)

# capitalize all opcodes
Expand Down Expand Up @@ -127,13 +144,17 @@
lines = instruction_file.readlines()
with open("Instructions Compiled", "w") as main_file:
for line in lines:
if line.startswith(("INC", "DEC", "RSH", "LSH", "INV", "LOD", "STR")): # two operands
if len(line.split()) == 2: # one opcode, only one operand
if line.startswith(
("INC", "DEC", "RSH", "LSH", "INV", "LOD", "STR", "SPD")
): # two operands
if len(line.split()) == 2: # one opcode, only one operand
fragments = line.split()
fragments.append(fragments[1])
line = " ".join(fragments) + "\n"
elif line.startswith(("ADD","SUB","MLT","DVS","SQA","SQR","ORR","AND","XOR")): # three operands
if len(line.split()) == 3: # one opcode, only 2 operands
elif line.startswith(
("ADD", "SUB", "MLT", "DVS", "SQA", "SQR", "ORR", "AND", "XOR")
): # three operands
if len(line.split()) == 3: # one opcode, only 2 operands
fragments = line.split()
fragments.append(fragments[1])
line = " ".join(fragments) + "\n"
Expand Down
37 changes: 20 additions & 17 deletions Display.py
Original file line number Diff line number Diff line change
@@ -1,37 +1,40 @@
import pygame
import RAM

pygame.init()
resolution = (256, 256)
scale = 4
width, height = resolution[0] * scale, resolution[1] * scale
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()

def init_display(scale):
resolutionX = 256
resolutionY = 256
width = resolutionX * scale
height = resolutionY * scale

def refresh():
pygame.init()
screen = pygame.display.set_mode((width, height))
# clock = pygame.time.Clock()
return screen


def update_display(screen, scale):
x = RAM.read(252, False)
y = RAM.read(253, False)
r = RAM.read(249, False)
g = RAM.read(250, False)
b = RAM.read(251, False)
mode = RAM.read(254)
if mode == 1:
# print("set color")
pixel_color = (r, g, b)
pixel_rect = pygame.Rect(x * scale, y * scale, scale, scale)
pygame.draw.rect(screen, pixel_color, pixel_rect)
elif mode == 2:
# print("reset color")
pixel_color = (0, 0, 0)
pixel_rect = pygame.Rect(x * scale, y * scale, scale, scale)
pygame.draw.rect(screen, pixel_color, pixel_rect)
elif mode == 3:
print("fill screen with color data")

def start():
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()

# print("fill color")
pixel_color = (r, g, b)
# pixel_rect = pygame.Rect(0, 0, 256 * scale, 256 * scale)
# pygame.draw.rect(screen, pixel_color, pixel_rect)
screen.fill(pixel_color)
RAM.write(254, 0, True)
99 changes: 54 additions & 45 deletions Excpute.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
# import Operations
import threading
# import threading
# import Display
import pygame
import re
import Display
import Port
import RAM
from Display import init_display, update_display
import Assembler # TEMP ASSEMBLY
import Keyboard # This imports the IO.py file, i dont want to but oh well 10/31/24

registers = [0] * 8


def display_start():
Display.start()


threading.Thread(target=display_start, daemon=True).start()
debug = False
print_registers = False

Expand Down Expand Up @@ -69,6 +67,10 @@ def flag_set(flag: str, sign: int):
raise ValueError("flag_write number must be 1 or 0")


global instruction_address
instruction_address = reg_read(7, False)


def next_instruction():
if instruction_address == 255:
reg_write(7, 0, False)
Expand Down Expand Up @@ -247,7 +249,7 @@ def lsh_op(regA, regDest, SetFlag):
if SetFlag == 1:
flag_set("carry", 1)
result = result - 256

reg_write(regDest, result, False)
next_instruction()

Expand Down Expand Up @@ -308,7 +310,7 @@ def psh_op(regA):
A = reg_read(regA, False)
stack_pointer = reg_read(5, False)
RAM.write(stack_pointer, A, False) # writes to stack
reg_write(5, reg_read(5, False) - 1, False) # "increments" (decrements) pointer
reg_write(5, stack_pointer - 1, False) # "increments" (decrements) pointer
next_instruction()


Expand Down Expand Up @@ -411,28 +413,16 @@ def spd_op(regA, property):
print(f"{instruction_address}: Set pixel data")
A = reg_read(regA, False)

property_mapping = {0: 249, 1: 250, 2: 251, 3: 252, 4: 253}

if property in property_mapping: # r, g, b, x, y
RAM.write(property_mapping[property], A, False)
elif property == 5:
RAM.write(254, 1) # set
Display.refresh()
elif property == 6:
RAM.write(254, 2) # reset
Display.refresh()
elif property == 7:
RAM.write(254, 3) # fill
Display.refresh()
if property < 5: # r, g, b, x, y
ram_address = property + 249 # 0 -> 249, 4 -> 253
RAM.write(ram_address, A, False)
elif property >= 5: # set, reset, fill
ram_data = property - 4 # 5 -> 1, 7 -> 3
RAM.write(254, ram_data, False)

next_instruction()


instruction_address = reg_read(7, False)
reg_write(7, 0, False) # set instruction address
reg_write(5, 248, False) # set stack address


instructions = {
"NOP": lambda: None,
"HLT": lambda: hlt_op(),
Expand Down Expand Up @@ -468,6 +458,7 @@ def spd_op(regA, property):
"SPD": lambda ra, pr: spd_op(ra, pr),
}


def get_instructions(file):
with open(file, "r") as instruction_file:
lines = instruction_file.readlines()
Expand All @@ -480,31 +471,49 @@ def get_instructions(file):
]
return instruction_array

program = get_instructions("Instructions Compiled")

if debug:
print(program)

while instruction_address < 256:
try:
def update_cpu(program):
global instruction_address
if instruction_address < 256:
instruction = program[instruction_address]
except IndexError:

op = instruction[0].upper()
args = instruction[1:]

instructions[op](*args)

if debug or print_registers:
print(registers)

instruction_address = reg_read(7, False)
else:
print("Ran out of instructions, halted automatically")
if debug:
print("Instruction address:", instruction_address)
exit()
op = instruction[0].upper()
args = instruction[1:]

instructions[op](*args)
if debug or print_registers:
print(registers)

instruction_address = reg_read(7, False)
scale = 4
renderer = init_display(scale)

program = get_instructions("Instructions Compiled")
reg_write(7, 0, False) # set instruction address
reg_write(5, 248, False) # set stack address

if debug:
print(program)

running = True

while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
Port.hardware(event) # for keuybaorrd stfufusuhfaahhfsiuiuh 10/31/24
pygame.display.flip()

update_cpu(program)

update_display(renderer, scale)

events = pygame.event.get()
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_0:
exit()
pygame.quit()
95 changes: 95 additions & 0 deletions Keyboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import Port
import pygame

# Mapping keys to their respective bitmasks
# key_bitmasks = {
# pygame.K_w: 0b10000000,
# pygame.K_a: 0b01000000,
# pygame.K_s: 0b00100000,
# pygame.K_d: 0b00010000,
# pygame.K_UP: 0b00001000,
# pygame.K_LEFT: 0b00000100,
# pygame.K_DOWN: 0b00000010,
# pygame.K_RIGHT: 0b00000001,
# }

key_bitmasks = {
pygame.K_SPACE: [0, 0b10000000],
pygame.K_BACKQUOTE: [0, 0b01000000],
pygame.K_1: [0, 0b00100000],
pygame.K_2: [0, 0b00010000],
pygame.K_3: [0, 0b00001000],
pygame.K_4: [0, 0b00000100],
pygame.K_5: [0, 0b00000010],
pygame.K_6: [0, 0b00000001],
pygame.K_7: [1, 0b10000000],
pygame.K_8: [1, 0b01000000],
pygame.K_9: [1, 0b00100000],
pygame.K_0: [1, 0b00010000],
pygame.K_MINUS: [1, 0b00001000],
pygame.K_EQUALS: [1, 0b00000100],
pygame.K_q: [1, 0b00000010],
pygame.K_w: [1, 0b00000001],
pygame.K_e: [2, 0b10000000],
pygame.K_r: [2, 0b01000000],
pygame.K_t: [2, 0b00100000],
pygame.K_y: [2, 0b00010000],
pygame.K_u: [2, 0b00001000],
pygame.K_i: [2, 0b00000100],
pygame.K_o: [2, 0b00000010],
pygame.K_p: [2, 0b00000001],
pygame.K_LEFTBRACKET: [2, 0b00000001],
pygame.K_RIGHTBRACKET: [3, 0b10000000],
pygame.K_BACKSLASH: [3, 0b00100000],
pygame.K_a: [3, 0b00010000],
pygame.K_s: [3, 0b00001000],
pygame.K_d: [3, 0b00000100],
pygame.K_f: [3, 0b00000010],
pygame.K_g: [3, 0b00000001],
pygame.K_h: [4, 0b10000000],
pygame.K_j: [4, 0b01000000],
pygame.K_k: [4, 0b00100000],
pygame.K_l: [4, 0b00010000],
pygame.K_SEMICOLON: [4, 0b00001000],
pygame.K_QUOTE: [4, 0b00000100],
pygame.K_z: [4, 0b00000010],
pygame.K_x: [4, 0b00000001],
pygame.K_c: [5, 0b10000000],
pygame.K_v: [5, 0b01000000],
pygame.K_b: [5, 0b00100000],
pygame.K_n: [5, 0b00010000],
pygame.K_m: [5, 0b00001000],
pygame.K_COMMA: [5, 0b00000100],
pygame.K_PERIOD: [5, 0b00000010],
pygame.K_SLASH: [5, 0b00000001],
pygame.K_BACKSPACE: [6, 0b10000000],
pygame.K_TAB: [6, 0b01000000],
pygame.K_RETURN: [6, 0b00100000],
pygame.K_LSHIFT: [6, 0b00010000], # Combined Shift
pygame.K_RSHIFT: [6, 0b00010000], # Combined Shift
pygame.K_UP: [6, 0b00001000],
pygame.K_LEFT: [6, 0b00000100],
pygame.K_DOWN: [6, 0b00000010],
pygame.K_RIGHT: [6, 0b00000001],
pygame.K_CAPSLOCK: [7, 0b10000000],
pygame.K_LCTRL: [7, 0b01000000], # Combined Control
pygame.K_RCTRL: [7, 0b01000000], # Combined Control
pygame.K_LALT: [7, 0b00010000], # Combined Alt
pygame.K_RALT: [7, 0b00010000], # Combined Alt
pygame.K_ESCAPE: [7, 0b00001000],
pygame.K_PRINTSCREEN: [8, 0b00000100],
pygame.K_INSERT: [8, 0b00000010],
pygame.K_DELETE: [8, 0b00000001],
}


def handle_key_event(event):
if event.type == pygame.KEYDOWN:
if event.key in key_bitmasks:
index, bitmask = key_bitmasks[event.key]
Port.Ports[index] ^= bitmask # Use the index and bitmask

elif event.type == pygame.KEYUP:
if event.key in key_bitmasks:
index, bitmask = key_bitmasks[event.key]
Port.Ports[index] &= ~bitmask # Use the index and bitmask
Loading

0 comments on commit dabc884

Please sign in to comment.