Create a gist now

Instantly share code, notes, and snippets.

@jcw /asm.py
Created Oct 21, 2017

What would you like to do?
# MCPU assembler, see https://github.com/cpldcpu/MCPU
# python asm.py <test.asm >test.obj
from __future__ import print_function
import sys
def valof(arg):
if arg in syms:
arg = syms[arg]
try:
return int(arg)
except:
return 0
# pseudo ops
def org(arg):
global pc
pc = valof(arg)
def dcb(arg):
global pc
mem[pc & 0x3F] = valof(arg)
pc += 1
# instruction set
def nor(arg): dcb(valof(arg) | 0x00)
def add(arg): dcb(valof(arg) | 0x40)
def sta(arg): dcb(valof(arg) | 0x80)
def jcc(arg): dcb(valof(arg) | 0xC0)
# combined instructions
def jcs(arg): jcc(pc+2); jcc(arg)
def jmp(arg): jcc(arg); jcc(arg)
def lda(arg): nor('allone'); add(arg)
def sub(arg): nor('zero'); add(arg); add('one')
def out(arg): dcb(0xFF)
code = sys.stdin.readlines()
syms = {}
for _ in range(2):
pc = 0
mem = 64 * [0]
for line in code:
fields = line.split()
if len(fields) > 0 and line[0] != '#':
if line.lstrip() == line:
syms[fields[0]] = pc
del fields[:1]
f = globals()[fields[0]]
f(fields[1])
s = '\n'
print(s.join([format(x, '02X') for x in mem]))
# MCPU emulator, see https://github.com/cpldcpu/MCPU
# python asm.py <... | python emu.py
# optional arg is # of cycles to run
# show instruction trace if cycles < 1000
from __future__ import print_function
import sys
try:
cycles = int(sys.argv[1])
except:
cycles = 20
mem = [int(x, 16) for x in sys.stdin.readlines()]
assert len(mem) == 64
pc, acc, cf = 0, 0, 0
for _ in range(cycles):
ir = mem[pc & 0x3F]
pc += 1
op, arg = ir >> 6, ir & 0x3F
if cycles < 1000:
print('pc,ir,acc,cf:', pc-1, hex(ir), acc, cf >> 8, sep='\t')
if op == 0:
acc = (acc | mem[arg]) ^ 0xFF
elif op == 1:
acc += mem[arg]
cf = acc & 0x100
acc &= 0xFF
elif op == 2:
mem[arg] = acc
else:
if ir == 0xFF:
print(acc)
elif cf == 0:
pc = arg
cf = 0
# MCPU prime number calculator, see https://github.com/cpldcpu/MCPU
# python asm.py <prime.asm | python emu.py 200000
org 61
zero dcb 0
allone dcb 255
one dcb 1
org 0
lda two
out *
start lda allone
add allone
sta subs
loop lda number
inner add subs
jcs inner
sub subs
add allone
jcc noprime
lda subs
add allone
sta subs
add number
add allone
jcs loop
lda number
out *
noprime lda number
add two
sta number
jmp start
two dcb 2
subs dcb 0
number dcb 3
# MCPU example test loop, see https://github.com/cpldcpu/MCPU
# python asm.py <test.asm | python emu.py
org 61
zero dcb 0
allone dcb 255
one dcb 1
org 0
lda count
cloop add one
jcc cloop
done jcc done
count dcb 250
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment