Skip to content

Completed run(self): #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
126 changes: 109 additions & 17 deletions ls8/cpu.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,63 @@
# cpu.py

"""CPU functionality."""

import sys
import os

class CPU:
"""Main CPU class."""

def __init__(self):
"""Construct a new CPU."""
pass

def load(self):
# Set RAM
self.ram = [0] * 256
# Create registers: R0 - R6 empty
self.reg = [0] * 8
# R7 set to 0xF4
self.reg[7] = 0xF4

# Set program counter to 0
self.pc = 0
# Set flags to 0
self.fl = 0
# Memory Address Register, holds the memory address we're reading or writing
self.mar = 0
# #Memory Data Register, holds the value to write or the value just read
self.mdr = 0
# Points to the register that contains address of stack pointer
self.sp = 7

def load(self, file_name):
"""Load a program into memory."""

address = 0

# For now, we've just hardcoded a program:

program = [
# From print8.ls8
0b10000010, # LDI R0,8
0b00000000,
0b00001000,
0b01000111, # PRN R0
0b00000000,
0b00000001, # HLT
]
program = []
self.reg[self.sp] = len(self.ram) - 1

input_text = os.path.join(os.path.dirname(__file__), f"examples/{file_name}")

try:
with open(input_text) as my_file:
for line in my_file:
comment_split = line.split('#')
possible_binary_number = comment_split[0]

try:
x = int(possible_binary_number, 2)
# print("{:08b}: {:d}".format(x, x))
program.append(x)
except:
print(f"Failed to cast {possible_binary_number} to an int")
continue
except:
print(f"File: {file_name} not found...")

for instruction in program:
self.ram[address] = instruction
address += 1



def alu(self, op, reg_a, reg_b):
"""ALU operations."""

Expand All @@ -40,6 +67,12 @@ def alu(self, op, reg_a, reg_b):
else:
raise Exception("Unsupported ALU operation")

def ram_read(self, mar):
return self.ram[mar]

def ram_write(self, mar, mdr):
self.ram[mar] = mdr

def trace(self):
"""
Handy function to print out the CPU state. You might want to call this
Expand All @@ -62,4 +95,63 @@ def trace(self):

def run(self):
"""Run the CPU."""
pass

running = True
ldi = 0b10000010
prn = 0b01000111
hlt = 0b00000001
mul = 0b10100010
push = 0b01000101
pop = 0b01000110
call = 0b01010000
ret = 0b00010001

while running:
# print(self.pc)
command_to_execute = self.ram_read(self.pc)
op_a = self.ram_read(self.pc + 1)
op_b = self.ram_read(self.pc + 2)

if command_to_execute == ldi:
print("LDI executed")
self.reg[op_a] = self.pc + 2
self.pc += (command_to_execute >> 6) + 1
elif command_to_execute == prn:
print("Print executed")
print(self.reg[op_a])
self.pc += (command_to_execute >> 6) + 1
elif command_to_execute == mul:
print("Mult executed")
print(op_a, op_b)
self.reg[op_a] *= self.reg[op_b]
self.pc += (command_to_execute >> 6) + 1
elif command_to_execute == hlt:
print("Halt executed")
running = False
elif command_to_execute == push:
self.reg[self.sp] -= 1
register_to_get_value_in = self.ram[self.pc + 1]
value_in_register = self.reg[register_to_get_value_in]
self.ram[self.reg[self.sp]] = value_in_register
print(f"Pushing: {value_in_register}")
self.pc += (command_to_execute >> 6) + 1
elif command_to_execute == pop:
register_to_pop_value_in = self.ram[self.pc + 1]
self.reg[register_to_pop_value_in] = self.ram[self.reg[self.sp]]
self.reg[self.sp] += 1
print(f"Popping: {self.reg[register_to_pop_value_in]}")
self.pc += (command_to_execute >> 6) + 1
elif command_to_execute == call:
self.reg[self.sp] -= 1
address_of_next_instruction = self.pc + 2
self.ram[self.reg[self.sp]] = address_of_next_instruction
register_to_get_address_from = self.ram[self.pc + 1]
self.pc = self.reg[register_to_get_address_from]
elif command_to_execute == ret:
self.pc = self.ram[self.reg[self.sp]]
self.reg[self.sp] += 1
else:
print(f"Unkown command: {command_to_execute}")
self.pc += (command_to_execute >> 6) + 1

self.trace()
5 changes: 2 additions & 3 deletions ls8/ls8.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@
from cpu import *

cpu = CPU()

cpu.load()
cpu.run()
cpu.load("call.ls8") #fileNameFromCommandLine
cpu.run()