How to use Virtual Processing Units Virtual Processing Units (VPU) can be programmed like any real CPU that uses Harward architecture. VPUs have separate memory spaces for code, data and stack. Data and code memorys are divided into segments (or pages). Technically there can be 16^2 pages for data memory and 15^2 pages for code memory. The smaller limitation for code memory comes from the way the JMP instruction is implemented. The pages can be 16^2 bytes long, but because the implementation of the host system may not allow 16^2 bytes long arrays (arrays can have some overhead in the runtime of the compiler) it's recommended to use few bytes smaller pages. Currently the assembler does not support multiple segments, so the program and data must fit in single segments. Contents: 1. Using VPU console 2. Using the assembler 2.1. Program header 3. Programming the VPU 3.1. Declaring variables 3.2. Writing VPU instructions 3.3. Comments # 1. Using VPU Console VPU Console can be used to write small programs and experiment with assembly procedures. You can write any built-in command, VPU instruction or symbol declaration into the command line. Built-in commands: EXIT - Close the console. EDIT - Go to code edit mode. Return to command line by ESC key. STATUS - Show VPU status. RESET - Reset VPU status. DEBUG - Show more or less debug information when running the program. It's not recommended to use this with the STRGET instruction. RUN - Assemble and run the program. STEP - Assemble the program and run it by one instruction at a time. CONTINUE - Continue running the program if it was stopped by a WAIT instruction. LOAD [filename] - Load a file into the editor. SAVE [filename] - Save the editor contents to a file. LSSYM - List all symbols. $[symbol] - Show information about a symbol. CODE [segment] [offset] [count] - List contents of the code memory starting from [segment:offset] and stopping after [count] lines. Note: If the first listed byte is an operand (not the opcode that starts an instruction) then the definitions listed in the rightmost column are not accurate. DATA [segment] [offset] [count] - List contents of the DATA memory. STACK [base] - List contents of the stack. MEMBYTE [segment] [offset] - Show contents of the memory address [segment:offset] as an unsigned char. MEMWORD [segment] [offset] - Show contents of the memory address [segment:offset] as an unsigned short. PID [pid] - Sets or shows the pid of the program that is being debugged. # 2. Using the assembler The assembler (ASSEMBLE.EXE) can be used to assemble larger programs. It produces an executable bytecode binary file that does not need to be assembled every time before running. Command example: ASSEMBLE [source file] [executable] If the executable file's name ends with .APP extension, it can be run from anywhere in the window manager like any executable. # 2.1. Program header The first four lines in the source code must define the header information. The header is needed to know how much memory needs to be allocated for the VPU. VPU console does not need the header. Example header: code 1 2048 data 1 4096 stack 128 interrupts 16 This header produces a VPU with one code segment of 2048 bytes, one data segment of 4096 bytes, a 128 entries long stack and 16 entries long interrupt table. # 3. Programming the VPU # 3.1. Declaring variables There are currently 4 data types: 8-bit unsigned integer "byte", 16-bit unsigned integer "word", 8-bit signed integer "signed byte", and 16-bit signed integer "signed word". After declaring the data can be accessed by inserting $ before the variable name. Inserting a dot (.) returns the segment where the variable is contained. Declaring a byte: byte [symbol_name] [value] Examples: byte foo 10 byte bar 0x26 Declaring a signed byte: signed byte [symbol_name] [value] Examples: signed byte foo 21 signed byte bar -52 Declaring a word: word [symbol_name] [value] Examples: word foo 18523 word biz 0x2451 word aaa 15 Declaring a signed word: signed word [symbol_name] [value] Examples: signed word foo -2568 signed word asdfghjkl 0x516 Declaring a string with contents str [symbol_name] "[string]" Example: str hello "Hello world" The above example creates a symbol $hello that points to the memory address of the first character of the string. Declaring an empty string str [symbol_name] [string_length] Example: str buff 80 The above example creates an 80 bytes long array of null characters. A symbol $buff is created, and it points to the first cell of the array. Declaring an array: str arrayofstrs { "Hello world" "Hello friends" "Goodbye cruel world" } The above example creates three strings and an array of three unsigned words that point to the first bytes of each string. A symbol named $arrayofstrs is created, and it points to the first entry of the word array. signed word arrayofints { 3620 0x650 0b11001001 0562 -50 } The above example creates an array of signed words. A symbol named $arrayofints is created, and it points to the first entry of the array. byte arrayofuchars { 0x28 0x58 0x00 0x53 } The above example creates an array of bytes. A symbol named $arrayofuchars is created, and it points to the first entry of the array. # 3.2. Writing instructions: See INSTRLST.TXT. # 3.3. Comments Comment lines begin with a semicolon (;).