Last active
October 14, 2016 18:00
-
-
Save nonchip/80b2971b827d2cd234b3f62848629df0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RAM, BankSwitcher from require 'ram' | |
ops=require 'ops' | |
rom=require 'rom' | |
eprint=(...)-> | |
for i in *{...} | |
io.stderr\write i..'\t' | |
io.stderr\write '\n' | |
bank1 = RAM! | |
bank2 = RAM! | |
bank3 = RAM! | |
switcher = BankSwitcher { bank1, bank2, bank3 } | |
regs = { running: true, ip: 0, a: 0, b: 0, c: 0, d: 0 } | |
eprint 'loading rom:' | |
da=0 | |
if rom[0]==nil then | |
eprint 'starts at 1, fixing...' | |
da=1 | |
for a=0,#rom-da | |
v=rom[a+da] or 0 | |
eprint '%02X: %02X'\format a, v | |
bank1\set a, v | |
bool2tf = (bool) -> bool and 'T' or 'F' | |
eprint 'RUN\tIP\tOPCODE\tA\tB\tC\tD' | |
while regs.running and regs.ip < 256 | |
opcode = switcher\get regs.ip | |
eprint '%s\t%02X\t%02X\t%02X\t%02X\t%02X\t%02X'\format bool2tf(regs.running), regs.ip, opcode,regs.a,regs.b,regs.c,regs.d | |
op=ops[opcode] | |
if op | |
op regs, switcher | |
else | |
regs.running=false | |
eprint '%02X.%02X: INVALID OPCODE %02X'\format switcher\getBank!, regs.ip, opcode | |
eprint '%s\t%02X\tHALTED\t%02X\t%02X\t%02X\t%02X'\format bool2tf(regs.running), regs.ip,regs.a,regs.b,regs.c,regs.d |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
bit = require 'bit' | |
loadRfromR=(t,f)-> | |
(regs,ram) -> | |
regs[t]=regs[f] | |
regs.ip+=1 | |
loadRfromV=(t)-> | |
(regs,ram) -> | |
regs[t]=ram\get regs.ip+1 | |
regs.ip+=2 | |
{ | |
-- 0x0 general | |
[0x00]: (regs,ram)-> --nop | |
regs.ip += 1 | |
[0x01]: (regs,ram)-> --halt | |
regs.running = false | |
[0x02]: (regs,ram)-> --JMP val | |
regs.ip=ram\get regs.ip+1 | |
[0x03]: (regs,ram)-> --JMP val if A | |
if regs.a>0 | |
regs.ip=ram\get regs.ip+1 | |
else | |
regs.ip=regs.ip+2 | |
[0x04]: (regs,ram)-> --JMP val if !A | |
if regs.a==0 | |
regs.ip=ram\get regs.ip+1 | |
else | |
regs.ip=regs.ip+2 | |
[0x05]: (regs,ram)-> --JMP val if A==1 | |
if regs.a==1 | |
regs.ip=ram\get regs.ip+1 | |
else | |
regs.ip=regs.ip+2 | |
[0x06]: (regs,ram)-> --JMP A | |
regs.ip=regs.b | |
[0x07]: (regs,ram)-> --JMP B | |
regs.ip=regs.b | |
[0x08]: (regs,ram)-> --JMP B if A | |
if regs.a>0 | |
regs.ip=regs.b | |
else | |
regs.ip=regs.ip+1 | |
[0x09]: (regs,ram)-> --JMP B if !A | |
if regs.a==0 | |
regs.ip=regs.b | |
else | |
regs.ip=regs.ip+1 | |
[0x0a]: (regs,ram)-> --JMP B if A==1 | |
if regs.a==1 | |
regs.ip=regs.b | |
else | |
regs.ip=regs.ip+1 | |
-- 0x1 LOAD: | |
[0x10]: loadRfromV 'a' | |
[0x11]: loadRfromR 'a', 'b' | |
[0x12]: loadRfromR 'a', 'c' | |
[0x13]: loadRfromR 'a', 'd' | |
[0x14]: loadRfromR 'b', 'a' | |
[0x15]: loadRfromV 'b' | |
[0x16]: loadRfromR 'b', 'c' | |
[0x17]: loadRfromR 'b', 'd' | |
[0x18]: loadRfromR 'c', 'a' | |
[0x19]: loadRfromR 'c', 'b' | |
[0x1a]: loadRfromV 'c' | |
[0x1b]: loadRfromR 'c', 'd' | |
[0x1c]: loadRfromR 'd', 'a' | |
[0x1d]: loadRfromR 'd', 'b' | |
[0x1e]: loadRfromR 'd', 'c' | |
[0x1f]: loadRfromV 'd' | |
-- 0x2 IO: | |
[0x20]: (regs,ram)-> -- READ A, [val] | |
regs.a=ram\get ram\get regs.ip+1 | |
regs.ip+=2 | |
[0x21]: (regs,ram)-> -- READ A, [B] | |
regs.a=ram\get regs.b | |
regs.ip+=1 | |
[0x22]: (regs,ram)-> -- WRITE [val], A | |
ram\set ram\get(regs.ip+1), regs.a | |
regs.ip+=2 | |
[0x23]: (regs,ram)-> -- WRITE [B], A | |
ram\set regs.b, regs.a | |
regs.ip+=1 | |
[0x24]: (regs,ram)-> -- READ A, stdin | |
regs.a=string.byte io.read(1) | |
regs.ip+=1 | |
[0x25]: (regs,ram)-> -- WRITE stdout, A | |
io.write(string.char regs.a) | |
regs.ip+=1 | |
-- 0x3 MATH: | |
[0x30]: (regs,ram)-> -- ADD A, val | |
regs.a+=ram\get regs.ip+1 | |
regs.ip+=2 | |
[0x31]: (regs,ram)-> -- ADD A, B | |
regs.a+=regs.b | |
regs.ip+=1 | |
[0x32]: (regs,ram)-> -- MUL A, val | |
regs.a*=ram\get regs.ip+1 | |
regs.ip+=2 | |
[0x33]: (regs,ram)-> -- MUL A, B | |
regs.a*=regs.b | |
regs.ip+=1 | |
[0x34]: (regs,ram)-> -- AND A, val | |
regs.a=bit.band regs.a, ram\get regs.ip+1 | |
regs.ip+=2 | |
[0x35]: (regs,ram)-> -- AND A, B | |
regs.a=bit.band regs.a, regs.b | |
regs.ip+=1 | |
[0x36]: (regs,ram)-> -- OR A, val | |
regs.a=bit.bor regs.a, ram\get regs.ip+1 | |
regs.ip+=2 | |
[0x37]: (regs,ram)-> -- OR A, B | |
regs.a=bit.bor regs.a, regs.b | |
regs.ip+=1 | |
[0x38]: (regs,ram)-> -- NOT A | |
regs.a=bit.bnot regs.a | |
regs.ip+=1 | |
[0x39]: (regs,ram)-> -- XOR A, val | |
regs.a=bit.bxor regs.a, ram\get regs.ip+1 | |
regs.ip+=2 | |
[0x3a]: (regs,ram)-> -- XOR A, B | |
regs.a=bit.bxor regs.a, regs.b | |
regs.ip+=1 | |
-- 0x4 CMP: | |
[0x40]: (regs,ram)-> -- A=CMP A, B (0<,1=,2>) | |
regs.a=((regs.a<regs.b) and 0) or ((regs.a>regs.b) and 2) or 1 | |
regs.ip+=1 | |
[0x41]: (regs,ram)-> -- A=CMP A, val (0<,1=,2>) | |
v=ram\get regs.ip+1 | |
regs.a=((regs.a<v) and 0) or ((regs.a>v) and 2) or 1 | |
regs.ip+=2 | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ffi = require 'ffi' | |
class RAM | |
new: (@size=256, @type='unsigned char') => | |
@mem = ffi.new @type..'[?]', @size | |
get: (addr) => | |
return nil, 'out of bounds' if addr < 0 or addr >= @size | |
tonumber(@mem[addr]) | |
set: (addr, val) => | |
return nil, 'out of bounds' if addr < 0 or addr >= @size | |
@mem[addr] = ffi.cast @type, tonumber(val) | |
true | |
class BankSwitcher | |
new: (@banks,@bank=0) => | |
get: (addr) => | |
@banks[@bank+1]\get addr | |
set: (addr, val) => | |
@banks[@bank+1]\set addr, val | |
switch: (@bank) => | |
true | |
getBank: => | |
@bank | |
{ :RAM, :BankSwitcher } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
STR= => @byte(1,#@) | |
{ | |
0x15, 0x13 -- 00: LOAD B, 0x13 | |
0x02, 0x05 -- 02: JMP 0x05 | |
0x01 -- 04: HCF | |
0x21 -- 05: READ A, [B] | |
0x18 -- 06: LOAD C, A | |
0x41, 0x00 -- 07: CMP A, 0 | |
0x05, 0x04 -- 09: =JMP 0x04 | |
0x12 -- 0b: LOAD A, C | |
0x25 -- 0c: WRITE stdout, A | |
0x11 -- 0d: LOAD A, B | |
0x30, 1 -- 0e: ADD A, 1 | |
0x14 -- 10: LOAD B, A | |
0x02, 0x05 -- 11: JMP 0x05 | |
STR 'Hello World.\n' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment