A simple emulator

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
mrminecrafttnt
Posts: 131
Joined: Feb 11, 2013 12:23

A simple emulator

Post by mrminecrafttnt »

Code: Select all

'It simulates my own CPU with 2 registers, 5 opcodes and 256bytes of rom - have fun :)
dim shared as ubyte r0,r1,prgctr,rom(256),exitflag

function hexconvert(value as ubyte) as string
    if value < 16 then 
        return 0 & HEX(VALUE)
    else
        return hex(value)
    end if
end function

sub cmsg(msg as string,adr as ubyte) ' a simple string to rom compiler
    for i as integer = 0 to len(msg)-1
        rom(i+adr)=msg[i]
    next
end sub

sub wr(value as ubyte) 'write a data into the rom and incrase the progrommcounter
    print hexconvert(value) & " " ;
    rom(prgctr)=value
    prgctr+=1
end sub


'this subs represents the microcode
sub c_print_r0
    wr 0
end sub

sub c_set_r0(value as ubyte)
    wr 2
    wr value
end sub

sub c_set_r1(value as ubyte)
    wr 3
    wr value
end sub

sub c_inc_r0
    wr 1
end sub

sub c_cmp
    wr 4
end sub

sub c_jump(value as ubyte)
    wr 5
    wr value
end sub


'firmware programming beginns here..
print "COMPILING..";
cmsg ("HELLO WORLD",100)
c_set_r0 100
c_set_r1 111
dim as ubyte jumpadr = prgctr
c_print_r0
c_inc_r0
c_cmp
c_jump jumpadr
print "DONE. (SIZE :";prgctr;" BYTES)"


'vm starts here
prgctr = 0
do    
    'microcode starts here
    select case rom(prgctr)
    case 0
        print chr(rom(r0));
    case 1
        r0+=1
    case 2
        r0 = rom(prgctr+1)
        prgctr+=1
    case 3
        r1 = rom(prgctr+1)
        prgctr+=1
    case 4
        if r0 =r1 then exitflag = 1
    case 5
        prgctr = rom(prgctr+1)-1
    end select
    'microcode ends here
    prgctr+=1 'incrases the progrommcounter
loop until inkey <> "" or exitflag = 1
locate csrlin+1,1
print "PRESS A KEY TO EXIT"
sleep
vdecampo
Posts: 2992
Joined: Aug 07, 2007 23:20
Location: Maryland, USA
Contact:

Re: A simple emulator

Post by vdecampo »

Just so you are aware, your hexconvert function is not necessary. Just use Hex(value,2) to guarantee you get a 2-digit value.

-Vince
oyster
Posts: 274
Joined: Oct 11, 2005 10:46

Re: A simple emulator

Post by oyster »

it is better give some doc on your CPU/ASM
mrminecrafttnt
Posts: 131
Joined: Feb 11, 2013 12:23

Re: A simple emulator

Post by mrminecrafttnt »

Here is a new example with a simple compiler :)
Features: 256bytes of programm memory and 256bytes of string memory
A very small build in BASIC Compiler

Code: Select all

dim shared as ubyte pram(256) 'programmram
dim shared as ubyte sram(256) 'stringram
dim shared as ubyte prgctr,sramctr,exitflag 'programmcounter, stringadr
sub compile_print (Message as String)
    pram(prgctr)=1
    pram(prgctr+1)=len(message)
    pram(prgctr+2)=sramctr
    for i as integer = 0 to len(message)
        sram(sramctr+i)=Message[i]
    next
    sramctr+=len(message)
    prgctr+=3
end sub

sub compile_exit
    pram(prgctr)=2
    prgctr+=1
end sub

sub compile_locate (x as ubyte,y as ubyte)
    pram(prgctr)=3
    pram(prgctr+1)=x
    pram(prgctr+2)=y
    prgctr+=3
end sub

'code
compile_print "HELLO WORLD"
compile_locate 2,1
compile_print "I LIKE CHICKEN"
compile_exit



'vm
prgctr = 0
do
    select case pram(prgctr)
    case 1
        dim as ubyte length = pram(prgctr+1)
        dim as ubyte startpos = pram(prgctr+2)
        for i as integer = startpos to startpos+length-1
            print chr(sram(i));
        next
        prgctr+=2
    case 2
        exitflag = 1
    case 3
        locate pram(prgctr+1),pram(prgctr+2)
        prgctr+=2
    end select
    prgctr+=1
loop until exitflag = 1
print "DONE."
sleep
Post Reply