Arduino VM builder (preview)

User projects written in or related to FreeBASIC.
Post Reply
mrminecrafttnt
Posts: 131
Joined: Feb 11, 2013 12:23

Arduino VM builder (preview)

Post by mrminecrafttnt »

This one can create an bytecode based VM Sketch for Ardruinos (yep simply coustumize, copy and paste the code in the ide and it works), supports allready SPI SRAM, more features are coming,
The Idea is that everybody can make easyly an VM for Arduinos.
Its very hard to code this and not finally but it has already a little bunch of code to learn how it works.. :)

Code: Select all

#include "windows.bi"
Print "Mrminecrafttnts AVR VM Builder for Arduino IDE"
#define AviableRam 2048
enum stortype
    InternalRam = 0
    ExternalRam = 1
end enum

type uint32_t
    objname as string
    setval as integer
end type


type register
    registername as string
    registervalue as ubyte
end type

type memoryarea
    memoryname as string
    chipname as string
    memorysize as integer
    extptr as integer
    storage_in_type as stortype
end type

type memorypointer
    pointername as string
    adress as uinteger
end type


type sram_chip
    sramchip_name as string
    sramsize as integer
    bytes_free as integer
    sram_chipselect as integer
end type



type vm_flags
    external_ram_exists as bool
end type


type vm
    flag as vm_flags
    freemem as integer
    nextmemoryext as integer
    memorypointers(any) as memorypointer
    registers(any) as register
    memoryareas(any) as memoryarea
    sram_chips(any) as sram_chip
    global_uint32_ts(any) as uint32_t
    declare sub add_register
    declare sub add_memoryarea(memname as string,size as uinteger,stortype as ushort)
    declare sub add_pointer(pname as string,memname as string,offset as uinteger)
    declare sub add_sramchip(chipname as string,byte_size as integer,CHIPSELECT as integer)
    declare sub add_global_uint32_t(uint_name as string,value as integer = 0)
    declare function finduint32 (n as string) as integer
    declare function search_memoryarea(memname as string) as integer
    declare function search_freesramchip(needed_size as integer) as integer
    declare function check_name_exits(objname as string) as bool
    declare function check_chipselect_exits(CS as integer) as bool
    declare function check_if_uint32_t_exists (uint_name as string) as bool
    declare constructor     
end type

constructor vm
    freemem = AviableRam
end constructor
    

function vm.finduint32 (n as string) as integer
    for i as integer = lbound(global_uint32_ts) to ubound(global_uint32_ts)
        with global_uint32_ts(i)
            if .objname = n then return i
        end with
    next
    return -1
end function

        

function vm.check_if_uint32_t_exists (uint_name as string) as bool
    for i as integer = lbound(global_uint32_ts) to ubound(global_uint32_ts)
        if global_uint32_ts(i).objname = uint_name then return true
    next
    return false
end function

sub vm.add_global_uint32_t(uint_name as string,value as integer = 0)
    if check_if_uint32_t_exists (uint_name) = true then print "uint32 ("+uint_name+") exists allready" : exit sub
    redim preserve global_uint32_ts(ubound(global_uint32_ts)+1)
    with global_uint32_ts(ubound(global_uint32_ts))
        .objname = uint_name
        .setval = value
    end with
end sub

    
    
    
    
    
function vm.search_freesramchip(needed_size as integer) as integer
    for i as integer = lbound(sram_chips) to ubound(sram_chips)
        with sram_chips(i)
            if .bytes_free - needed_size > 0 then
                print .bytes_free - needed_size
                return i
            else
                PRint "CHIP("+str(I)+") runs out of space ("+str(.bytes_free - needed_size )+")"
            end if
        end with
    next
    return -1
end function

            
        

function vm.search_memoryarea(memname as string) as integer
    for i as integer = lbound(memoryareas) to ubound(memoryareas)
        if memoryareas(i).memoryname = memname then return i
    next
    return -1
end function

function vm.check_chipselect_exits(CS as integer) as bool
    for i as integer = lbound(sram_chips) to ubound(sram_chips)
        with sram_chips(i)
            if .sram_chipselect = CS then return true
        end with
    next
    return false
end function

function vm.check_name_exits(objname as string) as bool
    for i as integer = lbound(sram_chips) to ubound(sram_chips)
        with sram_chips(i)
            if .sramchip_name = objname then return true
        end with
    next
    for i as integer = lbound(memorypointers) to ubound(memorypointers)
        with memorypointers(i)
            if .pointername = objname then return true
        end with
    next
    for i as integer = lbound(memoryareas) to ubound(memoryareas)
        with memoryareas(i)
            if .memoryname = objname then return true
        end with
    next
    return false
end function

    

sub vm.add_sramchip(chipname as string,byte_size as integer,CHIPSELECT as integer)
    PRINT "ADDING SRAMCHIP NAMED ";CHIPNAME;"- ";
    if check_name_exits (chipname) or  check_chipselect_exits(CHIPSELECT) then
        print "ERROR OBJECT("+chipname+") OR CHIPSELECT ("+str(CHIPSELECT)+") ALREADY EXISTS (NOT ADDED)" : exit sub
    end if
    
    redim preserve sram_chips(ubound(sram_chips)+1)
    with sram_chips(ubound(sram_chips))
        .sramchip_name = chipname
        .sramsize = byte_size
        .bytes_free = .sramsize
        .sram_chipselect = CHIPSELECT
        
    end with
    Print "SRAM NAMED "+chipname+" ADDED WITH "+str(byte_size)+"bytes"
    if flag.external_ram_exists = false then flag.external_ram_exists = true
end sub

    

sub vm.add_pointer(pname as string,memname as string,offset as uinteger)
    PRINT "ADDING POINTER NAMED ";PNAME;"- ";
    redim preserve memorypointers(ubound(memorypointers)+1)
    
        dim as integer memid = search_memoryarea(memname)
        if memid > -1 and flag.external_ram_exists = true then
            memorypointers(ubound(memorypointers)).pointername = pname
            memorypointers(ubound(memorypointers)).adress = memoryareas(memid).extptr + offset : 
        end if
        Print "Pointer ";UCASE (pname);" set to ";memorypointers(ubound(memorypointers)).adress
    
end sub

        


sub vm.add_memoryarea(memname as string,size as uinteger,stortype as ushort = 0)
    print size
    dim as bool ok = false
    
    PRINT "ADD MEMORYAREA NAMED ";memname;"- ";
    if check_name_exits(memname) = true then print "OBJECT ALLREADY EXISTS" : Exit sub
        if stortype = ExternalRam  then 
            if flag.external_ram_exists = false then print "NO EXTERNAL CHIP DECLRED BUT NEEDED" : exit sub
            redim preserve memoryareas(ubound(memoryareas)+1)
            dim as integer sramchipid = search_freesramchip(size)
                if sramchipid > -1 then
                    PRINT "SRAMCHIP ID : ";sramchipid
                    with sram_chips(sramchipid)
                        .bytes_free -= size
                    end with
                    with memoryareas(ubound(memoryareas))
                        .extptr = nextmemoryext 
                        nextmemoryext + = size 
                        PRINT "SIZE = ";size
                        .memorysize = size
                        .memoryname = memname
                        print "MEMSIZE = ";.memorysize
                        print "DEBUG :";.extptr,.memorysize
                        .storage_in_type = stortype
                        .chipname = sram_chips(sramchipid).sramchip_name
                    end with
                else
                    Print "NO FREE SRAM MEMORY DETECTED"
                    exit sub
                end if
                
            print nextmemoryext,memoryareas(ubound(memoryareas)).extptr
            ok = true
        end if
        if stortype = InternalRam then
            if freemem - size > 512 then
                redim preserve memoryareas(ubound(memoryareas)+1)
                with memoryareas(ubound(memoryareas))
                    .memoryname = memname
                    .memorysize = size
                end with
                freemem -=size
                Print "Using ";size;" bytes of internal Ram(";freemem;"bytes free)"
                ok = true
            else
                PRINT "ARREY IS TO BIG FOR INTERNAL MEMORY"
            end if
            
        end if
    
    if ok = true then 
        Print "Memory "+UCASE(memname) +" added ";
    else
        Print "Memory "+UCASE(memname) +">>NOT<< added ";
    select case stortype
    case InternalRam
        Print "[INTERNAL]"
    case ExternalRam
        Print "[EXTERNAL]"
    case else
        print "[ERROR IS HERE!!!]"
    end select
    end if
    
    nextmemoryext +=1
        
    
end sub


sub vm.add_register
 
    redim preserve registers(ubound(registers)+1)
    registers(ubound(registers)).registername = "r"+str(ubound(registers))
    Print "Register "; registers(ubound(registers)).registername; " added"
end sub

sub buildscript (programmcounter as string,memory as string,buildvm as vm)

    with buildvm
        
        open "VMSKETCH"+".ino" for output as #1
        
        PRINT "//GLOBAL VARIALBLES"
           for i as integer = lbound(.global_uint32_ts) to ubound(.global_uint32_ts)
                with .global_uint32_ts(i)
                   if .setval = 0 then 
                       PRINT  "uint32_t "+.objname+";"
                   else
                       PRINT  "uint32_t "+.objname+" ="+str(.setval)+";"
                   end if
                end with
               
               
           next
           
        if .flag.external_ram_exists=true then 
           PRINT  "//SPI AND SRAM23LC YOU FIND IT IN THE LIBARAY"
           PRINT  "#include <SPI.h>"
           PRINT  "#include <SRAM_23LC.h>"
           
           
           PRINT  "//DECLARE THE SRAM CHIPS"
            if ubound(.sram_chips) > -1 then
                for i as integer = lbound(.sram_chips) to ubound(.sram_chips)
                    PRINT  "SRAM_23LC "+.sram_chips(i).sramchip_name+"(&SPI,"+ str(.sram_chips(i).sram_chipselect)+", SRAM_23LCV1024);"
                next
            end if
        end if
        
        PRINT  "//INTERNAL MEMORY ARREYS"
            for i as integer = lbound(.memoryareas) to ubound(.memoryareas)
            with .memoryareas(i)
                if .storage_in_type = InternalRam then
                    PRINT  "uint8_t "+str(.memoryname)+"["+str(.memorysize)+"];"
                end if
                
            end with
        next
        
        for i as integer = lbound(.registers) to ubound(.registers)
            with .registers(i)
                PRINT  "int "+.registername+";"
            end with
        next
        
        for i as integer = lbound(.memoryareas) to ubound(.memoryareas)
            with .memoryareas(i)
                if .storage_in_type = ExternalRam then
                    PRINT  "void write_"+.memoryname+"(uint32_t adress,uint32_t b){"
                    PRINT  "     if (("+str(.extptr)+"+adress >="+str(.extptr+.memorysize)+") or ("+str(.extptr)+"+adress <="+str(.extptr)+")) {return;}"
                    PRINT  "     "+.chipname+".writeByte("+str(.extptr)+"+ adress,b);}"
                    PRINT  "uint8_t read_"+.memoryname+"(uint32_t adress){"
                    PRINT  "     if (("+str(.extptr)+"+adress >="+str(.extptr+.memorysize)+") or ("+str(.extptr)+"+adress <="+str(.extptr)+")) {return;}"
                    PRINT  "     "+.chipname+".readByte("+str(.extptr)+"+ adress);}"
                end if
                
        
                
                    
                
                
            end with
        next
        dim as integer opcode
        PRINT  "void vm_tick(){"
        if buildvm.memoryareas(buildvm.search_memoryarea(memory)).storage_in_type = ExternalRam then
            PRINT  "    switch(read_"+buildvm.memoryareas(buildvm.search_memoryarea(memory)).memoryname+"("+buildvm.global_uint32_ts(buildvm.finduint32(programmcounter)).objname+")){"
        else
            PRINT  "    switch("+buildvm.memoryareas(buildvm.search_memoryarea(memory)).memoryname+"["+buildvm.global_uint32_ts(buildvm.finduint32(programmcounter)).objname+"]){"
        end if
        
        for r as integer = lbound(.registers) to ubound(.registers)
        for i as integer = lbound(.memoryareas) to ubound(.memoryareas)
            if .memoryareas(i).storage_in_type = ExternalRam then
            
                PRINT 
                PRINT  "     case "+str(opcode)+":"
                PRINT  "          write_"+.memoryareas(i).memoryname+"("+.registers(r).registername+","+.registers(0).registername+");"
                PRINT  "          break;"
                opcode+=1
                PRINT  "     case "+str(opcode)+":"
                PRINT  "         "+.registers(r).registername+" = read_"+.memoryareas(i).memoryname+"("+.registers(0).registername+");"
                PRINT  "         break;";
                opcode+=1
            end if
            next
            
                
        next
        PRINT 
        for i as integer = lbound(.registers) to ubound(.registers)
            for mem as integer = lbound(.memoryareas) to ubound(.memoryareas)
            PRINT  "     case "+str(opcode)+":"
            
                if .memoryareas(mem).storage_in_type = ExternalRam then
                    PRINT  "     "+.registers(i).registername+" = "+buildvm.memoryareas(buildvm.search_memoryarea(memory)).memoryname+"["+buildvm.global_uint32_ts(buildvm.finduint32(programmcounter)).objname+"+1];"
                    PRINT  "     "+buildvm.global_uint32_ts(buildvm.finduint32(programmcounter)).objname+"++;"
                    PRINT  "     break;"
                    opcode+=1
                else
                    PRINT  "     "+.registers(i).registername+" =" +buildvm.memoryareas(buildvm.search_memoryarea(memory)).memoryname+"+1;"
                    PRINT  "     break;"
                    opcode+=1
                end if
            next
        next
        
            
        
            
                
                    
        PRINT  "}}"
        
        PRINT  "void setup(){}"
        PRINT  "void loop(){vm_tick();prgctr++;}"
        
            
        
    end with
end sub


dim as vm test
COLOR 14
' TEMPLATE DATA ARE HERE
test.add_global_uint32_t "prgctr"
for i as integer = 1 to 10
test.add_register
next
test.add_register
test.add_sramchip("SRAM0",3000,3)
test.add_sramchip("SRAM1",1600000,4)
test.add_memoryarea("StringData",1024,externalram)

test.add_memoryarea("FRAM",1024,externalram)
test.add_memoryarea("VRAM",1024*1024,externalram)
test.add_memoryarea("bf",512,internalram)
test.add_memoryarea("PRAM",256,internalram)
test.add_memoryarea("FRAM1",768,externalram)
test.add_pointer("DATAPTR","bf",4)

'BUILD THE SCRIPT
color 7
PRINT "***SCRIPT STARTS HERE***"
PRINT
color 15

buildscript("prgctr","bf",test)
sleep
Greatings MrMinecraftTNT
Post Reply