REBOL[ Title: "Tiny Emulator" Date: 24-April-2007 File: %timy_emulator.r Author: "Tim Wylie" Purpose: "Emulator for tiny machine code." ] tiny-emulator: make object![ bytes: 900 memory: array/initial bytes 0 cpu-running: false program-counter: 0 accumulator: 0 stack-pointer: 900 instruction-register: 0 get-opcode: func[x[string!]][to-integer (copy/part x 2)] get-operand: func[x[string!]][to-string reverse(copy/part reverse x 3)] get-memory: func[x[integer!]][x: x + 1 memory/:x] set-memory: func[x[integer!] str][x: x + 1 memory/:x: to-string str ] read-file: func[file[file!]][ tnc: read/lines file foreach line tnc[ if find line "*" [break] codes: parse line "," cell: (to-integer first codes) + 1 memory/:cell: to-string (second codes) ] ] boot: does[ cpu-running: true while[cpu-running = true][ opcode: get-opcode to-string (pick memory (to-integer program-counter + 1)) operand: get-operand to-string (pick memory (to-integer program-counter + 1)) switch/default opcode [ 0[cpu-running: false] ;stop 1[accumulator: get-memory (to-integer operand)];ld x 2[accumulator: get-memory to-integer (get-memory (to-integer operand)) ];ldi x; 3[accumulator: operand];lda x 4[set-memory (to-integer operand) accumulator];st x 5[set-memory (to-integer (get-memory to-integer operand) accumulator)];stix 6[accumulator: (to-integer accumulator) + (to-integer (get-memory (to-integer operand)))] ;add x 7[accumulator: (to-integer accumulator) - (to-integer (get-memory (to-integer operand)))] ;sub x 8[accumulator: (to-integer accumulator) * (to-integer (get-memory (to-integer operand)))] ;mul x 9[accumulator: (to-integer accumulator) / (to-integer (get-memory (to-integer operand)))] ;div x 10[if char: (pick input 1) <> none[accumulator: to-integer char]] ;in 11[prin accumulator] ;out 12[program-counter: (to-integer operand) - 1];b x 13[if (to-integer accumulator) > 0 [program-counter: (to-integer operand) - 1]];bp x 14[if (to-integer accumulator) < 0 [program-counter: (to-integer operand) - 1]];bn x 15[if (to-integer accumulator) = 0 [program-counter: (to-integer operand) - 1]];bz x 16[;?jsb x stack-pointer: stack-pointer - 1 set-memory stack-pointer program-counter program-counter: to-integer operand switch/default to-integer operand[ 900[prin to-integer accumulator program-counter: get-memory stack-pointer stack-pointer: stack-pointer + 1 ] 925[ i: 0 while [(to-integer (get-memory ((to-integer accumulator) + i))) > 0][ prin to-char to-integer((get-memory ((to-integer accumulator) + i))) i: i + 1 ] program-counter: get-memory stack-pointer stack-pointer: stack-pointer + 1 ] 950[ num: input if (length? num) > 0[accumulator: to-integer num] program-counter: get-memory stack-pointer stack-pointer: stack-pointer + 1 ] 975[ str: input if (length? str) > 0[ i: 0 while[i < length? str][ char: pick str (i + 1) set-memory (accumulator + i) char i: i + 1 ] set-memory (accumulator + i) 0 program-counter: get-memory stack-pointer stack-pointer: stack-pointer + 1 ] ] ][program-counter: (to-integer program-counter) - 1] ] 17[program-counter: get-memory stack-pointer stack-pointer: stack-pointer + 1]; rsb x 18[stack-pointer: stack-pointer - 1 set-memory stack-pointer accumulator];push 19[accumulator: get-memory stack-pointer stack-pointer: stack-pointer + 1] ][print rejoin["Fatal Error: Bad Opcode line " program-counter] cpu-running: false] program-counter: (to-integer program-counter) + 1 ] ] ] tiny-emulator/read-file %"tiny-program.tnc" tiny-emulator/boot