Skip to content

Instantly share code, notes, and snippets.

@tangentstorm
Created July 26, 2015 18:16
Show Gist options
  • Save tangentstorm/5ad567bad8c239afa3c0 to your computer and use it in GitHub Desktop.
Save tangentstorm/5ad567bad8c239afa3c0 to your computer and use it in GitHub Desktop.
# a tiny assembler
module 'asm'
imports [ 'vm', 'mr' ], ->
# instruction formats:
fm0 = 0
fm1 = 1 << 30
fm2 = 2 << 30
fm3 = 3 << 30
# modifier flags:
u = 1 << 29
v = 1 << 28
op =(n)-> n << 16
instruction =
MOV : op( 0 )
AND : op( 1 )
IOR : op( 2 )
XOR : op( 3 )
LSL : op( 4 )
ASR : op( 5 )
ADD : op( 8 )
SUB : op( 9 )
MUL : op( 10 )
DIV : op( 11 )
MOD : op( 11 ) + v
CMP : op( 12 )
jmpcond = # jump when:
JMI : op( 0 ) # ... negative ("minus", since NE is for not equal) (N)
JEQ : op( 1 ) # ... equal (zero)
JCS : op( 2 ) # ... carry bit set
JVS : op( 3 ) # ... overflow bit set
JLT : op( 4 ) # ... less than (Z or not C)
JLS : op( 5 ) # ... less than or same (n isnt v)
JLE : op( 6 ) # ... less or equal ((n isnt v) or z)
JMP : op( 7 ) # always (unconditional jump)
# and the reverse:
JPL : op( 8 ) # ... positive ("plus", to match with "minus")
JNE : op( 9 ) # ... not equal
JCC : op( 10 ) # ... carry bit C clear
JVC : op( 11 ) # ... overflow bit Z clear
JHI : op( 12 ) # ... high (C bit clear and not Z bit set)
JGE : op( 13 ) # ... greater or equal
JGT : op( 14 ) # ... greater than
NOP : op( 15 ) # never (so do nothing / waste a cycle)
vm = new $vm.RISC()
echo vm.R
rhs = $jq '#rhs'
rhs.html ''
EOT = '\x03'
[DC, DV, IP, SP, SS]=[0..4]
class Assembler
constructor:(@code)->
@PC : 0 # program cursor
@AC = 0
@OP = null
@next_ch()
emit:(op, a, b, c)->
@OP = [ op, a, b, c ]
next:()->
switch @CH
when EOT
@emit vm.op.end
when '!'
@consume '!'
@emit vm.op.wno, @read_reg()
next_ch:()->
if @AC is @code.length
then @CH = EOT
else @CH = @code[@AC]
@AC++
consume:(ch)->
unless ch is undefined or @CH is ch
throw "expected '#{ch}' but found '#{@CH}' at position #{@AC}"
@next_ch()
read_reg:()->
@consume 'R'
switch @CH
when '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
reg = parseInt "0x" + @CH
else
throw "invalid register at position #{PC}: #{code[PC]}"
@consume @CH
return reg
asm = new Assembler "!R0"
tick =->
asm.next()
console.log asm.OP
vm.perform asm.OP
asm_reg = ->
res ='R' + asm.code[asm.PC]
asm.PC += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment