:PROPERTIES: :ID: 9b251eb9-aff6-4025-94bf-25e89e26d54a :END: #+TITLE: Fifth - virtual machine #+AUTHOR: Svjatoslav Agejenko #+LANGUAGE: en Current emulator emulates: - 1 CPU. - It has 2 stacks - ~50 instructions - 4GB flat address space (theoretically). While I tried to keep instruction set simple, I was forced to put in some complex instructions to make performance acceptable on emulator. CPU has following registers: - IP :: instruction pointer - DSP :: data stack pointer - RSP :: return stack pointer * Instructions overview Virtual CPU, commands (most of them are avaiable as ordinary commands in programming language): | # | name | stack footprint | description | |----+--------------+--------------------------------------+-------------------------------------------------------------| | 0 | nop | -- | does nothing | | 1 | halt | -- | halt CPU ( return to DOS on emulator ) | | 2 | [[id:820b1b90-4f4c-4ab1-b49f-9b4a52ea2528][kbd@]] | -- c | read scancode of pressed or released key | | 3 | num | -- n | put immidiate number into datastack | | 4 | jmp | -- | jump to specified code | | 5 | call | | jump to specified code, save return address to return stack | | 6 | 1+ | n -- n+1 | | | 7 | 1- | n -- n-1 | | | 8 | dup | n -- n n | duplicate top of data stack | | 9 | drop | n -- | drop last element in data stack | | 10 | if | n -- | jump to addr if top element was 0 | | 11 | ret | | jump to code, specified in return stack. | | 12 | c@ | addr -- n | read byte from memory at specified address | | 13 | c! | n addr -- | store byte to specified memory | | 14 | push | DSTK -> RSTK | move top of datastack to returnstack | | 15 | pop | RSTK -> DSTK | move top of returnstack to datastack | | 16 | | | | | 17 | rot | n1 n2 n3 -- n2 n3 n1 | rotate stack elements | | 18 | disk@ | FromDiskSect ToMem -- | read 1KB from disk into RAM | | 19 | disk! | FromMem ToDiskSect -- | write 1KB to disk | | 20 | @ | addr -- n | read 32 bit number from memory | | 21 | ! | n addr -- | store 32 bit number to memory | | 22 | over | n1 n2 -- n1 n2 n1 | | | 23 | swap | n1 n2 -- n2 n1 | | | 24 | + | n1 n2 -- n1+n2 | | | 25 | - | n1 n2 -- n1-n2 | | | 26 | * | n1 n2 -- n1*n2 | | | 27 | / | n1 n2 -- n1/n2 | | | 28 | > | n1 n2 -- result | is true when n1 > n2 | | 29 | < | n1 n2 -- result | is true when n1 < n2 | | 30 | not | n1 -- not_n1 | logical not | | 31 | i | -- n | copies top of return stack into datastack | | 32 | cprt@ | addr -- n | read one byte from hardware port | | 33 | cprt! | n addr -- | store one byte to hardware port | | 34 | i2 | -- n | like "i" but takes second top stack element | | 35 | i3 | -- n | like "i" but takes third top stack element. | | 36 | shl | n amount -- n | left bit shift | | 37 | shr | n amount -- n | right bit shift | | 38 | or | n1 n2 -- n | logical or | | 39 | xor | n1 n2 -- n | exclusive logical or | | 40 | vidmap | addr -- | copy memory from "addr" to video memory. | | 41 | mouse@ | -- x y button | read mouse coordinates & buttons | | 42 | [[id:238e8b03-57b6-424d-bfee-b6bb652cefbc][vidput]] | addr1 addr2 x y -- | put image1 into image2, at location x, y | | 43 | [[id:79e1916f-4103-42cc-ac10-bb1ee776ed50][cmove]] | addr1 addr2 amount | move memory from addr1 to addr2 | | 44 | cfill | c addr amount -- | fill memory starting at "addr" with "c" bytes. | | 45 | [[id:ab45247c-44c3-464d-9e2a-337f483b4616][tvidput]] | addr1 addr2 x y -- | put image with transparency support | | 46 | depth | -- depth | returns current depth of data stack. | | 47 | [[id:4bb479cf-aae0-4128-9868-f016c286a162][charput]] | colorfg colorbg addrsrc addrdest x y | draw text character | ** kbd@ - read scancode of pressed or released key :PROPERTIES: :ID: 820b1b90-4f4c-4ab1-b49f-9b4a52ea2528 :END: Returns 0 if no data available. ** vidput - put image1 into image2, at location x, y :PROPERTIES: :ID: 238e8b03-57b6-424d-bfee-b6bb652cefbc :END: Does clipping, so part of a big image can be mapped into smaller one. ** cmove - copy memory array :PROPERTIES: :ID: 79e1916f-4103-42cc-ac10-bb1ee776ed50 :END: Move memory from addr1 to addr2. If addr1 is greater than addr2 then count address foward while moving, elseway starts from end and counts backwards, so no data loss occurs when memory regions partially overlap. ** tvidput - put image with transparency support :PROPERTIES: :ID: ab45247c-44c3-464d-9e2a-337f483b4616 :END: Stack footprint : addr1 addr2 x y -- Put image1 into image2, at location x, y with transparency support Color 255 in source image is treated as transparent. ** charput - draw text character :PROPERTIES: :ID: 4bb479cf-aae0-4128-9868-f016c286a162 :END: Draw character to image buffer located at "addrdest" to specified x & y location. Decodes 8 bytes from source to bits, used to draw character.