Skip to content

Instantly share code, notes, and snippets.

@v4lli
Created October 27, 2017 21:28
Show Gist options
  • Save v4lli/5d2d05353f22034aa20e2c4ff21cb381 to your computer and use it in GitHub Desktop.
Save v4lli/5d2d05353f22034aa20e2c4ff21cb381 to your computer and use it in GitHub Desktop.
Simple assembler to generate bytecode from asm text instructions for a custom-built microprocessor
#!/usr/bin/env python3
#
# Valentin Dornauer <valentin@unimplemented.org>
# Sun Dec 11 22:11:27 CET 2016
#
# Simple assembler to generate bytecode from asm
# text instructions for a custom-built microprocessor.
#
# Usage: tiasm.py <input_file>
# Example programm (multiplication 5*3):
#
# # erster faktor: 5
# LDA #5
# STA 14
# STA 13
# # zweiter faktor: 3
# LDA #3
# STA 15
# SUB #1
# STA 15
# BRZ #6
# LDA 13
# ADD 14
# STA 13
# LDA 15
# JMP 5
# NOP
# NOP
# NOP
import sys
import re
def generate_mword(lower, upper):
return lower | upper << 4
def ascii2mword(input):
match = re.match(r"^([A-Za-z]+)\s*([#~]?)([0-9]*)$", input)
if not match:
print("# ERROR: don't know what to do with '%s'", input)
return 0
opcode = match.group(1).upper()
is_immediate = len(match.group(2)) > 0
try:
immediate_value = int(match.group(3))
except ValueError:
immediate_value = None
if opcode == "NOP":
return 0
elif opcode == "LDA":
return generate_mword(0b0001 if is_immediate else 0b0010,
immediate_value)
elif opcode == "STA":
return generate_mword(0b0011, immediate_value)
elif opcode == "ADD":
return generate_mword(0b0100 if is_immediate else 0b0101,
immediate_value)
elif opcode == "SUB":
return generate_mword(0b0110 if is_immediate else 0b0111,
immediate_value)
elif opcode == "JMP":
return generate_mword(0b1000, immediate_value)
elif opcode == "BRZ":
return generate_mword(0b1001, immediate_value)
elif opcode == "BRC":
return generate_mword(0b1010, immediate_value)
elif opcode == "BRN":
return generate_mword(0b1011, immediate_value)
else:
print("# ERROR: Unknown instruction %s" % opcode)
return 0
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: tiasm.py <input_file>")
input_file = sys.argv[1]
with open(input_file) as fh:
for line in fh.readlines():
if line.startswith("#"):
continue
mword = ascii2mword(line.rstrip())
print("# %s" % line.rstrip())
print("{0:08b}".format(mword))
@v4lli
Copy link
Author

v4lli commented Oct 27, 2017

Output for example program:

# LDA #5
01010001
# STA 14
11100011
# STA 13
11010011
# LDA #3
00110001
# STA 15
11110011
# SUB #1
00010110
# STA 15
11110011
# BRZ #6
01101001
# LDA 13
11010010
# ADD 14
11100101
# STA 13
11010011
# LDA 15
11110010
# JMP 5
01011000
# NOP
00000000
# NOP
00000000
# NOP
00000000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment