Virtual Machine (definition)
version 2.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