Virtual Machine (definition)
version 1.0, done by Mc in 2002


table of contents:


The purpose of this virtual machine is to create a new, general purpose, hardware independent environment to speed up application development. Imagine that applications could be developed in any (high level) language. The compiler first generates code for this virtual machine and in the second step, an other simply assembler generates working code for existing processors. The main advantage of this technique is that high level compilers do not require modification to support new hardware environment, and every application could compile to any hardware without modification. So we can say that once we have a good compiler, it can compile for any (possible not yet existing) hardware environments. To do this, a simple assembler is needed to generate machine specific code. It means that this virtual machine code could be used as an intermediate language between higher level languages and the machine code. Because of this, virtual machine is defined with minimal set of instructions and registers, so every existing (and hopefully future) processors could used as target machine.
The only things what higher level compilers should know about target environment are the size of address, and the default integer size, but of course this knowledge is not required, a well chosen address size could be enough for every platform.
Another partition of this idea is the way how applications make system calls (such as file handling, etc). To make a general purpose virtual machine, we need to define these complex things at 'processor' level. This is done through the syscall instruction. Once an application wants to do something with the system, puts the appropriate syscall to the virtual machine code, and the assembler generates the hardware specific code to binary output.

table of contents


sizes:

b

byte

8 bits

w

word

16 bits

d

double word

32 bits

q

quad word

64 bits

table of contents


formats:

d

default bit order

m

Most Significant Bit first

l

Least Significant Bit first

table of contents


signs:

s

signed

u

unsigned

table of contents


registers:

a

data

b, w, d, w

b

data

b, w, d, w

c

data

b, w, d, w

d

data

b, w, d, w

src

pointer

depends on architecture

trg

pointer

depends on architecture

table of contents


addressing:

[src+-number]

[trg+-number]

table of contents


conditions:

a

above

b

below

e

equal

ae

above or equal

be

below or equal

na

not above

nb

not below

ne

not equal

nae

nor above nor equal

nbe

nor below nor equal

table of contents


syntax:

platform

name

 

the name of platform used at higher level

proc

label

 

beginning of subroutine

endp

 

 

end of subroutine

label

label

 

place a label here

defb

number(s)

 

place byte(s) in code

defw

number(s)

 

place word(s) in code

defd

number(s)

 

place double word(s) in code

defq

number(s)

 

place quad word(s) in code

const

name

number

let constant name equal to number

table of contents


instructions:
note1: the upper remainder parts of registers are not tested, and have invalid contents after execution.
note2: the conditions are destroied by instructions, so a jmpc or setc must preceded by a comp instruction.

add

size

reg

reg/num

adding op2 to op1

sub

size

reg

reg/num

subtract op2 from op1

mul

sign size

reg

reg/num

multiply op1 by op2

div

sign size

reg

reg/num

divide op1 by op2

mod

sign size

reg

reg/num

remainder from dividing op1 by op2

or

size

reg

reg/num

bitwise oring op1 by op2

xor

size

reg

reg/num

bitwise xoring op1 by op2

and

size

reg

reg/num

bitwise anding op1 by op2

not

size

reg

 

bitwise noting op1

neg

size

reg

 

negating op1

shl

size

reg

reg/num

shift left op1 by op2 bits

shr

size

reg

reg/num

shift right op1 by op2 bits

push

size

reg

 

put op1 to top of stack

pop

size

reg

 

get value from top of stack to op1

comp

sign size

reg

reg/num

compare op1 to op2

move

op1.sign op1.size op2.sign op2.size

reg

reg/num

move op2 to op1

movr

format op1.sign op1.size op2.sign op2.size

reg

mem

read op1 from memory

movw

format op1.sign op1.size op2.sign op2.size

mem

reg

write op2 to memory

call

label

 

 

jump to label, push offset to stack

cllr

src/trg

 

 

jump to an address, push offset to stack

ret

 

 

 

return to saved offset

jump

label

 

 

jump to label

jmpr

src/trg

 

 

jump to an address

jmpc

condition

label

 

jump to label if condition is true

setc

condition

size

reg

set the register to 1 if condition is true, else 0

xchg

size

mem

reg

exchange value in op2 register with op1 memory

addrLod

src/trg

mem

 

load address from memory to op1

addrSav

mem

src/trg

 

save address from op2 to memory

procAddr

src/trg

num

 

setup op1 to beginning of op2 subroutine's data block

procAllocBeg

num

num

 

begin allocating op2 bytes to op1 subroutine; use the - as number

procAllocEnd

num

num

 

finish allocating op2 bytes to op1 subroutine

procFree

num

num

 

release op2 bytes from op1 subroutine

codeOfs

src/trg

label

 

get offset of label in code

sysCall

function

 

 

do the function, parameters are in registers

table of contents


syscalls:

startup

 

 

starts the code here [maxproc] [maxstack] [maxheap]

terminate

w:a

 

terminates the code withe error code a

sleep

 

 

sleeps the process for a while

memCopy

src trg d:c

 

copy c bytes from [src] to [trg] in memory

memCopy2

src trg d:c

 

copy c bytes from [src] to [trg] in memory, cares on overlapping

memFillByte

trg b:a d:c

 

fill a byte to trg c times

memResize

d:c

d:c trg

resize the memory to c, returns the size, and beginning

getMemInfo

 

d:c trg

returns the size, and beginning of extended memory

codeCopy

src trg d:c

 

copy c bytes from code [src] to memory [trg]

console.write

src d:c

 

write c bytes from src to the console

console.iskey

 

b:a

test for char on console (1=yes, 0=no)

console.read

trg d:c

d:c

read c bytes to trg from the console, returns number of bytes read in c

console.size

 

w:a w:b

read console size (a=x, b=y)

console.clear

 

 

clears the console

console.gotoXY

w:a w:b

 

set the cursor to a column and b row

console.setColor

b:a

 

set the pen color to ibm attributes

console.getDate

 

w:a w:b w:c

returns current date, a-year, b-month, c-day

console.getTime

 

w:a w:b w:c

returns current time, a-hour, b-minute, c-second

console.execWait

src trg

w:a w:b

execute process in trg with src parameter, wait until terminate, returns exitcode in a (b=error)

file.maxName

 

w:a

returns maximum name length

file.myName

trg

w:c

returns pathname of running process

file.myParam

trg

w:c

returns parameters of running process

file.open

src d:a

d:a w:b

open file on pascii name src with a rights, handler returned in a (b=error)

file.read

d:a trg d:c

d:c w:b

read c bytes to trg memory from file handler a, return c bytes read, (b=error)

file.write

d:a src d:c

w:b

write c bytes from src memory to file handler a (b=error)

file.seek

d:a d:c

w:b

seek to c position in file handler a (b=error)

file.getSize

d:a

d:c w:b

get file size to c from handler a (b=error)

file.getPos

d:a

d:c w:b

get file position to c from handler a (b=error)

file.truncate

d:a

w:b

truncate file handler a (b=error)

file.close

d:a

w:b

close the file handler a (b=error)

file.create

src

w:b

create pascii src named file (b=error)

file.erase

src

w:b

erase pascii src named file (b=error)

dir.current

trg

w:b

get working directory to trg in pascii (b=error)

dir.change

src

w:b

change working directory from src in pascii (b=error)

dir.statistic

 

d:a d:b d:c d:d

get disk statistics: a-free, b-used, c-bad, d-blocksize

dir.setRights

src d:a d:b

w:b

set directory entry access rights to a and owner to b (b=error)

dir.setDate

src trg

w:b

set src directory entry create,modify date to trg (b=error)

dir.reName

src trg

w:b

rename src directory entry to trg name (b=error)

dir.makeLink

src trg

w:b

create link to src directory entry under trg name (b=error)

dir.open

src

d:a w:b

open directory on pascii src name, handler returned in a (b=error)

dir.read

d:a trg

w:b

read dir entry to trg memory from dir handler a (b=error)
format: d:size, d:rights, d:owner, t:create, t:modify, pascii:name
t: w:year, b:month, b:day, b:hour, b:minute, b:second

dir.close

d:a

w:b

close the directory handler a (b=error)

dir.create

src

w:b

create pascii src named directory (b=error)

dir.erase

src

w:b

erase pascii src named directory (b=error)

pipeline.startListen

 

w:b

start listening for incoming pipelines (b=error)

pipeline.stopListen

 

w:b

stop listening for incoming pipelines (b=error)

pipeline.getIncoming

 

w:b d:a

get next incoming pipeline number in a (b=error)

pipeline.create

d:a d:c b:b

w:b d:a

create c bytes pipe to a process b=1 if block mode, pipe id a (b=error)

pipeline.close

d:a

w:b

close pipeline a (b=error)

pipeline.info

d:a

d:a d:c d:d w:b

pipeline info, a=process, c=freeTx, d=usedRx (b=error)

pipeline.receive

d:a trg d:c

d:c w:b

receive c bytes to trg from a pipeline, c bytes received (b=error)

pipeline.send

d:a src d:c

w:b

send c bytes from src to a pipeline (b=error)

system.getPID

 

d:a d:b d:c

returns a=process id, b=parent process id, c=rights

system.getUID

 

d:a d:b

returns my user id in a, original in b

system.sysInfoNum

 

d:a d:c d:d

returns a=#of proc, c=#of pipes, d=#of files

system.sysInfoMem

 

d:a d:c d:d

returns memory in byte a=total, c=kernel, d=free

system.sysInfoProc

 

d:a d:b d:c d:d

returns process starts a=idles, b=rounds, c=full rounds, d=active start

system.procInfoNam

d:a trg

d:a d:c d:d

returns info about [a] process, trg=pathname+param, a=uid, c=parent pid, d=rights

system.procInfoNum

d:a

d:a d:c d:d

returns info about [a] process, a=bytes, c=pipes, d=files

system.procInfoRun

d:a

d:a d:b d:c

returns process runs a=working since, b=times was busy, c=times run

system.findProcNum

d:a

d:a

find process by number (0..max-1)

system.findProcNam

src

d:a

find process by name

system.cpuInfo

d:a trg

d:a d:c

get cpu info (0..max-1), a=max, c=number

system.kernelInfo

trg

 

get kernel info to trg in asciiZ

system.kernelLogo

trg

 

get kernel logo to trg in asciiZ

system.procLive

d:a

d:b

check process existence, 0=no, 1=yes

system.uptimeInfo

 

d:a d:c d:d

get uptime info, a=days, c=ticks, d=ticks/day

system.killProcess

d:a

d:b

kill another process

syscalls require extra privileges:

system.setUID

d:a

 

sets my user id

console.execBckgnd

src trg

d:a w:b

execute process in background, returns pid in a (b=error)

console.execInme

src trg

d:a d:c w:b

execute process inside me, returns pid in a, pipe in c (b=error)

system.mapMemory

d:a d:c

d:b trg d:a d:c

map c bytes from a of physical memory, returns trg as logical offset

system.contMem

d:c

d:b d:a d:c trg

allocate continous c bytes, returns b=error, a=physical, c=size, trg=beginning

system.IOportRead

d:d b:c

d:a

read c bits from d port to a

system.IOportWrite

d:d b:c d:a

 

write c bits from d port from a

system.DMAcount

w:d

d:c

get byte count of dma channel

system.DMAstop

w:d

 

stop dma channel

system.DMAstart

w:d d:a d:c b:b

 

start dma channel a=physical, c=count, b=mode:
0=demand, 1=single, 2=block, 3=cascade; 00h=verify, 10h=card>>mem, 20h=mem>>card

system.driveLogin

b:a src

d:b

login as drive letter

system.driveLogout

b:a

d:b

logout as drive letter

system.driveFinished

 

 

drive signals end of processing

system.dropPrivi

 

 

drop privileged flag

table of contents


errors:

0

no error

1

unknown error

2

out of memory

3

out of disk space

4

no right

5

sharing violation

6

path not exists

7

file not exists

8

file already exists

9

invalid handle

10

directory not empty

11

embedded directories

12

file/directory mismatch

13

file pointer too big

14

drive io fault

15

drive not ready

16

eof encountered

17

invalid filename format

18

abnormal program termination

table of contents


keys:
first byte bits:

7

extended key

2

alt

1

ctrl

0

shift

extended keys:

0

no operation

1

redraw screen

2

tab

3

backspace

4

enter

5

escape

6

insert

7

delete

8

home

9

end

10

pgup

11

pgdn

12

up

13

down

14

left

15

right

16

printscreen

17

break

18

start-left

19

menu

20..49

f1..f30

50

start-right

51

wake-up

52

sleep

53

power

table of contents


rights:

001h

owner read

002h

owner write

004h

owner execute

008h

anybody read

010h

anybody write

020h

anybody execute

040h

extended privileges

080h

directory

100h

owner read

200h

owner write

table of contents


filesys:
buffer:

dword

command/result

dword

userid

dword

rights

dword

buffer size

string

current directory

string

filename1

string

filename2

512 bytes

handler

65536 bytes

data

commands:

1

change directory

dir, fn1, uid

2

drive statistics

data: free,used,bad,blockSize:dword

3

create directory

dir, fn1, uid

4

erase directory

dir, fn1, uid

5

create file

dir, fn1, uid

6

erase file

dir, fn1, uid

7

rename

dir, fn1, fn2, uid

8

create link

dir, fn1, fn2, uid

9

set rights

dir, fn1, uid, data: rights,owner:dword

10

set date

dir, fn1, uid, data: create,modify:time

11

open directory

dir, fn1, uid, hdr, data: inode,rights:dword; name:string

12

read directory

hdr, data: size,right,own:dword; create,modify:time; name:string

13

open file

dir, fn1, right, uid, hdr, data: inode,rights:dword; name:string

14

read file

hdr, size, data

15

write file

hdr, size, data

16

seek file

hdr, data: position:dword

17

get file size

hdr, data: filesize:dword

18

get file position

hdr, data: position:dword

19

truncate file

hdr

table of contents