--- /dev/null
+#+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
| 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