RFC 005 OP-codes TOC ------------------------------------------------------------------------------- 1. Annotation to Revision 2 2. Annotation to VM 3. Definition 4. Example ------------------------------------------------------------------------------- 1. Annotation to Revision 2 The new opcodes defined in this document are all about the configurable ressources implemented in the second version of the compiler and the VM. It shall be possible for the VM to use the drivers-API (RFC006) to include and/or use different services (hardware, OS, other processes). For a minimalistic control of additional hardware (peckers, for example) we need to implement the following functions: - bit-masking for the control of individual pins of the hardware - sleep-function for delays - driver-API This revision 2 of the opcode-definition is made for this purposes. -------------------------------------------------------------------------------- 2. Annotation to VM The definition of the virtual machine is not included in this RFC; you can find the design and some examples in the documentation to the VM. Just a small list of all integrated components: - program-memory, byte-array with opcodes - data-memory, int-array with global variables - stack, int-array with stack-variables - BP: Basepointer, base-address of the actual context - SP: Stackpointer, actual position on the stack - PC: Programcounter, actual position in the program memory The VM implements a 32bit-system. All memory-arrays, stack and all registers use 32bits. All data is stored in big-endian-order. ------------------------------------------------------------------------------- 3. Definition New | OP (dec) | OP (hex) | Type | Description | VM-Action ----+-----------+-----------+-------------+--------------+------------------------------------------- | 20 | 14 | Stack | CONST n | Push(n) | 21 | 15 | " | LOAD a | Push(stack[bp+a]) | 22 | 16 | " | LOADG a | Push(globals[a]) | 23 | 17 | " | STO a | stack[bp+a]=Pop() | 24 | 18 | " | STOG a | globals[a]=Pop(); | 40 | 28 | Arithmetic | ADD | Push(Pop()+Pop()); | 41 | 29 | " | SUB | Push(-Pop()+Pop()); | 42 | 2a | " | DIV | x=Pop(); Push(Pop()/x); | 43 | 2b | " | MUL | Push(Pop()*Pop()); | 44 | 2c | " | NEG | Push(-Pop()); X | 50 | 32 | " | AND | Push(Pop() & Pop()); X | 51 | 33 | " | OR | Push(Pop() | Pop()); X | 52 | 34 | " | NOT | Push(~Pop()); X | 53 | 35 | " | XOR | Push(Pop() ^ Pop()); | 60 | 3c | Comparison | EQU | if (Pop()==Pop()) Push(1); else Push(0); | 61 | 3d | " | LSS | if (Pop()>Pop()) Push(1); else Push(0); | 62 | 3e | " | GTR | if (Pop()=Pop()) Push(1); else Push(0); | 64 | 40 | " | GTE | if (Pop()<=Pop()) Push(1); else Push(0); | 80 | 50 | Jumps | JMP a | pc = a; | 81 | 51 | " | FJMP a | if (Pop()==0) pc=a; | 100 | 64 | I/O | READ | Push(ReadInt()); | 101 | 65 | " | WRITE | WriteIntLine(Pop()); | 102 | 66 | " | READC | Push(ReadChar()); | 103 | 67 | " | WRITEC | WriteChar(Pop()); | 120 | 78 | Methods | CALL a | Push(pc+2); pc=a; | 121 | 79 | " | RET | pc = Pop(); if (pc==0) return; | 122 | 7a | " | ENTER a | Push(bp); bp=sp; sp+=a; | 123 | 7b | " | LEAVE | sp=bp; bp=Pop(); X | 140 | 8C | Utilities | RTSLEEP a | sleepms(a); X | 145 | 91 | " | LDRIVER a | installDriver(a,Pop()); | 153 | 99 | " | NOP | ----+-----------+-----------+-------------+--------------+------------------------------------------- RTSLEEP ("Real-Time-Sleep") : A function implemented for each platform that delays the running program for exactly "a" milliseconds. LDRIVER ("Load-Driver") : Installs for a given resource a special driver that has been named in the sourcecode. 3. Example Addition with global variables: Pseudocode | Mnemonicode (in Bytes) | Comment -----------+------------------------+----------------------------------------------------------------------------- VAR a,b; | | each var gets a number, a -> 0, b -> 1 b = 42; | 020 000 000 000 042 | put 42 on the stack | 024 000 000 000 001 | set var nr. 1 the value on the stack (42) READ(a); | 100 | wait for userinput | 024 000 000 000 000 | set var nr. 0 to input a = a+b; | 022 000 000 000 000 | put value of var nr. 0 on the stack | 022 000 000 000 001 | put value of var nr. 1 on the stack | 040 | add both values (2 x Pop()) and put result on the stack | 024 000 000 000 000 | set var nr. 0 the value on the stack WRITE(a); | 022 000 000 000 000 | put value of var nr. 0 on the stack | 101 | write the value on the stack on the console -----------+------------------------+----------------------------------------------------------------------------- The output in the "real" GRINJ, once in pseudo-assembler and then in opcodes with parameters: 1: ENTER 2 4: CONST 42 7: STO 1 10: READ 11: STO 0 14: LOAD 0 17: LOAD 1 20: ADD 21: STO 0 24: LOAD 0 27: WRITE 28: LEAVE 29: RET 1: 122 2 4: 020 42 7: 023 1 10: 100 11: 023 0 14: 021 0 17: 021 1 20: 040 21: 023 0 24: 021 0 27: 101 28: 123 29: 121