-- Primary documentation is stored in *.org files (they use emacs
- org-mode syntax). All html files are compiled from org, so you
- better read and write org files instead of html.
+#+TITLE: AGENTS — Fifth Operating System Project Guide
+#+AUTHOR: Guide for AI coding assistants (Aider, etc.)
-* Components
-** Kernel
+* Project Overview
-Kernel is minimal viable implementation of fifth language compiler and
-interpreter. It is immediately loaded when virtual machine starts.
+Fifth is a self-hosted hobby operating system built around a
+Forth-inspired programming language. It runs on a custom 32-bit
+stack-based virtual CPU, emulated on x86 DOS real mode. The system
+integrates a kernel (compiler + interpreter), a virtual machine
+emulator, device drivers, graphics libraries, a filesystem, a text
+editor, and a graphics editor.
-- *kernel/core.asm*: Main kernel code in virtual CPU own Assempbly
- language.
-- *kernel/define.inc*: Machine code definitions for the virtual CPU
- instructions.
+* Key Conventions and Warnings
-** Emulator
+** CRITICAL — Read Before Making Any Changes
-The virtual CPU emulator.
+1. *Do NOT edit =.html= files.* They are generated from =.org= files.
+ Always edit the =.org= source instead.
-- *emulator/emulator.asm*: Main emulator code that interprets Fifth
- machine code and interfaces with host system resources.
+2. *Files under =imageFile/f/= appear as plain text in the repo but
+ use FSCII encoding internally.* The files checked into git are
+ human-readable source representations. The actual disk image
+ (=disk.raw=) uses FSCII encoding. The conversion tools
+ (=src25th.bas=, =5th2src.bas=) handle translation. When editing
+ Fifth source files in =imageFile/f/=, write standard ASCII text —
+ the build tools handle FSCII conversion.
-** Drivers
+3. *Two different assembly languages exist in this project:*
+ - =kernel/core.asm= and =kernel/define.inc= use the *virtual CPU's
+ own instruction set* (NOT x86). See the "Virtual CPU Instruction
+ Set" section below.
+ - =emulator/emulator.asm= and its =.inc= files are *x86 real-mode
+ DOS assembly* for FASM (Flat Assembler).
-Hardware interface components that handle input and output devices.
+4. *Binary files* (=.raw=, =.com=, =.dat=, =FNT_SYSTEM=,
+ =I01_MCARROW=, =core.raw=, =emulator.com=) are compiled outputs
+ or binary data — do not edit them directly.
-- *imageFile/f/lib/5TH_DRVKBD*: Keyboard driver that translates scan
- codes into Fifth's character encoding (FSCII).
-- *imageFile/f/lib/5TH_DRVMOUSE*: Mouse driver that tracks cursor
- position and button states for graphical interaction.
+5. The project uses *spaces in directory names* (e.g.,
+ ="floppy image/"=). Always quote paths in shell commands.
-** Graphics Libraries
+6. *Numbers in Fifth source are hexadecimal by default*, not decimal.
+ For example, =FF= means 255, =400= means 1024, =3B= means 59.
+ The language has a =d.= word for decimal display but all literals
+ in source code are hex.
-Components responsible for rendering visual elements.
+** Documentation
+- =doc/index.org= — Project overview, installation, architecture.
+- =doc/language.org= — Complete Fifth language reference (all
+ commands, stack effects, examples).
+- =doc/virtual machine.org= — Virtual CPU architecture.
+- =doc/5TH_ET.txt= — Example Fifth source (text editor).
-- *imageFile/f/lib/5th_gfx*: Basic 2D graphics functions including
- drawing lines, boxes, and image manipulation.
-- *imageFile/f/lib/5th_gfx2*: Advanced graphics routines for more
- complex rendering operations.
+* FSCII Character Encoding
-** Utility Libraries
+Fifth uses FSCII (Fifth Standard Code for Information Interchange)
+instead of ASCII. Key differences:
-Specialized mathematical and data processing functions.
+| Dec | Hex | FSCII Function |
+|------+-----+---------------------------------------------|
+| 0–15 | 0–F | Hex digit characters (not control codes!) |
+| 252 | FC | Backspace |
+| 253 | FD | Tabulator (TAB) |
+| 254 | FE | Carriage return (newline) |
+| 255 | FF | Space |
+| else | | Same as ASCII (letters, punctuation, etc.) |
-- *imageFile/f/lib/5th_trig*: Trigonometric functions (sin, cos).
+This means: ASCII space (32) is NOT space in FSCII. The character "0"
+(ASCII 48) is an ordinary letter, not the number zero. Hex digits 0–F
+are represented by byte values 0–15.
-** Tools
-Utilities for development and maintenance of the Fifth system.
+* Virtual CPU Instruction Set
-- *tools/5th2src.bas*: Converts system files (FSCII encoded) into
- human-readable source code format.
-- *tools/fsimport.bas*: Imports external files into the Fifth system's
- virtual disk image.
-- *tools/src25th.bas*: Converts source code back into system-compatible
- FSCII encoded files.
+The virtual CPU is stack-based with two stacks: a data stack (=edi=
+register in emulator) and a return stack (=resp=). Instructions are
+single-byte opcodes, some followed by a 32-bit argument.
-** Documentation
+Opcodes defined in =kernel/define.inc= and dispatched in
+=emulator/emulator.asm=:
+
+| Opcode | Mnemonic | Args | Stack Effect | Description |
+|--------+----------+--------+---------------------------+-----------------------------------|
+| 0 | xnop | | ( -- ) | No operation |
+| 1 | xhalt | | | Halt / exit |
+| 2 | kbd@ | | ( -- scancode ) | Read keyboard scancode |
+| 3 | xnum | 32-bit | ( -- n ) | Push literal number |
+| 4 | xjmp | 32-bit | | Unconditional jump |
+| 5 | xcall | 32-bit | | Call subroutine (push return) |
+| 6 | xinc | | ( n -- n+1 ) | Increment TOS |
+| 7 | xdec | | ( n -- n-1 ) | Decrement TOS |
+| 8 | xdup | | ( n -- n n ) | Duplicate TOS |
+| 9 | xdrop | | ( n -- ) | Drop TOS |
+| 10 | xif | 32-bit | ( flag -- ) | Jump if flag = 0 |
+| 11 | xret | | | Return from subroutine |
+| 12 | xc@ | | ( addr -- byte ) | Fetch byte from memory |
+| 13 | xc! | | ( byte addr -- ) | Store byte to memory |
+| 14 | xpush | | ( n -- ) R:( -- n ) | Move TOS to return stack |
+| 15 | xpop | | ( -- n ) R:( n -- ) | Move from return stack to TOS |
+| 17 | xrot | | ( a b c -- b c a ) | Rotate top 3 (note: non-standard) |
+| 18 | xdisk@ | | ( sector mem -- ) | Load 1024 bytes from disk |
+| 19 | xdisk! | | ( mem sector -- ) | Save 1024 bytes to disk |
+| 20 | x@ | | ( addr -- n ) | Fetch 32-bit from memory |
+| 21 | x! | | ( n addr -- ) | Store 32-bit to memory |
+| 22 | xover | | ( a b -- a b a ) | Copy second to top |
+| 23 | xswap | | ( a b -- b a ) | Swap top two |
+| 24 | xplus | | ( a b -- a+b ) | Add |
+| 25 | xminus | | ( a b -- a-b ) | Subtract |
+| 26 | xmul | | ( a b -- a*b ) | Multiply (signed) |
+| 27 | xdiv | | ( a b -- a/b ) | Divide (signed) |
+| 28 | xcmpg | | ( a b -- flag ) | Greater than |
+| 29 | xcmpl | | ( a b -- flag ) | Less than |
+| 30 | xnot | | ( n -- ~n ) | Bitwise NOT |
+| 31 | xi | | ( -- n ) | Copy return stack TOS |
+| 32 | xcprt@ | | ( port -- byte ) | Read I/O port |
+| 33 | xcprt! | | ( byte port -- ) | Write I/O port |
+| 34 | xi2 | | ( -- n ) | Copy return stack 2nd |
+| 35 | xi3 | | ( -- n ) | Copy return stack 3rd |
+| 36 | xshl | | ( n count -- n<<count ) | Shift left |
+| 37 | xshr | | ( n count -- n>>count ) | Shift right |
+| 38 | lor | | ( a b -- a OR b ) | Bitwise OR |
+| 39 | lxor | | ( a b -- a XOR b ) | Bitwise XOR |
+| 40 | xvidmap | | ( addr -- ) | Map image buffer to VESA video |
+| 41 | xmouse@ | | ( -- btns dy dx ) | Read mouse state |
+| 42 | xvidput | | ( src dst x y -- ) | Blit image to image |
+| 43 | xcmove | | ( src dst count -- ) | Copy memory bytes |
+| 44 | xcfill | | ( byte addr count -- ) | Fill memory with byte |
+| 45 | xtvidput | | ( src dst x y -- ) | Transparent blit (FF=transparent) |
+| 46 | xdep | | ( -- depth ) | Data stack depth |
+| 47 | xcharput | | ( fg bg font dst x y -- ) | Render character glyph |
+
+* Fifth Language Quick Reference
+
+Fifth is Forth-like: postfix notation, stack-based, words separated by
+spaces. Key syntax patterns found in the source code:
+
+** Defining Words
+#+begin_example
+: name ... ; \ Define a new word (subroutine)
+:i name ... ; \ Define immediate word (runs at compile time)
+var name \ Define a 32-bit variable (initialized to 0)
+N vari name \ Define a variable initialized to N
+N const name \ Define a constant
+create name N alloc \ Allocate N bytes of data space
+str content" name \ Define a string constant
+Dstr content" name \ Define a dynamic string constant
+#+end_example
+
+** Control Flow
+#+begin_example
+if ... then \ Conditional
+if ... else ... then \ Conditional with else
+N do ... loop \ Count down from N-1 to 0 (i = counter)
+low high for ... loop \ Count up from low to high-1 (i = counter)
+until ... loop \ Repeat until "done" is called
+#+end_example
+
+** Stack Manipulation
+#+begin_example
+dup drop swap over rot 2dup 2drop nip
+push pop \ Move to/from return stack
+i i2 i3 \ Copy from return stack (loop counters)
+#+end_example
+
+** Memory
+#+begin_example
+@ ! \ 32-bit fetch/store
+c@ c! \ 8-bit fetch/store
+cmove \ Block copy ( src dst count -- )
+cfill \ Block fill ( byte addr count -- )
+#+end_example
+
+** Comments
+#+begin_example
+\ single line comment (to end of line)
+( comment until closing paren )
+.( visible message ) \ Print at compile time
+#+end_example
+
+** Important Idioms in the Codebase
+#+begin_example
+rh name \ Remove word "name" from dictionary (hide it)
+ \ Used extensively to keep namespace clean
+modulechk \ Load a module if not already loaded
+include \ Execute code from a file
+D> word \ Parse next word into default dynamic string
+D" string" \ Parse string into default dynamic string
+#+end_example
+
+* Disk Layout and Filesystem
+
+Constants from =5th_boot=:
+
+| Symbol | Hex Value | Description |
+|----------+---------------------------------+--------------------------------------------------|
+| fsroot | 24*400 | Root directory location (sector 24h × 1024) |
+| fsfatbeg | 25 | FAT starts at sector 25h |
+| fsfatsiz | 4000 | FAT size (4000h entries) |
+| fsdata | fsfatbeg + fsfatsiz*4/400 + 1 | Data area start sector |
+
+Sector size is 1024 bytes (=400h=). FAT entry values:
+- =-2= — last sector of a file chain
+- =-1= — free/unused sector
+- =0+= — pointer to next sector
+
+File directory entry (32 bytes):
+| Offset | Size | Content |
+|--------+------+-------------------------------------------------|
+| 0 | 4 | Extension (4-byte FSCII, e.g. "list", "5th_") |
+| 4 | 16 | Filename (padded with FF/spaces) |
+| 20 | 4 | First block address (FAT chain start) |
+| 24 | 4 | File size in bytes |
+
+Special extensions: ="free"= marks deleted entries, ="list"= marks
+directories (subdirectories).
+
+* Memory Map
+
+| Address | Size | Description |
+|----------+---------+----------------------------------------|
+| 0 | ~4096 | Kernel (core.raw) |
+| 1500000h | ~32000 | High-level Fifth boot code (5th_boot) |
+| 200000h | varies | Core startup messages area |
+| 5200000h | | End of dynamic memory space |
+
+Dynamic memory is managed by the =dynal=/=dynde=/=dynp=/=dyns= words
+defined in =5th_boot=. Up to =100h= (256) dynamic blocks.
+
+* Boot Sequence (detailed)
+
+1. Emulator (=emulator.com=) starts, allocates XMS, sets VESA 640×480
+ 8-bit mode, loads first 1024 bytes of =disk.raw= into virtual
+ memory at address 0.
+2. Kernel (=core.asm=) executes: loads remaining kernel sectors, then
+ loads high-level boot code (=5th_boot=) at address =1500000h=.
+3. =5th_boot= defines the compiler, interpreter, all core words
+ (arithmetic, stack ops, strings, dynamic memory, filesystem),
+ then runs =include= on =5TH_AUTORUN=.
+4. =5TH_AUTORUN= loads graphics library (=5th_gfx=), displays logo
+ (=5th_logo=), loads keyboard driver (=5TH_DRVKBD=), loads command
+ line UI (=5TH_UICMD=), sets up quick paths, and enters interactive
+ mode.
+
+* Components — Detailed File Map
+
+** Kernel (Virtual CPU assembly — NOT x86)
+| File | Description |
+|---------------------+------------------------------------------------|
+| =kernel/core.asm= | Main kernel: compiler, interpreter, core words |
+| =kernel/define.inc= | Virtual CPU opcode macro definitions (FASM) |
+| =kernel/font.asm= | 8×8 bitmap font data (256 characters) |
+| =kernel/core.raw= | Compiled kernel binary (do not edit) |
+
+** Emulator (x86 real-mode FASM assembly)
+| File | Description |
+|-------------------------+--------------------------------------------|
+| =emulator/emulator.asm= | Main emulator: instruction dispatch loop |
+| =emulator/system.inc= | XMS allocation, protected mode, A20 gate |
+| =emulator/vidput.inc= | Image-to-image blit (opaque) |
+| =emulator/tvidput.inc= | Image-to-image blit (transparent, FF=skip) |
+| =emulator/charput.inc= | Character glyph rendering to image buffer |
+| =emulator/kbdrive.inc= | Keyboard interrupt handler + ring buffer |
+| =emulator/compile.sh= | Build script (runs =fasm emulator.asm=) |
+| =emulator/emulator.com= | Compiled DOS COM binary (do not edit) |
+
+** High-Level Boot Code (Fifth language)
+| File | Description |
+|-----------------------------+-------------------------------------------------------------------|
+| =imageFile/f/5th_boot= | Core language: compiler, strings, dynamic memory, filesystem, FAT |
+| =imageFile/f/5TH_AUTORUN= | Startup script: loads drivers, shows logo, enters REPL |
+| =imageFile/f/5TH_QUICKPATH= | Shortcut path definitions for navigation |
+
+** Applications (Fifth language)
+| File | Description |
+|-------------------------+--------------------------------------------|
+| =imageFile/f/5th_et= | Full-screen text editor (ET command) |
+| =imageFile/f/5th_eg= | Graphics editor (gedit/geditnew commands) |
+| =imageFile/f/5th_logo= | Draws the Fifth logo on screen at startup |
+| =imageFile/f/5th_demo= | Demo programs (graphics test, mouse test) |
+
+** Libraries (Fifth language, in =imageFile/f/lib/=)
+| File | Description |
+|--------------------+---------------------------------------------------------------|
+| =5th_gfx= | Core graphics: screen buffer, palette, text output, scrolling |
+| =5th_gfx2= | Extended graphics: lines, boxes, flood fill, flip |
+| =5th_trig= | Trigonometry: sin/cos lookup table |
+| =5TH_DRVKBD= | Keyboard driver: scan code reading, layout loading |
+| =5TH_DRVMOUSE= | Mouse driver: position tracking, click regions |
+| =5TH_KBD_US= | US QWERTY keyboard layout scan code → FSCII table |
+| =5TH_KBD_USDVORAK= | US Dvorak keyboard layout table |
+| =5TH_UICMD= | Command-line UI: =words=, =cmdline=, =fs.=, =bye= |
+
+** Help/Data Files
+| File | Description |
+|-------------------------+----------------------|
+| =imageFile/f/txt_help= | General help text |
+| =imageFile/f/txt_et= | Text editor help |
+| =imageFile/f/txt_eg= | Graphics editor help |
+
+** Binary Assets (do not edit)
+| File | Description |
+|----------------------------+--------------------------|
+| =imageFile/f/FNT_SYSTEM= | System font binary |
+| =imageFile/f/I01_MCARROW= | Mouse cursor arrow image |
+
+* Tools (QuickBASIC / FreeBASIC)
+
+| File | Purpose |
+|----------------------+--------------------------------------------------|
+| =tools/5th2src.bas= | Convert FSCII file → readable =.src= text file |
+| =tools/src25th.bas= | Convert readable =.src= text → FSCII =.5th= file |
+| =tools/fsimport.bas= | Import a host file into =disk.raw= virtual disk |
+| =tools/editor.bas= | Source code editor utility |
+| =tools/font.dat= | Font data used by editor tool |
+
+** FSCII ↔ Source Conversion Details
+
+=5th2src.bas= converts: byte 0–9 → ASCII "0"–"9", byte 10–15 →
+ASCII "A"–"F", byte 255 → space, byte 253 → tab, byte 254 → newline.
+Everything else passes through as-is.
+
+=src25th.bas= does the reverse: tries to interpret words as hex
+numbers (converting ASCII "0"–"9" → bytes 0–9, "A"–"F" → bytes
+10–15), space → byte 255, tab → byte 253, newline → byte 254.
+
+* Building & Running
+
+** Compile the Emulator
+#+begin_src bash
+cd emulator && bash compile.sh
+#+end_src
+Requires FASM (Flat Assembler). Produces =emulator.com= (DOS COM).
+
+** Run Under QEMU
+#+begin_src bash
+bash "floppy image/run under qemu.sh"
+#+end_src
+
+** Mount/Unmount Floppy Image
+#+begin_src bash
+bash "floppy image/image mount.sh"
+bash "floppy image/image umount.sh"
+#+end_src
+
+* Graphics System Details
+
+The screen is a 640×480 (=280h= × =1E0h=) 8-bit indexed color image
+buffer, allocated as a dynamic memory block.
+
+Image buffer format:
+| Offset | Size | Content |
+|--------+------+-------------------------------|
+| 0 | 4 | X size (width) |
+| 4 | 4 | Y size (height) |
+| 8 | X*Y | Pixel data (1 byte per pixel) |
+
+Color is calculated with =calccol ( b g r -- c )= which maps RGB
+(0–255 each) to a 6×6×6 color cube (216 colors). The palette is set
+up by =setupal= in =5th_gfx=.
+
+Text output uses an 8×8 pixel font. Cursor position is tracked by
+=curx= and =cury= variables. The =emit= word is vectored — initially
+it writes to the core message area, then =5th_gfx= redirects it to
+graphical text rendering via =(emit2=.
+
+* In-RAM commands dictionary structure
+
+Each dictionary entry is 24 bytes:
+
+| Offset | Size | Content |
+|--------+------+-------------------------------------------|
+| 0 | 4 | Link to previous entry (0=last, -1=empty) |
+| 4 | 15 | Name string (padded) |
+| 19 | 1 | Type: 0=data, 1=subroutine, 2=immediate |
+| 20 | 4 | Entry data (address of code/data) |
+
+The dictionary is a linked list searched backwards from =lp= (last
+pointer). Up to ~1000 entries fit in the 24000-byte dictionary space.
+
+Type behavior when referenced:
+- Type 0 (data): compiles a =xnum= instruction with the address
+- Type 1 (subroutine): compiles an =xcall= instruction
+- Type 2 (immediate): executes immediately even during compilation
+
+* Keyboard System
+
+Scan codes from the hardware keyboard are buffered by =kbdrive.inc=.
+The Fifth keyboard driver (=5TH_DRVKBD=) provides:
+
+- =KBD_@= — read raw scan code
+- =KBD_SC2FSCII= — convert scan code to FSCII using layout table
+- =KBD_F@= — read FSCII key (with shift/alt modifiers: +100h/+200h)
+- =KBD_FW@= — blocking read (waits for keypress)
+
+Special key codes (FSK — Fifth Standard Keycodes):
+| Code | Key |
+|-------+-----------|
+| 400h | ESC |
+| 401h+ | F1, F2... |
+| 410h | Up |
+| 411h | Right |
+| 412h | Down |
+| 413h | Left |
+| 414h | Insert |
+| 415h | Delete |
+| 416h | Home |
+| 417h | End |
+| 418h | Page Up |
+| 419h | Page Down |
+| FCh | Backspace |
+| FDh | Tab |
+| FEh | Enter |
+| FFh | Space |
+
+* Common Patterns in Fifth Source Code
+
+** Module Loading Guard
+#+begin_example
+D> \listF\listLIB\5TH_GFX modulechk
+#+end_example
+Loads the module only if not already loaded (checks dictionary).
+
+** Variable Cleanup with =rh=
+#+begin_example
+var tmp1 var tmp2
+: myword ... ; rh tmp1 rh tmp2
+#+end_example
+=rh= (remove head) hides temporary variables from the dictionary
+after they're no longer needed externally. The variables still exist
+in memory but can't be found by name.
+
+** Dynamic String Lifecycle
+#+begin_example
+myvar Dv \ allocate dynamic string, store handle in myvar
+... \ use the string
+myvar Df \ deallocate it
+#+end_example
-System reference materials.
+** Vectored Execution (Deferred Words)
+#+begin_example
+defer cmdline \ create forward reference
+...
+' (cmdline ' cmdline is \ point it to actual implementation
+#+end_example
-- *doc/index.org*: Main documentation page providing an overview of
- the Fifth system.
-- *doc/language.org*: Detailed reference for the Fifth programming
- language syntax and commands.
+** File Operations
+#+begin_example
+D" \listF\myfile" fsDloadnew \ load file → new dynamic block
+dup dynp \ get pointer to data
+swap dynde \ deallocate when done
+#+end_example