Document Fifth virtual machine opcodes (10–49) in separate files with detailed usage...
authorSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 21 Feb 2026 08:43:00 +0000 (10:43 +0200)
committerSvjatoslav Agejenko <svjatoslav@svjatoslav.eu>
Sat, 21 Feb 2026 08:43:00 +0000 (10:43 +0200)
doc/opcodes_10_19.org [new file with mode: 0644]
doc/opcodes_20_29.org [new file with mode: 0644]
doc/opcodes_30_39.org [new file with mode: 0644]
doc/opcodes_40_49.org [new file with mode: 0644]
doc/virtual machine.org

diff --git a/doc/opcodes_10_19.org b/doc/opcodes_10_19.org
new file mode 100644 (file)
index 0000000..430ef47
--- /dev/null
@@ -0,0 +1,181 @@
+#+SETUPFILE: ~/.emacs.d/org-styles/html/darksun.theme
+#+TITLE: Fifth - virtual machine opcodes 10 -- 19
+#+AUTHOR: Svjatoslav Agejenko
+#+LANGUAGE: en
+
+#+OPTIONS: H:20 num:20
+#+OPTIONS: author:nil
+
+#+begin_export html
+<style>
+  .flex-center {
+    display: flex;            /* activate flexbox */
+    justify-content: center;  /* horizontally center anything inside   */
+  }
+
+  .flex-center video {
+    width: min(90%, 1000px); /* whichever is smaller wins */
+    height: auto;            /* preserve aspect ratio */
+  }
+
+  .responsive-img {
+    width: min(100%, 1000px);
+    height: auto;
+  }
+</style>
+#+end_export
+
+
+* 10: if
+:PROPERTIES:
+:CUSTOM_ID: if
+:ID:       d6f834b6-9a37-4414-91b3-62b3e1d920c1
+:END:
+- *Stack Effect:* =n --=
+- *Description:* Pops the top value from the data stack. If the value is
+  zero, jumps to the address specified by the next 32-bit value.
+  Otherwise, skips the address.
+- *Notes:* Used for conditional branching. The address is added to
+  =xms_addr= for physical address conversion.
+- *Example:*
+  #+begin_example
+  0
+  0x1000  ; Jump target if zero
+  if
+  #+end_example
+
+* 11: ret
+:PROPERTIES:
+:CUSTOM_ID: ret
+:ID:       6e683977-a985-4bb8-9d2c-c860d30e1df6
+:END:
+- *Stack Effect:* =--=
+- *Description:* Returns from a subroutine by popping the return address
+  from the return stack and jumping to it.
+- *Notes:* The return stack pointer is incremented after the jump.
+- *Example:*
+  #+begin_example
+  ret
+  #+end_example
+
+* 12: c@
+:PROPERTIES:
+:CUSTOM_ID: c
+:ID:       a2ce44f7-b661-44e0-909b-644ff52aa38e
+:END:
+- *Stack Effect:* =addr -- byte=
+- *Description:* Reads a single byte from the specified memory address.
+  Replaces the address on the stack with the byte value.
+- *Notes:* The address is adjusted by =xms_addr= to convert to physical
+  memory before reading.
+- *Example:*
+  #+begin_example
+  0x1000  ; Read from address 0x1000
+  c@
+  #+end_example
+  After execution, stack contains the byte at address 0x1000.
+
+* 13: c!
+:PROPERTIES:
+:CUSTOM_ID: c-1
+:ID:       f129ef87-a31a-40fe-b8d3-984da2db90e2
+:END:
+- *Stack Effect:* =byte addr --=
+- *Description:* Stores a byte value to the specified memory address.
+- *Notes:* Takes two values from the stack: the byte to store and the
+  address. The address is adjusted by =xms_addr= before writing.
+- *Example:*
+  #+begin_example
+  0x42  ; Byte to store
+  0x1000  ; Address to store to
+  c!
+  #+end_example
+
+* 14: push
+:PROPERTIES:
+:CUSTOM_ID: push
+:ID:       e4bcbaf1-7724-4051-b19c-1aa7cd06eae6
+:END:
+- *Stack Effect:* =n --=
+- *Description:* Moves the top value from the data stack to the return
+  stack.
+- *Notes:* Used for transferring values between the two stacks without
+  modifying the value.
+- *Example:*
+  #+begin_example
+  42
+  push
+  #+end_example
+  After execution, data stack is empty and return stack contains 42.
+
+* 15: pop
+:PROPERTIES:
+:CUSTOM_ID: ID-21871d09-4d58-440f-8c94-231105aa4e3f
+:ID:       21871d09-4d58-440f-8c94-231105aa4e3f
+:END:
+- *Stack Effect:* =-- n=
+- *Description:* Moves the top value from the return stack to the data
+  stack.
+- *Notes:* Used for transferring values between the two stacks without
+  modifying the value.
+- *Example:*
+  #+begin_example
+  pop
+  #+end_example
+  After execution, data stack contains the value that was on top of the return stack.
+
+* 16: <unused>
+- *Stack Effect:* =--=
+- *Description:* Opcode 16 is unassigned and has no implementation.
+
+* 17: rot
+:PROPERTIES:
+:CUSTOM_ID: rot
+:ID:       4cee73f7-c105-4b96-9380-ff89bd7fedad
+:END:
+- *Stack Effect:* =n1 n2 n3 -- n2 n3 n1=
+- *Description:* Rotates the top three values on the data stack. The
+  third item becomes the top, the top becomes the second, and the second
+  becomes the third.
+- *Notes:* Useful for reordering stack items without temporary storage.
+- *Example:*
+  #+begin_example
+  1 2 3
+  rot
+  #+end_example
+  After execution, stack contains 2 3 1.
+
+* 18: disk@
+:PROPERTIES:
+:CUSTOM_ID: disk
+:ID:       bed1aa27-66ac-4c73-bbb9-e49ff2aa67c5
+:END:
+- *Stack Effect:* =sector addr --=
+- *Description:* Reads 1KB of data from the virtual disk at the
+  specified sector into the specified memory address.
+- *Notes:* The sector number is the top of the stack, followed by the
+  destination address. The disk is accessed via DOS interrupt calls.
+- *Example:*
+  #+begin_example
+  16  ; Sector 16
+  0x2000  ; Destination address
+  disk@
+  #+end_example
+
+* 19: disk!
+:PROPERTIES:
+:CUSTOM_ID: disk-1
+:ID:       02eda775-e483-4057-b809-de36d586579b
+:END:
+- *Stack Effect:* =addr sector --=
+- *Description:* Writes 1KB of data from the specified memory address to
+  the virtual disk at the specified sector.
+- *Notes:* The destination address is on top of the stack, followed by
+  the sector number. Data is first copied to a temporary buffer before
+  writing.
+- *Example:*
+  #+begin_example
+  0x2000  ; Source address
+  16      ; Sector 16
+  disk!
+  #+end_example
diff --git a/doc/opcodes_20_29.org b/doc/opcodes_20_29.org
new file mode 100644 (file)
index 0000000..241f2ad
--- /dev/null
@@ -0,0 +1,194 @@
+#+SETUPFILE: ~/.emacs.d/org-styles/html/darksun.theme
+#+TITLE: Fifth - virtual machine opcodes 20 -- 29
+#+AUTHOR: Svjatoslav Agejenko
+#+LANGUAGE: en
+
+#+OPTIONS: H:20 num:20
+#+OPTIONS: author:nil
+
+#+begin_export html
+<style>
+  .flex-center {
+    display: flex;            /* activate flexbox */
+    justify-content: center;  /* horizontally center anything inside   */
+  }
+
+  .flex-center video {
+    width: min(90%, 1000px); /* whichever is smaller wins */
+    height: auto;            /* preserve aspect ratio */
+  }
+
+  .responsive-img {
+    width: min(100%, 1000px);
+    height: auto;
+  }
+</style>
+#+end_export
+
+
+* 20: @
+:PROPERTIES:
+:CUSTOM_ID: section-2
+:ID:       0a54f24b-e62a-4244-85e1-855a0007c81e
+:END:
+- *Stack Effect:* =addr -- value=
+- *Description:* Reads a 32-bit value from the specified memory address.
+  Replaces the address on the stack with the value.
+- *Notes:* The address is adjusted by =xms_addr= before reading. This is
+  the 32-bit equivalent of =c@=.
+- *Example:*
+  #+begin_example
+  0x1000  ; Read 32-bit value from address 0x1000
+  @
+  #+end_example
+
+* 21: !
+:PROPERTIES:
+:CUSTOM_ID: section-3
+:ID:       50e0c841-d678-41b4-be5a-1bab792f367d
+:END:
+- *Stack Effect:* =value addr --=
+- *Description:* Stores a 32-bit value to the specified memory address.
+- *Notes:* Takes two values: the value to store and the address. The
+  address is adjusted by =xms_addr= before writing.
+- *Example:*
+  #+begin_example
+  0x12345678  ; Value to store
+  0x1000      ; Address to store to
+  !
+  #+end_example
+
+* 22: over
+:PROPERTIES:
+:CUSTOM_ID: over
+:ID:       29828b20-b14d-41ff-9705-ca576c352fb4
+:END:
+- *Stack Effect:* =n1 n2 -- n1 n2 n1=
+- *Description:* Duplicates the second item on the data stack, placing
+  it on top.
+- *Notes:* Commonly used to access the second item without popping the
+  top item.
+- *Example:*
+  #+begin_example
+  1 2
+  over
+  #+end_example
+  After execution, stack contains 1 2 1.
+
+* 23: swap
+:PROPERTIES:
+:CUSTOM_ID: swap
+:ID:       905894ae-d687-47cd-add0-f1904179a8a0
+:END:
+- *Stack Effect:* =n1 n2 -- n2 n1=
+- *Description:* Swaps the top two values on the data stack.
+- *Notes:* Essential for reordering stack items during complex
+  operations.
+- *Example:*
+  #+begin_example
+  1 2
+  swap
+  #+end_example
+  After execution, stack contains 2 1.
+
+* 24: +
+:PROPERTIES:
+:CUSTOM_ID: section-4
+:ID:       bf4434bb-91a5-40c1-93de-90a0e05a50ec
+:END:
+- *Stack Effect:* =n1 n2 -- n1+n2=
+- *Description:* Adds the top two values on the data stack. The result
+  replaces both values.
+- *Notes:* Performs unsigned 32-bit addition. The top value (n1) is
+  added to the second value (n2).
+- *Example:*
+  #+begin_example
+  1 2
+  +
+  #+end_example
+  After execution, stack contains 3.
+
+* 25: -
+:PROPERTIES:
+:CUSTOM_ID: section-5
+:ID:       9afc77fc-ecee-4a69-b1d2-f511e64a0d72
+:END:
+- *Stack Effect:* =n1 n2 -- n2-n1=
+- *Description:* Subtracts the top value from the second value on the
+  data stack. The result replaces both values.
+- *Notes:* Performs unsigned 32-bit subtraction. The second value (n2)
+  minus the top value (n1).
+- *Example:*
+  #+begin_example
+  1 2
+  -
+  #+end_example
+  After execution, stack contains 1 (2 - 1).
+
+* 26: *
+:PROPERTIES:
+:CUSTOM_ID: section-6
+:ID:       85833e5c-e3ae-41a7-ad3d-6e9f0ecc9cdb
+:END:
+- *Stack Effect:* =n1 n2 -- n1*n2=
+- *Description:* Multiplies the top two values on the data stack. The
+  result replaces both values.
+- *Notes:* Uses 32-bit signed multiplication (IMUL). The top value (n1)
+  is multiplied by the second value (n2).
+- *Example:*
+  #+begin_example
+  2 3
+  *
+  #+end_example
+  After execution, stack contains 6.
+
+* 27: /
+:PROPERTIES:
+:CUSTOM_ID: section-7
+:ID:       e5ff13c7-a9e6-4035-8efd-220d05381bf1
+:END:
+- *Stack Effect:* =n1 n2 -- n2/n1=
+- *Description:* Divides the second value by the top value on the data
+  stack. The quotient replaces both values.
+- *Notes:* Uses signed integer division (IDIV). The second value (n2) is
+  divided by the top value (n1).
+- *Example:*
+  #+begin_example
+  2 6
+  /
+  #+end_example
+  After execution, stack contains 3 (6 / 2).
+
+* 28: >
+:PROPERTIES:
+:CUSTOM_ID: section-8
+:ID:       abcc14d3-6cbf-46c3-8a93-ee7180f350d4
+:END:
+- *Stack Effect:* =n1 n2 -- result=
+- *Description:* Compares the second value (n1) with the top value (n2).
+  Returns -1 (true) if n1 > n2, otherwise 0.
+- *Notes:* The comparison is between the second item (n1) and top item
+  (n2) on the stack.
+- *Example:*
+  #+begin_example
+  2 3
+  >
+  #+end_example
+  After execution, stack contains 0 (since 2 < 3).
+
+* 29: <
+:PROPERTIES:
+:CUSTOM_ID: section-9
+:ID:       68362f38-c9e4-43f8-809c-8e15725a58c8
+:END:
+- *Stack Effect:* =n1 n2 -- result=
+- *Description:* Compares the second value (n1) with the top value (n2).
+  Returns -1 (true) if n1 < n2, otherwise 0.
+- *Notes:* The comparison is between the second item (n1) and top item
+  (n2) on the stack.
+- *Example:*
+  #+begin_example
+  2 3
+  <
+  #+end_example
+  After execution, stack contains -1 (since 2 < 3).
diff --git a/doc/opcodes_30_39.org b/doc/opcodes_30_39.org
new file mode 100644 (file)
index 0000000..4476b1e
--- /dev/null
@@ -0,0 +1,194 @@
+#+SETUPFILE: ~/.emacs.d/org-styles/html/darksun.theme
+#+TITLE: Fifth - virtual machine opcodes 30 -- 39
+#+AUTHOR: Svjatoslav Agejenko
+#+LANGUAGE: en
+
+#+OPTIONS: H:20 num:20
+#+OPTIONS: author:nil
+
+#+begin_export html
+<style>
+  .flex-center {
+    display: flex;            /* activate flexbox */
+    justify-content: center;  /* horizontally center anything inside   */
+  }
+
+  .flex-center video {
+    width: min(90%, 1000px); /* whichever is smaller wins */
+    height: auto;            /* preserve aspect ratio */
+  }
+
+  .responsive-img {
+    width: min(100%, 1000px);
+    height: auto;
+  }
+</style>
+#+end_export
+
+
+* 30: not
+:PROPERTIES:
+:CUSTOM_ID: not
+:ID:       21994321-a1c6-42f6-9682-d5a3fbabb88a
+:END:
+- *Stack Effect:* =n -- ~n=
+- *Description:* Performs a bitwise NOT operation on the top value of
+  the data stack.
+- *Notes:* Inverts all bits of the dword at the top of the stack.
+- *Example:*
+  #+begin_example
+  0x0000FFFF
+  not
+  #+end_example
+  After execution, stack contains 0xFFFF0000.
+
+* 31: i
+:PROPERTIES:
+:CUSTOM_ID: i
+:ID:       61fbdd36-4384-44a6-b162-b4e998c4c191
+:END:
+- *Stack Effect:* =-- r=
+- *Description:* Pushes the top value from the return stack onto the
+  data stack.
+- *Notes:* Commonly used to access loop counters or subroutine
+  parameters.
+- *Example:*
+  #+begin_example
+  42
+  push
+  i
+  #+end_example
+  After execution, data stack contains 42.
+
+* 32: cprt@
+:PROPERTIES:
+:CUSTOM_ID: cprt
+:ID:       78c1ac50-9c26-4132-8e02-8311331f2a1c
+:END:
+- *Stack Effect:* =port -- byte=
+- *Description:* Reads a byte from the specified hardware I/O port.
+- *Notes:* Uses IN instruction to read from the port. Replaces the port
+  address with the read byte.
+- *Example:*
+  #+begin_example
+  0x60  ; Keyboard port
+  cprt@
+  #+end_example
+
+* 33: cprt!
+:PROPERTIES:
+:CUSTOM_ID: cprt-1
+:ID:       cfa8550e-bf8b-4d44-a3d1-9ba8ad183147
+:END:
+- *Stack Effect:* =byte port --=
+- *Description:* Writes a byte to the specified hardware I/O port.
+- *Notes:* Uses OUT instruction to write to the port. Consumes both the
+  byte and port address.
+- *Example:*
+  #+begin_example
+  0x42  ; Byte to write
+  0x60  ; Keyboard port
+  cprt!
+  #+end_example
+
+* 34: i2
+:PROPERTIES:
+:CUSTOM_ID: i2
+:ID:       c3758859-c82e-40c1-9e92-87e5ef410cd2
+:END:
+- *Stack Effect:* =-- r2=
+- *Description:* Pushes the second value from the return stack onto the
+  data stack.
+- *Notes:* Useful for accessing deeper items in the return stack without
+  popping.
+- *Example:*
+  #+begin_example
+  1 2
+  push push
+  i2
+  #+end_example
+  After execution, data stack contains 1.
+
+* 35: i3
+:PROPERTIES:
+:CUSTOM_ID: i3
+:ID:       304cadf7-9725-4e2d-8634-2e67b5ad49f3
+:END:
+- *Stack Effect:* =-- r3=
+- *Description:* Pushes the third value from the return stack onto the
+  data stack.
+- *Notes:* Allows access to the third item in the return stack for
+  deeper subroutine contexts.
+- *Example:*
+  #+begin_example
+  1 2 3
+  push push push
+  i3
+  #+end_example
+  After execution, data stack contains 1.
+
+* 36: shl
+:PROPERTIES:
+:CUSTOM_ID: shl
+:ID:       978d1b75-3a1d-476f-8cdb-d3a6ee40b3f5
+:END:
+- *Stack Effect:* =value shift -- result=
+- *Description:* Shifts the top value left by the specified number of
+  bits.
+- *Notes:* The shift amount is the top item, and the value to shift is
+  the second item. Uses SHL instruction.
+- *Example:*
+  #+begin_example
+  2  ; Shift amount
+  1  ; Value to shift
+  shl
+  #+end_example
+  After execution, stack contains 2 (1 << 2).
+
+* 37: shr
+:PROPERTIES:
+:CUSTOM_ID: shr
+:ID:       9dbfcd07-6c34-41b7-b5dc-a33f0773e7cd
+:END:
+- *Stack Effect:* =value shift -- result=
+- *Description:* Shifts the top value right by the specified number of
+  bits.
+- *Notes:* The shift amount is the top item, and the value to shift is
+  the second item. Uses SHR instruction.
+- *Example:*
+  #+begin_example
+  1  ; Shift amount
+  2  ; Value to shift
+  shr
+  #+end_example
+  After execution, stack contains 1 (2 >> 1).
+
+* 38: or
+:PROPERTIES:
+:CUSTOM_ID: or
+:ID:       b38b971f-3a5f-4b16-9536-4193d2c5ae6b
+:END:
+- *Stack Effect:* =n1 n2 -- n1|n2=
+- *Description:* Performs a bitwise OR operation on the top two values.
+- *Notes:* The top value (n1) is ORed with the second value (n2).
+- *Example:*
+  #+begin_example
+  1 2
+  or
+  #+end_example
+  After execution, stack contains 3 (0b01 | 0b10).
+
+* 39: xor
+:PROPERTIES:
+:CUSTOM_ID: xor
+:ID:       e87a0d6d-89b0-4791-9500-654d60d99318
+:END:
+- *Stack Effect:* =n1 n2 -- n1^n2=
+- *Description:* Performs a bitwise XOR operation on the top two values.
+- *Notes:* The top value (n1) is XORed with the second value (n2).
+- *Example:*
+  #+begin_example
+  1 2
+  xor
+  #+end_example
+  After execution, stack contains 3 (0b01 ^ 0b10).
diff --git a/doc/opcodes_40_49.org b/doc/opcodes_40_49.org
new file mode 100644 (file)
index 0000000..27b2cf0
--- /dev/null
@@ -0,0 +1,314 @@
+#+SETUPFILE: ~/.emacs.d/org-styles/html/darksun.theme
+#+TITLE: Fifth - virtual machine opcodes 40 -- 49
+#+AUTHOR: Svjatoslav Agejenko
+#+LANGUAGE: en
+
+#+OPTIONS: H:20 num:20
+#+OPTIONS: author:nil
+
+#+begin_export html
+<style>
+  .flex-center {
+    display: flex;            /* activate flexbox */
+    justify-content: center;  /* horizontally center anything inside   */
+  }
+
+  .flex-center video {
+    width: min(90%, 1000px); /* whichever is smaller wins */
+    height: auto;            /* preserve aspect ratio */
+  }
+
+  .responsive-img {
+    width: min(100%, 1000px);
+    height: auto;
+  }
+</style>
+#+end_export
+
+
+* 40: vidmap
+:PROPERTIES:
+:CUSTOM_ID: vidmap
+:ID:       fe47ff6d-768f-4b05-9f8c-f52352c106f4
+:END:
+Stack Footprint
+: addr --
+
+Copies memory from the specified address to the video memory (VGA or
+VESA mode). Used for displaying images directly on the screen.
+
+Parameters:
+- *addr* (32-bit): Source memory address containing the image data to
+  copy to video memory.
+
+** Detailed Operation
+:PROPERTIES:
+:CUSTOM_ID: detailed-operation-4
+:END:
+1. *Video Memory Setup*:
+   - Set video memory segment to =0xA000= (VGA standard segment for
+     graphics mode).
+   - Initialize VESA-related variables (e.g., =gra= for page number).
+2. *VESA Page Mapping*:
+   - For each VESA page (up to 19 pages for 640x480x8 mode):
+     - Set VESA page using interrupt =0x10= with =AX = 0x4F05=.
+     - The page number is stored in =gra=.
+3. *Memory Copying*:
+   - For each page:
+     - Copy 4096 bytes (4KB) from source address to video memory.
+     - Use =STOSD= to write 32-bit words for efficiency.
+   - The source address is incremented by 4KB after each page.
+4. *Final Cleanup*:
+   - Restore original segments and clean up stack.
+
+** Example
+Copy a 640x480x8 image (307,200 bytes) from memory at =0x10000= to video
+memory:
+#+begin_example
+0x10000
+vidmap
+#+end_example
+
+** Notes
+
+- The operation assumes the video mode is set to VESA 640x480x8 (mode
+  =0x101=).
+- The exact number of pages copied depends on the video mode (19 pages
+  for 640x480x8).
+- Requires VESA BIOS support and proper initialization via
+  =set_vesa_mode=.
+
+* 41: mouse@
+:PROPERTIES:
+:CUSTOM_ID: mouse
+:ID:       b4bce653-d38f-45ed-82ec-13ca78c9860b
+:END:
+Stack Footprint:
+: -- x y buttons
+
+*Description:*
+
+Reads the current mouse position and button states from the mouse
+driver. Returns three values on the stack:
+- X-coordinate,
+- Y-coordinate,
+- button states.
+
+
+- *Returns*:
+  - *x* (32-bit): Current X-coordinate of the mouse cursor (0-based).
+  - *y* (32-bit): Current Y-coordinate of the mouse cursor (0-based).
+  - *buttons* (32-bit): Bitmask of button states:
+    - Bit 0: Left button (1 = pressed)
+    - Bit 1: Right button (1 = pressed)
+    - Bit 2: Middle button (1 = pressed)
+
+*Example:*
+
+#+begin_example
+mouse@
+#+end_example
+After execution, stack contains buttons (top), y, x (bottom).
+
+* 42: vidput - put image1 into image2, at location x, y
+:PROPERTIES:
+:CUSTOM_ID: ID-238e8b03-57b6-424d-bfee-b6bb652cefbc
+:ID:       238e8b03-57b6-424d-bfee-b6bb652cefbc
+:END:
+Stack Footprint:
+: addr1 addr2 x y --=
+
+Copies a portion of image1 to image2 at the specified (x, y)
+coordinates with clipping. Unlike =tvidput=, there is no transparency
+support - every pixel is copied regardless of value.
+
+*Parameters:*
+
+- *addr1* (32-bit): Address of the source image structure (width,
+  height, data address).
+- *addr2* (32-bit): Address of the destination image structure (width,
+  height, data address).
+- *x* (32-bit): X-coordinate in the destination image where the copy
+  starts.
+- *y* (32-bit): Y-coordinate in the destination image where the copy
+  starts.
+
+*Image Structure Format:*
+
+Identical to =tvidput=:
+- *Offset 0*: Image width (32-bit)
+- *Offset 4*: Image height (32-bit)
+- *Offset 8*: Base address of image data (32-bit pointer)
+
+*Example:*
+#+begin_example
+0x1000  ; Source image structure
+0x2000  ; Destination image structure
+50      ; x
+50      ; y
+vidput
+#+end_example
+
+* 43: cmove - copy memory array
+:PROPERTIES:
+:CUSTOM_ID: ID-79e1916f-4103-42cc-ac10-bb1ee776ed50
+:ID:       79e1916f-4103-42cc-ac10-bb1ee776ed50
+:END:
+
+- *Stack Effect:*
+: addr1 addr2 len --
+
+Copies =len= bytes from =addr1= to =addr2=. Handles overlapping memory
+regions correctly.
+
+- *Notes:* If =addr1 > addr2=, copies backwards to avoid data
+  corruption; otherwise copies forwards.
+- *Example:*
+  #+begin_example
+  100  ; Length
+  0x2000  ; Destination address
+  0x1000  ; Source address
+  cmove
+  #+end_example
+
+* 44: cfill
+:PROPERTIES:
+:CUSTOM_ID: cfill
+:ID:       fecb9438-d9d2-4224-a017-cc87dba9209e
+:END:
+- *Stack Effect:* =byte addr len --=
+- *Description:* Fills =len= bytes of memory starting at =addr= with the
+  specified byte value.
+- *Notes:* Simple byte-by-byte filling operation. Used for initializing
+  memory regions.
+- *Example:*
+  #+begin_example
+  0xFF  ; Fill byte
+  0x1000  ; Start address
+  100  ; Length
+  cfill
+  #+end_example
+
+* 45: tvidput - put image with transparency support
+:PROPERTIES:
+:CUSTOM_ID: ID-ab45247c-44c3-464d-9e2a-337f483b4616
+:ID:       ab45247c-44c3-464d-9e2a-337f483b4616
+:END:
+Stack Footprint:
+: addr1 addr2 x y --
+
+Copies a portion of image1 to image2 at the specified (x, y)
+coordinates with transparency support. Pixels in image1 with value 255
+(0xFF) are treated as transparent and are not copied to the
+destination.
+
+*Parameters:*
+
+- *addr1* (32-bit): Address of the source image structure (contains
+  width, height, and data address).
+- *addr2* (32-bit): Address of the destination image structure (contains
+  width, height, and data address).
+- *x* (32-bit): X-coordinate in the destination image where the copy
+  starts.
+- *y* (32-bit): Y-coordinate in the destination image where the copy
+  starts.
+
+*Image Structure Format:*
+
+Each image structure is stored in memory as follows:
+- *Offset 0*: Image width (32-bit integer)
+- *Offset 4*: Image height (32-bit integer)
+- *Offset 8*: Base address of image data (32-bit pointer)
+
+*Example:*
+#+begin_example
+0x1000  ; Source image structure
+0x2000  ; Destination image structure
+50      ; x
+50      ; y
+tvidput
+#+end_example
+
+*Notes:*
+
+- Transparency is fixed at value 255 (0xFF).
+- The operation handles clipping automatically to ensure the copy stays
+  within destination bounds.
+- Source and destination image structures must be properly formatted.
+
+* 46: depth
+:PROPERTIES:
+:CUSTOM_ID: ID-77fa76d3-9cd0-49c1-882c-f30383347352
+:ID:       77fa76d3-9cd0-49c1-882c-f30383347352
+:END:
+- *Stack Effect:* =-- depth=
+- *Description:* Pushes the current depth (number of items) on the data
+  stack onto the stack.
+- *Notes:* Calculated by comparing the data stack pointer to the base
+  address of the stack.
+- *Example:*
+  #+begin_example
+  1 2 3
+  depth
+  #+end_example
+  After execution, stack contains 3 (depth) followed by 1 2 3.
+
+* 47: charput - draw text character
+:PROPERTIES:
+:CUSTOM_ID: ID-4bb479cf-aae0-4128-9868-f016c286a162
+:ID:       4bb479cf-aae0-4128-9868-f016c286a162
+:END:
+
+Stack Footprint:
+=colorfg colorbg addrsrc addrdest x y --=
+
+
+Draws an 8x8 character from a source memory buffer to a destination
+image buffer at the specified (x, y) coordinates. Each byte in the
+source buffer represents one row of the character (8 bits per row),
+where each bit determines whether to use the foreground or background
+color for that pixel.
+
+*Parameters:*
+
+- *colorfg* (1 byte): Foreground color value (0-255). Typically a
+  grayscale value where 0 is black and 255 is white.
+- *colorbg* (1 byte): Background color value (0-255).
+- *addrsrc* (32-bit): Memory address pointing to 8 bytes of character
+  data. Each byte represents one row of the character (8 bits per row).
+- *addrdest* (32-bit): Base address of the destination image buffer in
+  memory.
+- *x* (32-bit): X-coordinate (0-based) where the character's left edge
+  starts.
+- *y* (32-bit): Y-coordinate (0-based) where the character's top edge
+  starts.
+
+*Example:*
+
+TODO: Create dedicated page that explains this instruction in
+depth. Link to this new page from current one.
+
+#+begin_example
+0xFF  ; White foreground
+0x00  ; Black background
+0x3000  ; Character data address
+0x5000  ; Video memory address
+20      ; y
+10      ; x
+charput
+#+end_example
+
+Character data for 'A' (ASCII 65):
+#+begin_example
+0x00, 0x18, 0x24, 0x24, 0x24, 0x3C, 0x24, 0x24
+#+end_example
+
+- Each byte represents a row:
+  - Row 0: =0x00= → all pixels black
+  - Row 1: =0x18= → bits 3-4 set (binary =00011000=)
+  - Row 2: =0x24= → bits 2 and 5 set (binary =00100100=)
+  - Row 3: =0x24= → same as row 2
+  - Row 4: =0x24= → same as row 2
+  - Row 5: =0x3C= → bits 2-5 set (binary =00111100=)
+  - Row 6: =0x24= → same as row 2
+  - Row 7: =0x24= → same as row 2
index 7bda79f..0650773 100644 (file)
@@ -122,812 +122,43 @@ in FIFTH programming language):
 |  7 | [[id:523f93a3-359e-4a6d-b296-df25008db403][1-]]       | n -- n-1              | Decrement top of data stack by 1                         |                                                                     |
 |  8 | [[id:2a6a449a-fc76-421c-a81c-c2024a15fc78][dup]]      | n -- n n              | Duplicate top of data stack                              |                                                                     |
 |  9 | [[id:4600dbeb-1833-4e7d-af7e-f6cc6c98d022][drop]]     | n --                  | Drop top of data stack                                   |                                                                     |
-| 10 | [[#if][if]]       | n --                  | Jump to address if top of stack is zero                  |                                                                     |
-| 11 | [[#ret][ret]]      |                       | Return from subroutine (pop return address)              |                                                                     |
-| 12 | [[#c][c@]]       | addr -- byte          | Read byte from memory at specified address               |                                                                     |
-| 13 | [[#c-1][c!]]       | byte addr --          | Store byte to specified memory address                   |                                                                     |
-| 14 | [[#push][push]]     | n --                  | Move top of data stack to return stack                   |                                                                     |
+| 10 | [[id:d6f834b6-9a37-4414-91b3-62b3e1d920c1][if]]       | n --                  | Jump to address if top of stack is zero                  |                                                                     |
+| 11 | [[id:6e683977-a985-4bb8-9d2c-c860d30e1df6][ret]]      |                       | Return from subroutine (pop return address)              |                                                                     |
+| 12 | [[id:a2ce44f7-b661-44e0-909b-644ff52aa38e][c@]]       | addr -- byte          | Read byte from memory at specified address               |                                                                     |
+| 13 | [[id:f129ef87-a31a-40fe-b8d3-984da2db90e2][c!]]       | byte addr --          | Store byte to specified memory address                   |                                                                     |
+| 14 | [[id:e4bcbaf1-7724-4051-b19c-1aa7cd06eae6][push]]     | n --                  | Move top of data stack to return stack                   |                                                                     |
 | 15 | [[id:21871d09-4d58-440f-8c94-231105aa4e3f][pop]]      | -- n                  | Move top of return stack to data stack                   |                                                                     |
 | 16 | <unused> |                       |                                                          |                                                                     |
-| 17 | [[#rot][rot]]      | n1 n2 n3 -- n2 n3 n1  | Rotate top three stack elements                          |                                                                     |
-| 18 | [[#disk][disk@]]    | sector addr --        | Read 1KB from disk into RAM at specified address         |                                                                     |
-| 19 | [[#disk-1][disk!]]    | addr sector --        | Write 1KB from RAM to disk at specified sector           |                                                                     |
-| 20 | [[#section-2][@]]        | addr -- n             | Read 32-bit value from memory                            |                                                                     |
-| 21 | [[#section-3][!]]        | n addr --             | Store 32-bit value to memory                             |                                                                     |
-| 22 | [[#over][over]]     | n1 n2 -- n1 n2 n1     | Duplicate second item on data stack                      |                                                                     |
-| 23 | [[#swap][swap]]     | n1 n2 -- n2 n1        | Swap top two items on data stack                         |                                                                     |
-| 24 | [[#section-4][+]]        | n1 n2 -- n1+n2        | Add top two items on data stack                          |                                                                     |
-| 25 | [[#section-5][-]]        | n1 n2 -- n1-n2        | Subtract second item from top item on data stack         | TODO: verify argument order                                         |
-| 26 | [[#section-6][*]]        | n1 n2 -- n1*n2        | Multiply top two items on data stack                     |                                                                     |
-| 27 | [[#section-7][/]]        | n1 n2 -- n1/n2        | Divide top item by second item on data stack             | TODO: verify argument order                                         |
-| 28 | [[#section-8][>]]        | n1 n2 -- result       | Compare n1 > n2 (returns true, false otherwise)          | TODO: document, what true and false means                           |
-| 29 | [[#section-9][<]]        | n1 n2 -- result       | Compare n1 < n2 (returns true, false otherwise)          | TODO: document, what true and false means                           |
-| 30 | [[#not][not]]      | n -- ~n               | Bitwise NOT on top of data stack                         |                                                                     |
-| 31 | [[#i][i]]        | -- n                  | Push top of return stack to data stack                   |                                                                     |
-| 32 | [[#cprt][cprt@]]    | port -- byte          | Read byte from hardware I/O port                         |                                                                     |
-| 33 | [[#cprt-1][cprt!]]    | byte port --          | Write byte to hardware I/O port                          |                                                                     |
-| 34 | [[#i2][i2]]       | -- n                  | Push second item from return stack to data stack         |                                                                     |
-| 35 | [[#i3][i3]]       | -- n                  | Push third item from return stack to data stack          |                                                                     |
-| 36 | [[#shl][shl]]      | value shift -- result | Left shift value by shift amount                         | TODO: Document example. What happens to bits that are shifted away? |
-| 37 | [[#shr][shr]]      | value shift -- result | Right shift value by shift amount                        |                                                                     |
-| 38 | [[#or][or]]       | n1 n2 -- result       | Bitwise OR of top two items on data stack                |                                                                     |
-| 39 | [[#xor][xor]]      | n1 n2 -- result       | Bitwise XOR of top two items on data stack               |                                                                     |
-| 40 | [[#vidmap][vidmap]]   | addr --               | Copy memory to video memory                              |                                                                     |
-| 41 | [[#mouse][mouse@]]   | -- x y buttons        | Read mouse coordinates and button states                 |                                                                     |
+| 17 | [[id:4cee73f7-c105-4b96-9380-ff89bd7fedad][rot]]      | n1 n2 n3 -- n2 n3 n1  | Rotate top three stack elements                          |                                                                     |
+| 18 | [[id:bed1aa27-66ac-4c73-bbb9-e49ff2aa67c5][disk@]]    | sector addr --        | Read 1KB from disk into RAM at specified address         |                                                                     |
+| 19 | [[id:02eda775-e483-4057-b809-de36d586579b][disk!]]    | addr sector --        | Write 1KB from RAM to disk at specified sector           |                                                                     |
+| 20 | [[id:0a54f24b-e62a-4244-85e1-855a0007c81e][@]]        | addr -- n             | Read 32-bit value from memory                            |                                                                     |
+| 21 | [[id:50e0c841-d678-41b4-be5a-1bab792f367d][!]]        | n addr --             | Store 32-bit value to memory                             |                                                                     |
+| 22 | [[id:29828b20-b14d-41ff-9705-ca576c352fb4][over]]     | n1 n2 -- n1 n2 n1     | Duplicate second item on data stack                      |                                                                     |
+| 23 | [[id:905894ae-d687-47cd-add0-f1904179a8a0][swap]]     | n1 n2 -- n2 n1        | Swap top two items on data stack                         |                                                                     |
+| 24 | [[id:bf4434bb-91a5-40c1-93de-90a0e05a50ec][+]]        | n1 n2 -- n1+n2        | Add top two items on data stack                          |                                                                     |
+| 25 | [[id:9afc77fc-ecee-4a69-b1d2-f511e64a0d72][-]]        | n1 n2 -- n1-n2        | Subtract second item from top item on data stack         | TODO: verify argument order                                         |
+| 26 | [[id:85833e5c-e3ae-41a7-ad3d-6e9f0ecc9cdb][*]]        | n1 n2 -- n1*n2        | Multiply top two items on data stack                     |                                                                     |
+| 27 | [[id:e5ff13c7-a9e6-4035-8efd-220d05381bf1][/]]        | n1 n2 -- n2/n1        | Divide top item by second item on data stack             | TODO: verify argument order                                         |
+| 28 | [[id:abcc14d3-6cbf-46c3-8a93-ee7180f350d4][>]]        | n1 n2 -- result       | Compare n1 > n2 (returns true, false otherwise)          | TODO: document, what true and false means                           |
+| 29 | [[id:68362f38-c9e4-43f8-809c-8e15725a58c8][<]]        | n1 n2 -- result       | Compare n1 < n2 (returns true, false otherwise)          | TODO: document, what true and false means                           |
+| 30 | [[id:21994321-a1c6-42f6-9682-d5a3fbabb88a][not]]      | n -- ~n               | Bitwise NOT on top of data stack                         |                                                                     |
+| 31 | [[id:61fbdd36-4384-44a6-b162-b4e998c4c191][i]]        | -- n                  | Push top of return stack to data stack                   |                                                                     |
+| 32 | [[id:78c1ac50-9c26-4132-8e02-8311331f2a1c][cprt@]]    | port -- byte          | Read byte from hardware I/O port                         |                                                                     |
+| 33 | [[id:cfa8550e-bf8b-4d44-a3d1-9ba8ad183147][cprt!]]    | byte port --          | Write byte to hardware I/O port                          |                                                                     |
+| 34 | [[id:c3758859-c82e-40c1-9e92-87e5ef410cd2][i2]]       | -- n                  | Push second item from return stack to data stack         |                                                                     |
+| 35 | [[id:304cadf7-9725-4e2d-8634-2e67b5ad49f3][i3]]       | -- n                  | Push third item from return stack to data stack          |                                                                     |
+| 36 | [[id:978d1b75-3a1d-476f-8cdb-d3a6ee40b3f5][shl]]      | value shift -- result | Left shift value by shift amount                         | TODO: Document example. What happens to bits that are shifted away? |
+| 37 | [[id:9dbfcd07-6c34-41b7-b5dc-a33f0773e7cd][shr]]      | value shift -- result | Right shift value by shift amount                        |                                                                     |
+| 38 | [[id:b38b971f-3a5f-4b16-9536-4193d2c5ae6b][or]]       | n1 n2 -- result       | Bitwise OR of top two items on data stack                |                                                                     |
+| 39 | [[id:e87a0d6d-89b0-4791-9500-654d60d99318][xor]]      | n1 n2 -- result       | Bitwise XOR of top two items on data stack               |                                                                     |
+| 40 | [[id:fe47ff6d-768f-4b05-9f8c-f52352c106f4][vidmap]]   | addr --               | Copy memory to video memory                              |                                                                     |
+| 41 | [[id:b4bce653-d38f-45ed-82ec-13ca78c9860b][mouse@]]   | -- x y buttons        | Read mouse coordinates and button states                 |                                                                     |
 | 42 | [[id:238e8b03-57b6-424d-bfee-b6bb652cefbc][vidput]]   | addr1 addr2 x y --    | Blit image1 to image2 at (x,y) without transparency      |                                                                     |
 | 43 | [[id:79e1916f-4103-42cc-ac10-bb1ee776ed50][cmove]]    | addr1 addr2 len --    | Copy memory block from addr1 to addr2                    |                                                                     |
-| 44 | [[#cfill][cfill]]    | byte addr len --      | Fill memory with specified byte value                    |                                                                     |
+| 44 | [[id:fecb9438-d9d2-4224-a017-cc87dba9209e][cfill]]    | byte addr len --      | Fill memory with specified byte value                    |                                                                     |
 | 45 | [[id:ab45247c-44c3-464d-9e2a-337f483b4616][tvidput]]  | addr1 addr2 x y --    | Blit image1 to image2 at (x,y) with transparency support |                                                                     |
 | 46 | [[id:77fa76d3-9cd0-49c1-882c-f30383347352][depth]]    | -- depth              | Push current data stack depth                            |                                                                     |
 | 47 | [[id:4bb479cf-aae0-4128-9868-f016c286a162][charput]]  | fg bg src dest x y -- | Draw character from source buffer to destination buffer  |                                                                     |
 
-** if
-:PROPERTIES:
-:CUSTOM_ID: if
-:ID:       d6f834b6-9a37-4414-91b3-62b3e1d920c1
-:END:
-- *Stack Effect:* =n --=
-- *Description:* Pops the top value from the data stack. If the value is
-  zero, jumps to the address specified by the next 32-bit value.
-  Otherwise, skips the address.
-- *Notes:* Used for conditional branching. The address is added to
-  =xms_addr= for physical address conversion.
-- *Example:*
-  #+begin_example
-  0
-  0x1000  ; Jump target if zero
-  if
-  #+end_example
-
-** ret
-:PROPERTIES:
-:CUSTOM_ID: ret
-:ID:       6e683977-a985-4bb8-9d2c-c860d30e1df6
-:END:
-- *Stack Effect:* =--=
-- *Description:* Returns from a subroutine by popping the return address
-  from the return stack and jumping to it.
-- *Notes:* The return stack pointer is incremented after the jump.
-- *Example:*
-  #+begin_example
-  ret
-  #+end_example
-
-** c@
-:PROPERTIES:
-:CUSTOM_ID: c
-:ID:       a2ce44f7-b661-44e0-909b-644ff52aa38e
-:END:
-- *Stack Effect:* =addr -- byte=
-- *Description:* Reads a single byte from the specified memory address.
-  Replaces the address on the stack with the byte value.
-- *Notes:* The address is adjusted by =xms_addr= to convert to physical
-  memory before reading.
-- *Example:*
-  #+begin_example
-  0x1000  ; Read from address 0x1000
-  c@
-  #+end_example
-  After execution, stack contains the byte at address 0x1000.
-
-** c!
-:PROPERTIES:
-:CUSTOM_ID: c-1
-:ID:       f129ef87-a31a-40fe-b8d3-984da2db90e2
-:END:
-- *Stack Effect:* =byte addr --=
-- *Description:* Stores a byte value to the specified memory address.
-- *Notes:* Takes two values from the stack: the byte to store and the
-  address. The address is adjusted by =xms_addr= before writing.
-- *Example:*
-  #+begin_example
-  0x42  ; Byte to store
-  0x1000  ; Address to store to
-  c!
-  #+end_example
-
-** push
-:PROPERTIES:
-:CUSTOM_ID: push
-:ID:       e4bcbaf1-7724-4051-b19c-1aa7cd06eae6
-:END:
-- *Stack Effect:* =n --=
-- *Description:* Moves the top value from the data stack to the return
-  stack.
-- *Notes:* Used for transferring values between the two stacks without
-  modifying the value.
-- *Example:*
-  #+begin_example
-  42
-  push
-  #+end_example
-  After execution, data stack is empty and return stack contains 42.
-
-** pop
-:PROPERTIES:
-:CUSTOM_ID: ID-21871d09-4d58-440f-8c94-231105aa4e3f
-:ID:       21871d09-4d58-440f-8c94-231105aa4e3f
-:END:
-- *Stack Effect:* =-- n=
-- *Description:* Moves the top value from the return stack to the data
-  stack.
-- *Notes:* Used for transferring values between the two stacks without
-  modifying the value.
-- *Example:*
-  #+begin_example
-  pop
-  #+end_example
-  After execution, data stack contains the value that was on top of the return stack.
-
-** rot
-:PROPERTIES:
-:CUSTOM_ID: rot
-:ID:       4cee73f7-c105-4b96-9380-ff89bd7fedad
-:END:
-- *Stack Effect:* =n1 n2 n3 -- n2 n3 n1=
-- *Description:* Rotates the top three values on the data stack. The
-  third item becomes the top, the top becomes the second, and the second
-  becomes the third.
-- *Notes:* Useful for reordering stack items without temporary storage.
-- *Example:*
-  #+begin_example
-  1 2 3
-  rot
-  #+end_example
-  After execution, stack contains 2 3 1.
-
-** disk@
-:PROPERTIES:
-:CUSTOM_ID: disk
-:ID:       bed1aa27-66ac-4c73-bbb9-e49ff2aa67c5
-:END:
-- *Stack Effect:* =sector addr --=
-- *Description:* Reads 1KB of data from the virtual disk at the
-  specified sector into the specified memory address.
-- *Notes:* The sector number is the top of the stack, followed by the
-  destination address. The disk is accessed via DOS interrupt calls.
-- *Example:*
-  #+begin_example
-  16  ; Sector 16
-  0x2000  ; Destination address
-  disk@
-  #+end_example
-
-** disk!
-:PROPERTIES:
-:CUSTOM_ID: disk-1
-:ID:       02eda775-e483-4057-b809-de36d586579b
-:END:
-- *Stack Effect:* =addr sector --=
-- *Description:* Writes 1KB of data from the specified memory address to
-  the virtual disk at the specified sector.
-- *Notes:* The destination address is on top of the stack, followed by
-  the sector number. Data is first copied to a temporary buffer before
-  writing.
-- *Example:*
-  #+begin_example
-  0x2000  ; Source address
-  16      ; Sector 16
-  disk!
-  #+end_example
-
-** @
-:PROPERTIES:
-:CUSTOM_ID: section-2
-:ID:       0a54f24b-e62a-4244-85e1-855a0007c81e
-:END:
-- *Stack Effect:* =addr -- value=
-- *Description:* Reads a 32-bit value from the specified memory address.
-  Replaces the address on the stack with the value.
-- *Notes:* The address is adjusted by =xms_addr= before reading. This is
-  the 32-bit equivalent of =c@=.
-- *Example:*
-  #+begin_example
-  0x1000  ; Read 32-bit value from address 0x1000
-  @
-  #+end_example
-
-** !
-:PROPERTIES:
-:CUSTOM_ID: section-3
-:ID:       50e0c841-d678-41b4-be5a-1bab792f367d
-:END:
-- *Stack Effect:* =value addr --=
-- *Description:* Stores a 32-bit value to the specified memory address.
-- *Notes:* Takes two values: the value to store and the address. The
-  address is adjusted by =xms_addr= before writing.
-- *Example:*
-  #+begin_example
-  0x12345678  ; Value to store
-  0x1000      ; Address to store to
-  !
-  #+end_example
-
-** over
-:PROPERTIES:
-:CUSTOM_ID: over
-:ID:       29828b20-b14d-41ff-9705-ca576c352fb4
-:END:
-- *Stack Effect:* =n1 n2 -- n1 n2 n1=
-- *Description:* Duplicates the second item on the data stack, placing
-  it on top.
-- *Notes:* Commonly used to access the second item without popping the
-  top item.
-- *Example:*
-  #+begin_example
-  1 2
-  over
-  #+end_example
-  After execution, stack contains 1 2 1.
-
-** swap
-:PROPERTIES:
-:CUSTOM_ID: swap
-:ID:       905894ae-d687-47cd-add0-f1904179a8a0
-:END:
-- *Stack Effect:* =n1 n2 -- n2 n1=
-- *Description:* Swaps the top two values on the data stack.
-- *Notes:* Essential for reordering stack items during complex
-  operations.
-- *Example:*
-  #+begin_example
-  1 2
-  swap
-  #+end_example
-  After execution, stack contains 2 1.
-
-** +
-:PROPERTIES:
-:CUSTOM_ID: section-4
-:ID:       bf4434bb-91a5-40c1-93de-90a0e05a50ec
-:END:
-- *Stack Effect:* =n1 n2 -- n1+n2=
-- *Description:* Adds the top two values on the data stack. The result
-  replaces both values.
-- *Notes:* Performs unsigned 32-bit addition. The top value (n1) is
-  added to the second value (n2).
-- *Example:*
-  #+begin_example
-  1 2
-  +
-  #+end_example
-  After execution, stack contains 3.
-
-** -
-:PROPERTIES:
-:CUSTOM_ID: section-5
-:ID:       9afc77fc-ecee-4a69-b1d2-f511e64a0d72
-:END:
-- *Stack Effect:* =n1 n2 -- n2-n1=
-- *Description:* Subtracts the top value from the second value on the
-  data stack. The result replaces both values.
-- *Notes:* Performs unsigned 32-bit subtraction. The second value (n2)
-  minus the top value (n1).
-- *Example:*
-  #+begin_example
-  1 2
-  -
-  #+end_example
-  After execution, stack contains 1 (2 - 1).
-
-** *
-:PROPERTIES:
-:CUSTOM_ID: section-6
-:ID:       85833e5c-e3ae-41a7-ad3d-6e9f0ecc9cdb
-:END:
-- *Stack Effect:* =n1 n2 -- n1*n2=
-- *Description:* Multiplies the top two values on the data stack. The
-  result replaces both values.
-- *Notes:* Uses 32-bit signed multiplication (IMUL). The top value (n1)
-  is multiplied by the second value (n2).
-- *Example:*
-  #+begin_example
-  2 3
-  *
-  #+end_example
-  After execution, stack contains 6.
-
-** /
-:PROPERTIES:
-:CUSTOM_ID: section-7
-:ID:       e5ff13c7-a9e6-4035-8efd-220d05381bf1
-:END:
-- *Stack Effect:* =n1 n2 -- n2/n1=
-- *Description:* Divides the second value by the top value on the data
-  stack. The quotient replaces both values.
-- *Notes:* Uses signed integer division (IDIV). The second value (n2) is
-  divided by the top value (n1).
-- *Example:*
-  #+begin_example
-  2 6
-  /
-  #+end_example
-  After execution, stack contains 3 (6 / 2).
-
-** >
-:PROPERTIES:
-:CUSTOM_ID: section-8
-:ID:       abcc14d3-6cbf-46c3-8a93-ee7180f350d4
-:END:
-- *Stack Effect:* =n1 n2 -- result=
-- *Description:* Compares the second value (n1) with the top value (n2).
-  Returns -1 (true) if n1 > n2, otherwise 0.
-- *Notes:* The comparison is between the second item (n1) and top item
-  (n2) on the stack.
-- *Example:*
-  #+begin_example
-  2 3
-  >
-  #+end_example
-  After execution, stack contains 0 (since 2 < 3).
-
-** <
-:PROPERTIES:
-:CUSTOM_ID: section-9
-:ID:       68362f38-c9e4-43f8-809c-8e15725a58c8
-:END:
-- *Stack Effect:* =n1 n2 -- result=
-- *Description:* Compares the second value (n1) with the top value (n2).
-  Returns -1 (true) if n1 < n2, otherwise 0.
-- *Notes:* The comparison is between the second item (n1) and top item
-  (n2) on the stack.
-- *Example:*
-  #+begin_example
-  2 3
-  <
-  #+end_example
-  After execution, stack contains -1 (since 2 < 3).
-
-** not
-:PROPERTIES:
-:CUSTOM_ID: not
-:ID:       21994321-a1c6-42f6-9682-d5a3fbabb88a
-:END:
-- *Stack Effect:* =n -- ~n=
-- *Description:* Performs a bitwise NOT operation on the top value of
-  the data stack.
-- *Notes:* Inverts all bits of the dword at the top of the stack.
-- *Example:*
-  #+begin_example
-  0x0000FFFF
-  not
-  #+end_example
-  After execution, stack contains 0xFFFF0000.
-
-** i
-:PROPERTIES:
-:CUSTOM_ID: i
-:ID:       61fbdd36-4384-44a6-b162-b4e998c4c191
-:END:
-- *Stack Effect:* =-- r=
-- *Description:* Pushes the top value from the return stack onto the
-  data stack.
-- *Notes:* Commonly used to access loop counters or subroutine
-  parameters.
-- *Example:*
-  #+begin_example
-  42
-  push
-  i
-  #+end_example
-  After execution, data stack contains 42.
-
-** cprt@
-:PROPERTIES:
-:CUSTOM_ID: cprt
-:ID:       78c1ac50-9c26-4132-8e02-8311331f2a1c
-:END:
-- *Stack Effect:* =port -- byte=
-- *Description:* Reads a byte from the specified hardware I/O port.
-- *Notes:* Uses IN instruction to read from the port. Replaces the port
-  address with the read byte.
-- *Example:*
-  #+begin_example
-  0x60  ; Keyboard port
-  cprt@
-  #+end_example
-
-** cprt!
-:PROPERTIES:
-:CUSTOM_ID: cprt-1
-:ID:       cfa8550e-bf8b-4d44-a3d1-9ba8ad183147
-:END:
-- *Stack Effect:* =byte port --=
-- *Description:* Writes a byte to the specified hardware I/O port.
-- *Notes:* Uses OUT instruction to write to the port. Consumes both the
-  byte and port address.
-- *Example:*
-  #+begin_example
-  0x42  ; Byte to write
-  0x60  ; Keyboard port
-  cprt!
-  #+end_example
-
-** i2
-:PROPERTIES:
-:CUSTOM_ID: i2
-:ID:       c3758859-c82e-40c1-9e92-87e5ef410cd2
-:END:
-- *Stack Effect:* =-- r2=
-- *Description:* Pushes the second value from the return stack onto the
-  data stack.
-- *Notes:* Useful for accessing deeper items in the return stack without
-  popping.
-- *Example:*
-  #+begin_example
-  1 2
-  push push
-  i2
-  #+end_example
-  After execution, data stack contains 1.
-
-** i3
-:PROPERTIES:
-:CUSTOM_ID: i3
-:ID:       304cadf7-9725-4e2d-8634-2e67b5ad49f3
-:END:
-- *Stack Effect:* =-- r3=
-- *Description:* Pushes the third value from the return stack onto the
-  data stack.
-- *Notes:* Allows access to the third item in the return stack for
-  deeper subroutine contexts.
-- *Example:*
-  #+begin_example
-  1 2 3
-  push push push
-  i3
-  #+end_example
-  After execution, data stack contains 1.
-
-** shl
-:PROPERTIES:
-:CUSTOM_ID: shl
-:ID:       978d1b75-3a1d-476f-8cdb-d3a6ee40b3f5
-:END:
-- *Stack Effect:* =value shift -- result=
-- *Description:* Shifts the top value left by the specified number of
-  bits.
-- *Notes:* The shift amount is the top item, and the value to shift is
-  the second item. Uses SHL instruction.
-- *Example:*
-  #+begin_example
-  2  ; Shift amount
-  1  ; Value to shift
-  shl
-  #+end_example
-  After execution, stack contains 2 (1 << 2).
-
-** shr
-:PROPERTIES:
-:CUSTOM_ID: shr
-:ID:       9dbfcd07-6c34-41b7-b5dc-a33f0773e7cd
-:END:
-- *Stack Effect:* =value shift -- result=
-- *Description:* Shifts the top value right by the specified number of
-  bits.
-- *Notes:* The shift amount is the top item, and the value to shift is
-  the second item. Uses SHR instruction.
-- *Example:*
-  #+begin_example
-  1  ; Shift amount
-  2  ; Value to shift
-  shr
-  #+end_example
-  After execution, stack contains 1 (2 >> 1).
-
-** or
-:PROPERTIES:
-:CUSTOM_ID: or
-:ID:       b38b971f-3a5f-4b16-9536-4193d2c5ae6b
-:END:
-- *Stack Effect:* =n1 n2 -- n1|n2=
-- *Description:* Performs a bitwise OR operation on the top two values.
-- *Notes:* The top value (n1) is ORed with the second value (n2).
-- *Example:*
-  #+begin_example
-  1 2
-  or
-  #+end_example
-  After execution, stack contains 3 (0b01 | 0b10).
-
-** xor
-:PROPERTIES:
-:CUSTOM_ID: xor
-:ID:       e87a0d6d-89b0-4791-9500-654d60d99318
-:END:
-- *Stack Effect:* =n1 n2 -- n1^n2=
-- *Description:* Performs a bitwise XOR operation on the top two values.
-- *Notes:* The top value (n1) is XORed with the second value (n2).
-- *Example:*
-  #+begin_example
-  1 2
-  xor
-  #+end_example
-  After execution, stack contains 3 (0b01 ^ 0b10).
-
-** vidmap
-:PROPERTIES:
-:CUSTOM_ID: vidmap
-:ID:       fe47ff6d-768f-4b05-9f8c-f52352c106f4
-:END:
-Stack Footprint
-: addr --
-
-Copies memory from the specified address to the video memory (VGA or
-VESA mode). Used for displaying images directly on the screen.
-
-Parameters:
-- *addr* (32-bit): Source memory address containing the image data to
-  copy to video memory.
-
-*** Detailed Operation
-:PROPERTIES:
-:CUSTOM_ID: detailed-operation-4
-:END:
-1. *Video Memory Setup*:
-   - Set video memory segment to =0xA000= (VGA standard segment for
-     graphics mode).
-   - Initialize VESA-related variables (e.g., =gra= for page number).
-2. *VESA Page Mapping*:
-   - For each VESA page (up to 19 pages for 640x480x8 mode):
-     - Set VESA page using interrupt =0x10= with =AX = 0x4F05=.
-     - The page number is stored in =gra=.
-3. *Memory Copying*:
-   - For each page:
-     - Copy 4096 bytes (4KB) from source address to video memory.
-     - Use =STOSD= to write 32-bit words for efficiency.
-   - The source address is incremented by 4KB after each page.
-4. *Final Cleanup*:
-   - Restore original segments and clean up stack.
-
-*** Example
-Copy a 640x480x8 image (307,200 bytes) from memory at =0x10000= to video
-memory:
-#+begin_example
-0x10000
-vidmap
-#+end_example
-
-*** Notes
-
-- The operation assumes the video mode is set to VESA 640x480x8 (mode
-  =0x101=).
-- The exact number of pages copied depends on the video mode (19 pages
-  for 640x480x8).
-- Requires VESA BIOS support and proper initialization via
-  =set_vesa_mode=.
-
-** mouse@
-:PROPERTIES:
-:CUSTOM_ID: mouse
-:ID:       b4bce653-d38f-45ed-82ec-13ca78c9860b
-:END:
-Stack Footprint:
-: -- x y buttons
-
-*Description:*
-
-Reads the current mouse position and button states from the mouse
-driver. Returns three values on the stack:
-- X-coordinate,
-- Y-coordinate,
-- button states.
-
-
-- *Returns*:
-  - *x* (32-bit): Current X-coordinate of the mouse cursor (0-based).
-  - *y* (32-bit): Current Y-coordinate of the mouse cursor (0-based).
-  - *buttons* (32-bit): Bitmask of button states:
-    - Bit 0: Left button (1 = pressed)
-    - Bit 1: Right button (1 = pressed)
-    - Bit 2: Middle button (1 = pressed)
-
-*Example:*
-
-#+begin_example
-mouse@
-#+end_example
-After execution, stack contains buttons (top), y, x (bottom).
-
-** vidput - put image1 into image2, at location x, y
-:PROPERTIES:
-:CUSTOM_ID: ID-238e8b03-57b6-424d-bfee-b6bb652cefbc
-:ID:       238e8b03-57b6-424d-bfee-b6bb652cefbc
-:END:
-Stack Footprint:
-: addr1 addr2 x y --=
-
-Copies a portion of image1 to image2 at the specified (x, y)
-coordinates with clipping. Unlike =tvidput=, there is no transparency
-support - every pixel is copied regardless of value.
-
-*Parameters:*
-
-- *addr1* (32-bit): Address of the source image structure (width,
-  height, data address).
-- *addr2* (32-bit): Address of the destination image structure (width,
-  height, data address).
-- *x* (32-bit): X-coordinate in the destination image where the copy
-  starts.
-- *y* (32-bit): Y-coordinate in the destination image where the copy
-  starts.
-
-*Image Structure Format:*
-
-Identical to =tvidput=:
-- *Offset 0*: Image width (32-bit)
-- *Offset 4*: Image height (32-bit)
-- *Offset 8*: Base address of image data (32-bit pointer)
-
-*Example:*
-#+begin_example
-0x1000  ; Source image structure
-0x2000  ; Destination image structure
-50      ; x
-50      ; y
-vidput
-#+end_example
-
-** cmove - copy memory array
-:PROPERTIES:
-:CUSTOM_ID: ID-79e1916f-4103-42cc-ac10-bb1ee776ed50
-:ID:       79e1916f-4103-42cc-ac10-bb1ee776ed50
-:END:
-
-- *Stack Effect:*
-: addr1 addr2 len --
-
-Copies =len= bytes from =addr1= to =addr2=. Handles overlapping memory
-regions correctly.
-
-- *Notes:* If =addr1 > addr2=, copies backwards to avoid data
-  corruption; otherwise copies forwards.
-- *Example:*
-  #+begin_example
-  100  ; Length
-  0x2000  ; Destination address
-  0x1000  ; Source address
-  cmove
-  #+end_example
-
-** cfill
-:PROPERTIES:
-:CUSTOM_ID: cfill
-:ID:       fecb9438-d9d2-4224-a017-cc87dba9209e
-:END:
-- *Stack Effect:* =byte addr len --=
-- *Description:* Fills =len= bytes of memory starting at =addr= with the
-  specified byte value.
-- *Notes:* Simple byte-by-byte filling operation. Used for initializing
-  memory regions.
-- *Example:*
-  #+begin_example
-  0xFF  ; Fill byte
-  0x1000  ; Start address
-  100  ; Length
-  cfill
-  #+end_example
-
-** tvidput - put image with transparency support
-:PROPERTIES:
-:CUSTOM_ID: ID-ab45247c-44c3-464d-9e2a-337f483b4616
-:ID:       ab45247c-44c3-464d-9e2a-337f483b4616
-:END:
-Stack Footprint:
-: addr1 addr2 x y --
-
-Copies a portion of image1 to image2 at the specified (x, y)
-coordinates with transparency support. Pixels in image1 with value 255
-(0xFF) are treated as transparent and are not copied to the
-destination.
-
-*Parameters:*
-
-- *addr1* (32-bit): Address of the source image structure (contains
-  width, height, and data address).
-- *addr2* (32-bit): Address of the destination image structure (contains
-  width, height, and data address).
-- *x* (32-bit): X-coordinate in the destination image where the copy
-  starts.
-- *y* (32-bit): Y-coordinate in the destination image where the copy
-  starts.
-
-*Image Structure Format:*
-
-Each image structure is stored in memory as follows:
-- *Offset 0*: Image width (32-bit integer)
-- *Offset 4*: Image height (32-bit integer)
-- *Offset 8*: Base address of image data (32-bit pointer)
-
-*Example:*
-#+begin_example
-0x1000  ; Source image structure
-0x2000  ; Destination image structure
-50      ; x
-50      ; y
-tvidput
-#+end_example
-
-*Notes:*
-
-- Transparency is fixed at value 255 (0xFF).
-- The operation handles clipping automatically to ensure the copy stays
-  within destination bounds.
-- Source and destination image structures must be properly formatted.
-
-** depth
-:PROPERTIES:
-:CUSTOM_ID: ID-77fa76d3-9cd0-49c1-882c-f30383347352
-:ID:       77fa76d3-9cd0-49c1-882c-f30383347352
-:END:
-- *Stack Effect:* =-- depth=
-- *Description:* Pushes the current depth (number of items) on the data
-  stack onto the stack.
-- *Notes:* Calculated by comparing the data stack pointer to the base
-  address of the stack.
-- *Example:*
-  #+begin_example
-  1 2 3
-  depth
-  #+end_example
-  After execution, stack contains 3 (depth) followed by 1 2 3.
-
-** charput - draw text character
-:PROPERTIES:
-:CUSTOM_ID: ID-4bb479cf-aae0-4128-9868-f016c286a162
-:ID:       4bb479cf-aae0-4128-9868-f016c286a162
-:END:
-
-Stack Footprint:
-=colorfg colorbg addrsrc addrdest x y --=
-
-
-Draws an 8x8 character from a source memory buffer to a destination
-image buffer at the specified (x, y) coordinates. Each byte in the
-source buffer represents one row of the character (8 bits per row),
-where each bit determines whether to use the foreground or background
-color for that pixel.
-
-*Parameters:*
-
-- *colorfg* (1 byte): Foreground color value (0-255). Typically a
-  grayscale value where 0 is black and 255 is white.
-- *colorbg* (1 byte): Background color value (0-255).
-- *addrsrc* (32-bit): Memory address pointing to 8 bytes of character
-  data. Each byte represents one row of the character (8 bits per row).
-- *addrdest* (32-bit): Base address of the destination image buffer in
-  memory.
-- *x* (32-bit): X-coordinate (0-based) where the character's left edge
-  starts.
-- *y* (32-bit): Y-coordinate (0-based) where the character's top edge
-  starts.
-
-*Example:*
-
-TODO: Create dedicated page that explains this instruction in
-depth. Link to this new page from current one.
-
-#+begin_example
-0xFF  ; White foreground
-0x00  ; Black background
-0x3000  ; Character data address
-0x5000  ; Video memory address
-20      ; y
-10      ; x
-charput
-#+end_example
-
-Character data for 'A' (ASCII 65):
-#+begin_example
-0x00, 0x18, 0x24, 0x24, 0x24, 0x3C, 0x24, 0x24
-#+end_example
 
-- Each byte represents a row:
-  - Row 0: =0x00= → all pixels black
-  - Row 1: =0x18= → bits 3-4 set (binary =00011000=)
-  - Row 2: =0x24= → bits 2 and 5 set (binary =00100100=)
-  - Row 3: =0x24= → same as row 2
-  - Row 4: =0x24= → same as row 2
-  - Row 5: =0x3C= → bits 2-5 set (binary =00111100=)
-  - Row 6: =0x24= → same as row 2
-  - Row 7: =0x24= → same as row 2