-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAssemblerJuggernautUpdated(7)
184 lines (164 loc) · 6.72 KB
/
AssemblerJuggernautUpdated(7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# This is the Assembler for the Juggernaut CPU in Minecraft
# Build by Jobe, WildScaryFox, JediZach, Saturnxcode, Tarmalot and Death_Slice
# Code written by Jobe
# Imports
import sys
import time as t
# Prefixes
# $ -> Register Address
# @ -> Ram Address
# & -> I/O Port Address
# / -> No Operand in that position
# Numbers are an Immediate unless they have a Prefix
# ISA OpCodeList
op_code_list = {
'nop': '0', 'add': '1', 'sub': '2', 'nota': '3', 'neg': '4','mp': '5', 'nimp': '6', 'and': '7',
'or': '8','xor': '9','nand': '10', 'nor': '11', 'xnor': '12', 'bsu': '13', 'bsd': '14','bsur': '15',
'bsdr': '16','addca': '17', 'jmp': '18','branch': '19', 'jmpr': '20', 'branchr': '21','ldi': '22','mov': '23',
'rldi': '24','str': '25','ldr': '26','pin': '27','pout': '28','pinr': '29','poutr': '30','incr': '31',
'decr': '32','mult': '33','div': '34','mod': '35','sqr': '36','sqrt': '37','cmpr': '38','lflgre': '39',
'lflgra': '40','lpre': '41','rpre': '42','lpra': '43','rpra': '44','psh': '45','pop': '46','call': '47',
'rtrn': '48','rnd': '49','swp': '50','': '51','': '52','': '53','': '54','': '55',
'': '56','': '57','': '58','': '59','': '60','': '61','stl': '62','hlt': '63',
}
# Main
max_lines = 0
input_a = 0
stop = 0
input_lines = [] # Initialize an empty list to hold the input lines
# Talks to the user
def talk():
print()
print("| This is the Assembler for the Juggernaut CPU, made entirely in Minecraft.")
print("| Juggernaut has been built by: Jobe, WildScaryFox, JediZach, Saturnxcode, Tarmalot and Death_Slice")
print()
t.sleep(.5)
print("How many Lines of Code do you need (the maximum is 65536 lines):")
# Take input from user and convert str to int
def LineNumber():
global input_a
try:
input_a = int(input())
return
except ValueError:
print()
print("That is not a Number")
print("Please try again")
LineNumber()
talk()
LineNumber()
def check_line():
global stop
# Checks whether the number of lines is allowed
if input_a > 65536:
print()
print("The number", input_a, "is above the limit of 65536")
stop += 1
return
elif input_a < 0:
print()
print("The number", input_a, "is negative")
stop += 1
return
else:
stop = 0
check_line()
# Helper function to convert operand to binary
def operand_to_binary(operand):
value =int(operand[1:])
try:
if 0 <= value <255:
if operand.startswith('$'):
# Assuming register addresses are in the form $0, $1, ..., $15 and need to be 4-bit binary -> first 4 bits of reg will always be 0000XXXX
return format(int(operand[1:]), '08b')
elif operand.startswith('@'):
# Assuming RAM needs to be treated as immediate values
return format(int(operand[1:]), '08b')
elif operand.startswith('&'):
# Assuming IO needs to be treated as immediate values
return format(int(operand[1:]), '08b')
elif operand.startswith("/"):
# If there is no Operand needed in Line
return "00000000"
elif operand.isdigit():
# immediate
return format(int(operand), '08b')
else:
print(f"Unknown Operand format in {operand}")
elif value > 255:
print(f"The Operand {value} is bigger than 255.")
elif value < 0:
print(f"The Operand {value} is smaller than 0.")
except ValueError as e:
print(f"Error assembling line {index}: {e}")
def display_inputs(inputs):
# Function to display current inputs
print("\nCurrent Inputs:")
for index, line in enumerate(inputs, start=+1):
print(f"{index}: {line}")
print()
def assemble(input_lines):
for index, line in enumerate(input_lines, start=1):
tokens = line.split()
if tokens:
opcode = tokens[0]
operands = tokens[1:]
if opcode in op_code_list:
try:
binary_opcode = format(int(op_code_list[opcode]), '08b')
binary_operands = [operand_to_binary(op) for op in operands]
# Combine the binary parts
final_binary_instruction = binary_opcode + ''.join(binary_operands)
# Format the final binary instruction to be 4 8-bit strings
formatted_instruction = ' '.join(final_binary_instruction[i:i+8] for i in range(0, len(final_binary_instruction), 8))
print(formatted_instruction)
except ValueError as e:
print(f"Error assembling line {index}: {e}")
else:
print(f"Unknown opcode: '{opcode}'")
return()
print("You can now copy this into the Schematic Generator")
if stop == 0:
print()
print("The ISA:")
print()
print("\n".join(op_code_list.keys()))
print()
print("Please enter up to", input_a, "lines of input (Press Enter twice to finish early):")
for i in range(1, input_a + 1): # Read up to 65536 lines of input from the Terminal
try:
line = input(f"{i} | ")
if line == "":
break
input_lines.append(line)
except EOFError:
break
for index, line in enumerate(input_lines, start=1):
# Assign each line to a new variable
globals()[f"line_{index}"] = line
print("Here is the code you wrote (To verify):")
print()
# Print the variables to verify
for index in range(1, len(input_lines)+1):
print(f"line {index}:", globals()[f"line_{index}"])
while True:
print("Press Enter to continue or press # to stop and edit the Code.")
action = input().strip()
if action == "": # Check if the input is the Enter key (empty string)
print("Enter key detected, Assembling your Code.")
assemble(input_lines)
break
elif action == "#":
print("# key detected, you can now edit your Code")
display_inputs(input_lines)
edit_index = input("Enter the line number to edit (or 'c' to continue): ").strip()
if edit_index.lower() == 'c':
continue
elif edit_index.isdigit() and 1 <= int(edit_index) <= len(input_lines):
new_input = input(f"Edit line {edit_index}: ")
input_lines[int(edit_index) - 1] = new_input
display_inputs(input_lines)
else:
print("Invalid line number.")
else:
print("Invalid input, please press Enter to continue or # to edit the Code.")