THOREAU BASIC 2.3.1 =================== Homepage : https://thoreaubasic.com Itch site: https://tarjan.itch.io/thoreaubasic Mail : info@thoreaubasic.com A 64-bit BASIC interpreter for x64 Windows and x64 UEFI. Thoreau BASIC keeps the direct, line-numbered style of classic Microsoft BASIC, adds modern 64-bit memory and graphics, and can run either as a Windows program or directly from UEFI firmware without an operating system. Version 2.3.1 is a compatibility, debugging and usability update. It adds the lazy IIF conditional expression, corrects nested single-line IF/ELSE execution, expands the Thoreau Machine Explorer into a live debugger, reports the source line reached by STOP, and tightens program loading, directory output and Windows file-handle lifetime. Version 2.3 adds two substantial new language areas: software sprites for games and a native hypercomplex @ numeric type for higher mathematics. Sprite images and instances are separate, allowing up to 65,536 loaded images and 65,536 independent instances while many instances share one image in memory. Sprites support movement, visibility, text layering and pixel-perfect collision using precomputed transparency masks. Version 2.3 also adds game-oriented KEYREPEAT and WAITREL timing controls. The @ type covers complex numbers, quaternions and octonions in one numeric promotion tower. CPLX, QUAT and OCT construct values; arithmetic, conjugation, inverse, norm, component access and @ arrays are integrated into the expression engine. Version 2.3 also extends ^, SIN, COS, TAN, EXP, LOG, SQR/SQRT, SINH, COSH and TANH to @ values, with explicit principal-value rules where the mathematics is multivalued. Version 2.2 was primarily a compatibility, robustness and memory-management release. It added SAVEBMP, wildcard KILL, parenthesized BITBLT coordinates, automatic .BAS on SAVE, interruptible recursive DIR/FILES, compacting string garbage collection, reusable/coalescing array and bitmap memory, classic two-byte extended-key INKEY$ results, and full-width word-aware HELP. Version 2.1 adds international keyboard support to the x64 UEFI build, runtime keyboard-layout switching, and the SYSTEM command on both platforms. On UEFI, THOREAU.CFG beside the EFI can contain a DOS-style keyboard selection: KEYB GR KEYB can also switch layouts while Thoreau BASIC is running. Thoreau supports 23 layouts. When possible it reads a USB HID boot keyboard directly so physical key positions are preserved even when firmware keyboard translation is incomplete. If direct USB HID input is unavailable, it falls back to UEFI firmware input. The default layout is US. SYSTEM leaves Thoreau BASIC. On Windows it closes the application. On UEFI it returns to the firmware/caller, allowing normal firmware boot processing to continue when Thoreau was started as a boot option. Version 2.1 also includes the 2.01 compatibility refinements: RUN accepts a starting line or filename, AUTO preserves an existing line when Enter is pressed immediately at its * prompt, and bitmap slots range from 0 through 65535. Version 2.0 added standalone application creation: Windows: CREATEEXE "program" UEFI: CREATEEFI "program" The generated EXE/EFI contains the currently loaded BASIC program. When the generated application starts, it skips the normal Thoreau BASIC banner and command prompt and immediately runs the embedded program. External assets such as BMP files and save files remain ordinary files beside the application. VERSION 2.3.1 CHANGES ===================== Version 2.3.1 builds on 2.3 without changing existing program syntax: - IIF(condition,ifTrue,ifFalse) adds a conditional expression, particularly useful inside DEF FN definitions. The condition is evaluated first and only the selected result expression is evaluated. The unselected branch cannot cause an error or side effect. For example, IIF(X=0,0,1/X) is safe at zero. - Nested single-line IF/ELSE statements now follow the classic dangling-ELSE rule: ELSE binds to the nearest unmatched IF. A false outer IF skips the complete nested THEN clause, including any ELSE belonging to an inner IF. - IF branches that execute GOSUB now retain their enclosing single-line IF context across the subroutine call, so RETURN resumes at the correct ELSE or end of statement instead of producing a Syntax Error. - STOP reports its source line as "Break in n". CONT still resumes after the STOP, and the Machine Explorer records the last pause reason and location. - The Machine Explorer has live, read-only interpreter views: STATE summarizes execution and memory use, STACK displays GOSUB/timer returns, FLOW displays FOR/WHILE/handler/single-line-IF frames, BREAKS shows pause and breakpoint state, TIMERS shows programmable timers, and INTERNALS lists core structure addresses and capacities. - F12 enters DebuggerMode from a running program, INPUT, or the BASIC prompt. Entry clears the debugger screen, uses normal key repeat and temporarily hides sprites. X restores the exact framebuffer, text grid, cursor, colors, views, sprite presentation and prior KEYREPEAT settings, then resumes the program or returns to the prompt. THOREAU uses the same protected session. - LOAD, BREAK, CLEAR and NEW clears source-line breakpoints. - DIR and FILES display filenames, directory names and paths in uppercase, while retaining directories-first, case-insensitive sorting and [DIR] markers. - Windows keeps BASIC's current directory separate from the process current directory and opens ordinary files with delete-sharing. LOAD, RUN and LOADSPRITE close their source/asset handles promptly, so a game's directory may be renamed or deleted after loading unless it contains the running EXE. VERSION 2.3 CHANGES =================== Version 2.3 introduces sprites, game-loop timing controls and hypercomplex numbers: - Software sprites separate loaded images from instances. Up to 65,536 image slots and 65,536 instances are available, so many copies can share one bitmap in memory. Sprite dimensions may exceed the current screen and are clipped while drawing. - LOADSPRITE optionally defines a transparent color. A compact 1-bit opacity mask is generated at load time. SPRITECOLLIDE first rejects non-overlapping bounding boxes, then tests the common area for exact overlap of two non-transparent pixels. One opaque-pixel overlap is a collision. - SPRITE, MOVESPRITE, SHOWSPRITE, HIDESPRITE and DELSPRITE manage persistent sprite instances. SPRITEX and SPRITEY expose instance positions. - SPRITETEXT UNDER|OVER selects whether text ink is composited below or above software sprites. UNDER is the compatibility default; OVER is useful for score displays, HUDs and labels. - KEYREPEAT delay,rate provides game-style keyboard repeat timing on Windows and raw USB HID UEFI. KEYREPEAT DEFAULT restores normal platform behavior. Firmware-input UEFI fallback cannot override repeat because UEFI text input does not expose reliable key-release state. - WAITREL milliseconds provides relative frame pacing. Work done between calls counts toward the requested interval; late frames return immediately and re-anchor instead of producing a burst of catch-up frames. WAITREL 0 resets its timing reference. - The new @ numeric type adds complex numbers, quaternions and octonions as one hypercomplex promotion tower. CPLX, QUAT and OCT construct values. - @ values support +, -, *, /, = and <> with automatic promotion from real to complex to quaternion to octonion. Quaternion/octonion multiplication keeps its mathematical non-commutative behavior, and octonion multiplication is correctly non-associative. - CONJ, INV, NORM, NORM2, ABS and COMP operate on hypercomplex values. Named component access such as Z@.R, Z@.I, Q@.J and O@.E7 is supported, including component assignment. @ arrays are supported as ordinary BASIC arrays. - ^ accepts an @ base with an ordinary real scalar exponent. Integer powers use exponentiation by squaring; non-integer powers use the documented principal value EXP(exponent*LOG(base)). A@^B@ is intentionally rejected because quaternion multiplication is non-commutative and octonions add non-associativity, so there is no single unsurprising exponent convention. - SIN, COS, TAN, EXP, LOG, SQR/SQRT, SINH, COSH and TANH accept complex, quaternion and octonion @ values. LOG, SQRT and non-integer powers use a deterministic principal branch. Negative real quaternions choose +i; negative real octonions choose +e1. - ASCII LOAD and MERGE accept literal TAB characters (CHR$(9)) from external editors. Tabs are expanded to the next 4-column tab stop before the source line is stored, so LIST displays normal spaces rather than control glyphs. - Hypercomplex division, INV, ABS and NORM use scaled numerical algorithms to avoid avoidable overflow/underflow for very large or very small components. - Scalar and hypercomplex floating-point narrowing now reports Overflow rather than silently storing infinities where the BASIC type cannot represent the result. - Windows BLOAD/BSAVE use guarded memory access, so invalid process addresses become BASIC errors instead of crashing the interpreter. - SAVE and buffered PRINT# propagate disk write failures as Disk I/O error. - Apostrophe comments now terminate the token stream correctly after any statement element, including PRINT separators. For example: 10 PRINT "_"; ' Empty cell is accepted as expected. - WHILE now rejects trailing unparsed expression text instead of silently treating it as part of the loop structure. This catches mistakes such as WHILE NOR EOF(1) with a Syntax Error while still allowing NOR as an ordinary variable name. - DIR and FILES mark directories with [DIR], list directories before files, and sort names case-insensitively within each group. This also applies to wide directory listings. - Windows BLOAD and BSAVE validate memory accesses through Thoreau's guarded memory layer. UEFI deliberately retains raw bare-metal memory semantics. SAVE and buffered file output now propagate disk write failures as "Disk I/O error". VERSION 2.2 CHANGES =================== Version 2.2 collects compatibility, memory-management and usability fixes: - Strings are reclaimed automatically by a compacting garbage collector, so repeated concatenation and reassignment no longer steadily exhaust string space. - ERASE returns numeric/string-array descriptor blocks to a coalescing free list. Live arrays never move, so VARPTR addresses remain stable. - Loaded bitmaps use the same reusable arena. Replacing a LOADBMP slot returns the old pixel block, and failed loads release temporary allocations. - FRE(0) includes reusable reclaimed array/bitmap blocks instead of reporting only the untouched gap at the top of the arena. - SAVEBMP writes the active graphics VIEW, the full screen, or an explicit rectangle as an uncompressed 24-bit BMP. - BITBLT accepts both slot,x,y and slot,(x,y) destination syntax. - KILL accepts DOS-style * and ? wildcards. Matching is case-insensitive, non-recursive and never removes directories. - SAVE appends .BAS when the final path component has no extension. - Recursive DIR/FILES output can be aborted with ESC while traversal is in progress. - HELP uses the full physical text screen rather than an 80-column cap. It wraps at word boundaries and temporarily ignores TXTWINDOW and VIEW PRINT while the HELP interface is displayed. - INKEY$ returns classic Microsoft BASIC/DOS two-byte strings for supported extended keys on both Windows and UEFI: CHR$(0)+CHR$(scan). This includes the cursor/navigation keys and F1 through F10. PLATFORMS --------- Windows x64 - Native 64-bit Windows application. - BASIC program can be supplied as an autostart file. - COMMANDLINEARG$(n) exposes arguments passed to BASIC programs. - CREATEEXE creates a standalone Windows application. - SYSTEM closes Thoreau BASIC and exits the Windows process. x64 UEFI - Runs directly as an EFI application, with no operating system required. - Uses UEFI graphics and filesystem services. - STARTUP.BAS can automatically load and run at interpreter startup. - THOREAU.CFG beside the EFI can select an international keyboard layout. - KEYB can report or switch the active keyboard layout at runtime. - Compatible USB HID boot keyboards can be read directly; firmware input is used as a compatibility fallback when raw HID takeover is unavailable. The fallback keeps non-raw-HID keyboards usable but cannot provide independent key-up/repeat timing or recover keys the firmware does not expose. - CREATEEFI creates a standalone EFI application. - SYSTEM returns to the UEFI firmware/caller. - A generated EFI application can be used as \EFI\BOOT\BOOTX64.EFI on a suitable x64 UEFI boot volume. QUICK START ----------- 10 CLS 20 PRINT "HELLO FROM THOREAU BASIC" 30 FOR I=1 TO 5 40 PRINT I 50 NEXT I 60 END RUN Program files are plain ASCII BASIC source files. Literal TAB characters from external editors are accepted by LOAD and MERGE and expanded to 4-column tab stops before storage. Classic-style LOAD shorthand is supported: LOAD "GAME LOAD "GAME.BAS Both are valid. If LOAD is given a filename without an extension, .BAS is appended. The closing quote may be omitted for LOAD. RUN accepts a stored line number or a filename as well as the traditional bare form: RUN RUN 1000 RUN "GAME RUN "GAME.BAS" RUN with a filename uses LOAD semantics first. A missing extension defaults to .BAS, and the closing quote may be omitted just as with LOAD. Save a program (the .BAS extension is added when omitted): SAVE "GAME",A Create a standalone application after loading/editing the program: CREATEEXE "GAME" Windows -> GAME.EXE CREATEEFI "GAME" UEFI -> GAME.EFI THOREAU BASIC FEATURES NOT PRESENT IN GW-BASIC ============================================== The language intentionally resembles GW-BASIC, but Thoreau BASIC is not a byte-for-byte clone. These are major Thoreau additions or substantial extensions beyond GW-BASIC: 1. NATIVE 64-BIT WINDOWS AND BARE-METAL UEFI Thoreau BASIC runs as a native x64 Windows program and as an x64 EFI application directly under firmware, without DOS or another operating system. 2. CREATEEXE / CREATEEFI The currently loaded BASIC program can be packaged into a standalone Windows EXE or UEFI EFI application. CREATEEXE "MYGAME" CREATEEFI "MYGAME" 3. 64-BIT INTEGER TYPE The && suffix and DEFI64 provide signed 64-bit integers. A&&=9223372036854775807 DEFI64 A-Z 4. 64-BIT ADDRESS-ORIENTED BASIC VARPTR returns 64-bit addresses. LOMEM, HIMEM, FREEBOT, FREETOP and THOREAUADR expose the interpreter and machine memory layout. 5. WIDE PEEK/POKE PEEK16, PEEK32, PEEK64 and POKE16, POKE32, POKE64 complement byte PEEK/POKE. 6. THOREAU MACHINE EXPLORER THOREAU opens a built-in low-level machine monitor with memory dumps, searches, transfers, maps, landmarks and machine information. 7. STORAGE / BOOT ARCHAEOLOGY The Machine Explorer can inspect disks, sectors, partitions, filesystems, UEFI boot entries and perform best-effort installed-OS detection. Storage inspection commands are read-only. 8. 24-BIT GW-BASIC GRAPHICS EXTENSIONS Classic GW-BASIC-style PSET, PRESET, LINE, CIRCLE, PAINT, COLOR, POINT, GET/PUT, DRAW, VIEW and WINDOW operate on a 24-bit RGB framebuffer. Palette colors 0-15 remain compatible, while direct 0xRRGGBB values are accepted throughout. PSET/PRESET, LINE, PAINT and COLOR also accept r,g,b component triples. PSET (10,10),255,136,0 LINE (20,20)-(300,180),30,80,160,BF CIRCLE (320,240),100,&HFF8800 COLOR 255,255,255,16,16,16 POINT returns raw 24-bit RGB for non-palette pixels, and graphics GET/PUT preserve full 24-bit pixels. 9. BMP GRAPHICS LOADBMP loads uncompressed 24/32-bit BMP files into slots 0..65535, BITBLT draws them, and SAVEBMP writes the current graphics VIEW, full screen, or an explicit rectangle as a 24-bit BMP. BITBLT accepts either flat x,y coordinates or a GW-style (x,y) point and can use a transparent color key. LOADBMP 0,"ROOM.BMP" BITBLT 0,(0,0) BITBLT 0,(100,80),&HFF00FF SAVEBMP "SCREEN.BMP" 10. FRAMEBUFFER INTROSPECTION GRAMAXX, GRAMAXY, GRAPITCH and SCRNADR expose graphics dimensions and the framebuffer address. 11. EXTENDED SCREEN SELECTION SCREEN width,height selects a graphics mode by dimensions rather than the classic GW-BASIC SCREEN mode-number model. 12. TXTWINDOW AND NAMED TEXT WINDOWS TXTWINDOW can set the default text rectangle and create named @n windows. PRINT @n, CLS @n and LOCATE @n can address those regions. 13. PRINT WRAP / PRINT JUSTIFY Long prose can be word-wrapped or fully justified directly by PRINT. PRINT WRAP 60,TEXT$ PRINT JUSTIFY 60,TEXT$ 14. MULTIPLE PROGRAMMABLE TIMERS Eight independent millisecond timers (0..7) can call GOSUB handlers. 15. BREAKPOINT MANAGER BREAK can set, list, delete and clear source-line breakpoints. BREAK 1000,2000 BREAK LIST BREAK DELETE 1000 BREAK CLEAR 16. VARIABLE WATCHING AND INTROSPECTION TRACE can watch scalar values while the program runs. VARINFO and ARRAYINFO can list variables, arrays, types, sizes, values and addresses. 17. FIND FIND performs case-insensitive source-code searches, optionally in a line range. FIND "LOADBMP",1000-5000 18. EXTENDED LIST / EDIT ERROR WORKFLOW LIST ERL and EDIT ERL jump directly to the last stored-program error line. LIST also supports paging and NOWAIT. 19. RECURSIVE / WIDE / PAGED DIRECTORY LISTING DIR is an alias for FILES and S, W and P options add recursion, wide output and paging. DIR "*.BAS",S,W,P 20. LCASE$ / UCASE$ ASCII case conversion functions are provided. 21. PLATFORM STARTUP / ARGUMENT FEATURES Windows provides COMMANDLINEARG$(n). The UEFI interpreter supports STARTUP.BAS and THOREAU.CFG. 22. SAFE WINDOWS MEMORY ACCESS Arbitrary PEEK/POKE-style access on Windows is guarded so invalid or protected addresses become BASIC errors instead of simply crashing the interpreter. 23. CATEGORIZED BUILT-IN HELP HELP and HELP name provide a built-in reference for the language and extensions. HELP uses the full physical text screen, wraps descriptions at word boundaries, and is independent of TXTWINDOW / VIEW PRINT while shown. 24. ON BREAK GOTO ESC/break events can be routed to a BASIC handler and resumed using the normal RESUME machinery. 25. LARGE MODERN BASIC MEMORY ARENA Variables, arrays, strings and loaded bitmaps use a modern 64-bit memory arena rather than the tiny segmented memory model of DOS BASIC. Strings are compacted automatically; ERASE and replaced bitmap slots return storage to a coalescing free list. Live arrays do not move, preserving VARPTR values, and FRE(0) includes reusable reclaimed blocks. 26. INTERNATIONAL UEFI KEYBOARD SUPPORT The UEFI build supports 23 DOS-style keyboard layout codes through THOREAU.CFG and the runtime KEYB command. Compatible USB HID boot keyboards can be read directly, bypassing incomplete firmware key translation. 27. HYPERCOMPLEX NUMBERS The @ suffix adds a native hypercomplex numeric type covering complex numbers, quaternions and octonions. Values participate directly in +, -, *, /, ^, = and <> expressions, may be stored in arrays, expose named components, and support transcendental functions including EXP, LOG, SIN, COS, TAN, SINH, COSH, TANH and principal square roots. Z@=CPLX(3,4) Q@=QUAT(1,2,3,4) O@=OCT(1,2,3,4,5,6,7,8) INCLUDED 2.3 SHOWCASE PROGRAMS ------------------------------ Version 2.3's examples are intended to exercise the new facilities rather than only document their syntax. SpriteInvaders A compact Space-Invaders-style sprite demonstration. It shows loaded sprite images, multiple persistent instances, movement, transparent sprites, collision detection, projectiles, keyboard control and timed game loops. NeonDescent A more ambitious 1024x768 scrolling shooter inspired by classic vertically scrolling PC/Amiga shooters. A large bitmap is scrolled with BITBLT while ships, aliens, shots and bombs are handled by the sprite system. It demonstrates many simultaneous sprite instances, pixel-perfect collisions, HUD text over sprites, KEYREPEAT, WAITREL and continuous background motion. complex-demo A 2D Mandelbrot renderer written using the new native complex syntax. Instead of manually carrying separate real and imaginary variables, the iteration can be written directly with @ values: C@=CPLX(CR,CI) Z@=CPLX(0,0) Z@=Z@*Z@+C@ The demo is a compact introduction to CPLX(), @ variables and complex arithmetic inside an ordinary BASIC graphics program. quaternion-demo A quaternion fractal demonstration using the 4-component QUAT() syntax. It renders a three-dimensional ray-marched slice of a four-dimensional quaternion Julia set, using iterations such as: Q@=QUAT(X,Y,Z,W) Q@=Q@*Q@+C@ The program combines quaternion arithmetic, NORM, LOG, ray marching, numerical surface normals and 24-bit graphics. It is deliberately a substantial example of the new mathematics rather than a syntax test. DATA TYPES ---------- Suffix Type ------ ---- % 16-bit integer & 32-bit integer && 64-bit integer ! single-precision floating point # double-precision floating point $ string @ hypercomplex (complex / quaternion / octonion) DEFI64 adds a native 64-bit integer default type. Integer literals and memory addresses can use the full 64-bit range supported by the interpreter. HYPERCOMPLEX NUMBERS -------------------- Thoreau BASIC treats complex numbers, quaternions and octonions as one native @ type. The value carries its current dimension internally: complex 2 components real, i quaternion 4 components real, i, j, k octonion 8 components real, e1, e2, e3, e4, e5, e6, e7 Constructors: Z@=CPLX(3,4) Q@=QUAT(1,2,3,4) O@=OCT(1,2,3,4,5,6,7,8) A plain real number mixed with an @ value is promoted automatically. Promotion follows the Cayley-Dickson tower: real -> complex -> quaternion -> octonion The wider operand determines the result dimension. For example: Z@=CPLX(10,20) Q@=QUAT(1,2,3,4) PRINT Q@+Z@ The complex value is embedded as (10,20,0,0) before quaternion addition. Assigning an ordinary real number to an @ variable creates a complex value with zero imaginary part: A@=5 ' equivalent to CPLX(5,0) @ arrays are ordinary BASIC arrays: DIM Z@(100) DIM Q@(20,20) Z@(10)=CPLX(2,3) COMPONENT ACCESS Named components may be read directly: Z@.R real component Z@.I complex i Q@.R Q@.I Q@.J Q@.K O@.R O@.E1 O@.E2 ... O@.E7 For convenience, .I is the same component as .E1, .J as .E2, and .K as .E3. Array elements and parenthesized hypercomplex expressions may also use the postfix: PRINT Q@(5).K PRINT (A@*B@).E7 PRINT CONJ(Q@).I Reading a component above the value's current dimension returns zero. Assigning such a component promotes the value automatically: A@=CPLX(1,2) A@.K=3 A@ is now a quaternion, equivalent to QUAT(1,2,0,3). COMP(x,n) is the expression-friendly alternative and returns component 0..7. Component 0 is always the real/scalar component: PRINT COMP(A@*B@,3) ARITHMETIC The operators +, -, * and / work directly on @ values. Addition/subtraction are componentwise. Multiplication uses the standard Cayley-Dickson construction with the quaternion convention: i*j = k j*k = i k*i = j Quaternion multiplication is not commutative: I@=QUAT(0,1,0,0) J@=QUAT(0,0,1,0) PRINT I@*J@ ' +k PRINT J@*I@ ' -k Octonion multiplication is neither commutative nor associative. Thoreau uses the language's normal left-associative evaluation, so: A@*B@*C@ means: (A@*B@)*C@ For octonions, A@*(B@*C@) may genuinely produce a different result. This is a property of octonion algebra, not a rounding or parser error. Division is defined explicitly as: A@ / B@ = A@ * INV(B@) Division by a zero-norm value reports Division by zero. FUNCTIONS CONJ(x) conjugate; negate every non-real component INV(x) multiplicative inverse ABS(x) Euclidean magnitude NORM(x) Euclidean magnitude; same result as ABS for @ values NORM2(x) squared Euclidean norm COMP(x,n) component 0..7 Examples: Z@=CPLX(3,4) PRINT ABS(Z@) ' 5 PRINT NORM2(Z@) ' 25 PRINT CONJ(Z@) PRINT Z@*INV(Z@) ' unit value COMPARISON AND OUTPUT = and <> compare all promoted components exactly. Hypercomplex values have no natural ordering, so <, >, <= and >= report Illegal comparison. PRINT and STR$ use a canonical component form and keep the current dimension visible, for example: 3+4i 1+2i+3j+4k 1+2e1+3e2+4e3+5e4+6e5+7e6+8e7 Every component is printed, including zero components. Hypercomplex values are stored internally with double-precision components. TRANSCENDENTAL FUNCTIONS AND POWERS The one-value functions EXP, LOG, SIN, COS, TAN, SINH, COSH, TANH and square root work on complex numbers, quaternions and octonions. SQR and SQRT are equivalent square-root spellings. Ordinary scalar arguments continue to use their traditional real-number behavior. For an @ value x, write x = a + v where a is the real component and v is the vector formed by all non-real components. Let r=|v|. When r is nonzero, u=v/r is the unit imaginary direction carried by x itself. Because the subalgebra generated by one complex/quaternion/octonion value is associative, the same closed forms work for all three dimensions. In particular: EXP(a+v) = exp(a) * (cos(r) + u*sin(r)) SIN(a+v) = sin(a)*cosh(r) + u*cos(a)*sinh(r) COS(a+v) = cos(a)*cosh(r) - u*sin(a)*sinh(r) SINH(a+v) = sinh(a)*cos(r) + u*cosh(a)*sin(r) COSH(a+v) = cosh(a)*cos(r) + u*sinh(a)*sin(r) TAN(x) is SIN(x)/COS(x), and TANH(x) is SINH(x)/COSH(x). A zero denominator reports Division by zero. Large real or vector components can overflow the underlying double-precision exponential/hyperbolic calculations; Thoreau reports Overflow rather than silently returning an invalid @ value. LOG AND PRINCIPAL VALUES LOG is multivalued for complex numbers and even more so for quaternions and octonions. Thoreau therefore defines one deterministic principal value. For a non-real x=a+v: LOG(x) = log(|x|) + u*atan2(|v|,a) For positive real @ values the imaginary part is zero. For a negative real complex value the principal direction is +i, matching the usual complex principal logarithm. A negative real quaternion also chooses +i, while a negative real octonion chooses +e1. These are conventions: infinitely many other quaternion/octonion logarithms are mathematically valid. LOG of a zero @ value, for example LOG(CPLX(0,0)), reports Illegal function call. The same convention determines principal square roots: SQRT(x) = SQR(x) = EXP(.5*LOG(x)) with zero handled directly. Thus: PRINT SQRT(CPLX(-1,0)) PRINT SQRT(QUAT(-1,0,0,0)) PRINT SQRT(OCT(-1,0,0,0,0,0,0,0)) select +i for the complex/quaternion results and +e1 for the octonion result. Other roots exist; Thoreau deliberately returns one repeatable principal root. POWER OPERATOR The exponent of an @ value must be an ordinary real scalar: Q@^2 Q@^-3 O@^.5 Integer exponents are evaluated by exponentiation by squaring. This is unambiguous even for octonions because the Cayley-Dickson algebras used here are power-associative: powers of one value have a well-defined meaning. Negative integer exponents use INV(x). Non-integer real powers use the principal definition: x^p = EXP(p*LOG(x)) so they inherit the LOG branch convention described above. Zero to a positive real power is zero; zero to a negative power reports Division by zero. A hypercomplex exponent is intentionally not accepted: A@^B@ ' Type mismatch For quaternions, EXP(B@*LOG(A@)) and EXP(LOG(A@)*B@) need not agree because multiplication is non-commutative. Octonions additionally make parenthesization significant. Thoreau does not choose one of those inequivalent definitions silently. IDENTITIES AND QUIRKS Functions of a single @ value are well defined under the rules above, but many familiar multi-value identities require commuting operands. For example, with independent quaternion or octonion values A@ and B@, users must not generally assume: EXP(A@+B@) = EXP(A@)*EXP(B@) or ordinary trigonometric addition formulas. Octonion multiplication remains non-associative, so explicit parentheses can change expressions involving several independently oriented values. This is mathematical behavior, not an interpreter quirk. Examples: Z@=CPLX(0,1) PRINT EXP(Z@) PRINT SIN(Z@) PRINT COS(Z@) Q@=QUAT(1,2,3,4) PRINT EXP(LOG(Q@)) PRINT Q@^2 PRINT Q@^.5 O@=OCT(-1,0,0,0,0,0,0,0) PRINT SQRT(O@) ' principal +e1 root WRITE#/INPUT# do not define a portable textual @ serialization; use STR$ or store components explicitly when a file representation is needed. ERROR HANDLING -------------- ON ERROR GOTO 9000 ... 9000 PRINT "ERROR";ERR;"AT";ERL 9010 RESUME NEXT Runtime errors print their message and source line, for example: Illegal function call in 1230 ON BREAK GOTO can trap ESC/break events. RESUME, RESUME NEXT and RESUME line leave an active error/break handler correctly. PROGRAMMABLE TIMERS ------------------- Eight independent timers are available, numbered 0 through 7. TIMER(0)=1000 ON TIMER(0) GOSUB 9000 TIMER(0) ON Intervals are milliseconds. Timers are non-preemptive and are dispatched between BASIC statements. RELATIVE FRAME PACING --------------------- WAITREL is intended for game loops, animation and other code that needs a stable frame period without manually subtracting TIMER values: WAITREL milliseconds The first WAITREL establishes the reference point and waits the requested interval. Later calls wait only for the time still remaining since the previous WAITREL returned. Code executed between calls therefore counts toward the interval. For example: 100 GOSUB 1000 110 WAITREL 16 120 GOTO 100 If the game logic in GOSUB 1000 takes 5 ms, WAITREL waits roughly another 11 ms. If a frame already took 20 ms, WAITREL 16 returns immediately and re-anchors to the current time. It deliberately does not generate catch-up frames. WAITREL 0 can be used to reset the reference without a delay. WAITREL uses the platform's monotonic high-resolution timing. On modern Windows it uses a high-resolution waitable timer when available; on older Windows it yields while waiting rather than inheriting the coarse desktop Sleep() interval. On UEFI it uses short firmware Stall() intervals. ESC and ON BREAK GOTO remain responsive while WAITREL is waiting. UEFI INTERNATIONAL KEYBOARD SUPPORT =================================== This section applies only to the x64 UEFI build. Windows uses the normal Windows keyboard input and does not use THOREAU.CFG or KEYB layout translation. At startup, Thoreau looks for THOREAU.CFG in the directory containing the EFI. A keyboard layout is selected with a DOS-style line such as: KEYB GR If THOREAU.CFG is absent, the default is US. Blank lines and lines beginning with ;, # or REM are ignored. An unknown KEYB code falls back to US at startup. The active layout can be displayed or changed immediately from BASIC: KEYB KEYB GR KEYB UK KEYB US A runtime KEYB change affects only the current session and does not rewrite THOREAU.CFG. An unknown runtime code leaves the current layout unchanged. Supported layouts: Code Layout Code page ---- ----------------------------- --------- BE Belgium 850 BR Brazil 850 DK Denmark 850 GR Germany 850 SU Finland 850 FR France 850 UK United Kingdom 850 IT Italy 850 YU Yugoslavia 852 CF Canadian French 850 LA Latin America 850 NL Netherlands 850 NO Norway 850 PL Poland 852 PO Portugal 850 SV Sweden 850 SG Swiss German 850 SF Swiss French 850 SP Spain 850 SL Slovak 852 CZ Czech 852 HU Hungary 852 US USA 437 On a compatible USB HID boot keyboard, Thoreau can read raw HID reports and translate physical key usages itself. This avoids firmware errors involving international keys, including the ISO 102nd key used for <, > and | on several European layouts. Raw USB HID is preferred, but it cannot be assumed on every UEFI machine. An internal laptop keyboard, PS/2-style keyboard, Bluetooth keyboard, firmware- managed keyboard controller, or a USB keyboard whose EFI_USB_IO_PROTOCOL device cannot be safely taken over may be available only through the generic UEFI text input interface. Rather than make Thoreau unusable on such systems, it falls back to firmware keyboard input. The active backend is shown at startup. Typical status lines are: Keyboard: GR (CP850, USB HID) Keyboard: GR (CP850, firmware) The difference has practical consequences. Raw USB HID exposes physical key usages and key-release state, so Thoreau can distinguish international physical keys accurately, apply its own KEYB layout translation and implement independent KEYREPEAT timing. Firmware input has already been interpreted by the firmware and does not provide reliable key-release events. Thoreau can still apply the selected layout as far as the received key information allows, but it cannot recover a physical key the firmware never reports. In particular, a firmware that collapses or omits the ISO 102nd key cannot be repaired by software above that interface. For the same reason, KEYREPEAT delay/rate control is available on raw USB HID UEFI input but not on firmware fallback. In firmware mode the firmware owns repeat timing. The fallback is therefore a compatibility path, not the preferred keyboard backend: it keeps more machines usable at the cost of less complete physical-key information and no independent key-up/repeat control. INKEY$ EXTENDED KEYS ==================== This section applies to both Windows and UEFI. INKEY$ returns an empty string when no key is waiting and a one-character string for ordinary character keys. Supported extended keys use the classic Microsoft BASIC/DOS two-byte form: CHR$(0)+CHR$(scan) The scan values are: Key Scan Key Scan --------- ---- --------- ---- F1 59 F6 64 F2 60 F7 65 F3 61 F8 66 F4 62 F9 67 F5 63 F10 68 Home 71 Up 72 Page Up 73 Left 75 Right 77 End 79 Down 80 Page Down 81 Insert 82 Delete 83 For example: K$=INKEY$ IF K$=CHR$(0)+CHR$(72) THEN PRINT "UP" IF K$=CHR$(0)+CHR$(80) THEN PRINT "DOWN" IF K$=CHR$(0)+CHR$(75) THEN PRINT "LEFT" IF K$=CHR$(0)+CHR$(77) THEN PRINT "RIGHT" This makes old BASIC games that test DOS/GW-BASIC extended-key strings portable between the Windows and UEFI builds. KEY REPEAT FOR GAMES ==================== KEYREPEAT can override the usual typematic delay: KEYREPEAT delayMilliseconds,rateHz KEYREPEAT DEFAULT For example: KEYREPEAT 0,30 The initial key press is delivered immediately. With a delay of 0, the first repeat follows after one normal repeat interval, so 0,30 feels continuous for game movement instead of waiting through the desktop keyboard-repeat delay. On Windows, custom KEYREPEAT timing is generated by Thoreau from key-down and key-up state and does not depend on the Windows user repeat setting. DEFAULT returns control to the normal Windows typematic setting. On UEFI with direct raw USB HID keyboard input, Thoreau also has key-up state and uses the requested timing. The UEFI firmware text-input fallback does not expose key-up state, so firmware repeat timing cannot be overridden there. KEYREPEAT DEFAULT restores the raw-HID default of approximately 500 ms at 30 repeats per second. 24-BIT GW-BASIC GRAPHICS ======================== Thoreau BASIC keeps the classic GW-BASIC graphics model, but the drawing surface is a modern 24-bit RGB framebuffer. COLOR VALUES ------------ Most graphics commands accept the traditional palette numbers 0 through 15. Those map to the 16 CGA-style colors. They also accept a packed 24-bit RGB value: &HRRGGBB Examples: &HFF0000 red &H00FF00 green &H0000FF blue &HFF8800 orange &H202020 dark gray Internally the low 24 bits are used as 0xRRGGBB. A non-negative color value greater than 15 is interpreted as a direct RGB color. Several commands also accept three separate RGB components, each 0 through 255: red,green,blue For example, these two commands draw the same color: PSET (100,100),&HFF8800 PSET (100,100),255,136,0 PSET / PRESET ------------- Classic forms: PSET [STEP](x,y)[,color] PRESET [STEP](x,y)[,color] Thoreau 24-bit forms: PSET [STEP](x,y),r,g,b PRESET [STEP](x,y),r,g,b Examples: PSET (100,80),&H40C0FF PSET (100,80),64,192,255 PRESET STEP(10,0),255,0,0 If the color is omitted, PSET uses the current foreground color and PRESET uses the current background color. Both update the GW-BASIC "last point referenced", so STEP coordinates and LINE -(x,y) retain classic behavior. LINE ---- Classic geometry and B/BF box flags are retained: LINE [[STEP](x1,y1)]-[STEP](x2,y2)[,color][,B|BF] The color may be a palette number, a packed 24-bit value, or an RGB triple: LINE (10,10)-(300,150),&HFF8800 LINE (10,10)-(300,150),255,136,0 LINE (10,10)-(300,150),255,136,0,B LINE (10,10)-(300,150),30,80,160,BF B draws a box and BF draws a filled box. If the first point is omitted, LINE starts from the last point referenced: PSET (20,20) LINE -(200,100),&H00FF80 STEP on the second point is relative to the first point of that LINE. CIRCLE ------ CIRCLE [STEP](x,y),radius[,color[,start[,end[,aspect]]]] CIRCLE accepts a palette color or one packed 24-bit RGB value: CIRCLE (320,240),100,&HFF8800 The GW-BASIC start, end and aspect arguments are accepted by the parser so older source continues to load, but in Thoreau BASIC 2.3 they are currently ignored. CIRCLE therefore draws a complete circle rather than arcs or ellipses. PAINT ----- PAINT [STEP](x,y)[,paint[,border]] The paint color accepts a palette/direct color or an RGB triple: PAINT (100,100),&H204080 PAINT (100,100),32,64,128 An optional border color follows. The border is one palette/direct packed color value: PAINT (100,100),32,64,128,&HFFFFFF The fill is a four-connected scanline flood fill. If border is omitted, the paint color is also used as the border color, matching the GW-BASIC default. COLOR ----- COLOR controls the current foreground/background colors used by text and by graphics commands whose color is omitted. Traditional forms: COLOR fg COLOR fg,bg COLOR ,bg Both fg and bg may be palette numbers or packed 24-bit colors: COLOR &H80FF40,&H101810 Thoreau also accepts RGB triples: COLOR r,g,b COLOR r,g,b,background_r,background_g,background_b Examples: COLOR 255,136,0 COLOR 255,136,0,16,16,16 Named text windows can have their own colors: COLOR @1,255,255,0,0,0,64 POINT ----- POINT(x,y) POINT reads the framebuffer pixel. For compatibility, if the pixel exactly matches one of the 16 standard palette entries, POINT returns the palette index 0 through 15. Otherwise it returns the raw packed 24-bit RGB value. Example: PSET (10,10),255,136,0 PRINT HEX$(POINT(10,10)) prints: FF8800 POINT returns -1 outside the screen or outside the active graphics VIEW. GET / PUT --------- The classic sprite/image commands operate on full 24-bit pixels: GET [STEP](x1,y1)-[STEP](x2,y2),array PUT [STEP](x,y),array[,PSET|PRESET|XOR|AND|OR] GET stores an 8-byte width/height header followed by one 32-bit value per pixel; the low 24 bits contain 0xRRGGBB. The numeric array must therefore provide at least: 8 + 4 * width * height bytes of storage. Example for a 64x64 image using a LONG array and OPTION BASE 0: OPTION BASE 0 DIM SPR&(4097) GET (0,0)-(63,63),SPR& PUT (200,100),SPR&,PSET PUT supports PSET, PRESET, XOR, AND and OR. XOR is the default, as in GW-BASIC. All operations are masked to 24 bits. GET and PUT require the entire rectangle to fit on screen; an out-of-bounds rectangle raises Illegal function call. PSET, LINE, CIRCLE and PAINT instead clip silently at the screen/VIEW boundary. DRAW ---- Thoreau implements the GW-BASIC Graphics Macro Language commands: U D L R E F G H M B N A TA C S The C command uses the same color resolver as the other graphics commands: 0 through 15 are palette colors, while larger values are packed RGB. Inside DRAW strings, numeric values are decimal or may be taken from a BASIC variable with =name; syntax. This is convenient for hexadecimal RGB values: COL&&=&HFF8800 DRAW "C=COL&&;R80D40L80U40" WINDOW / VIEW / SCREEN ---------------------- GW-BASIC logical graphics coordinates are supported: WINDOW (x1,y1)-(x2,y2) WINDOW SCREEN (x1,y1)-(x2,y2) Without SCREEN, Y increases upward in logical coordinates. With SCREEN, Y increases downward. WINDOW affects coordinate mapping; it is not a display page selector. VIEW defines a physical graphics clipping rectangle: VIEW [SCREEN] (x1,y1)-(x2,y2)[,fill[,border]] VIEW fill and border accept palette numbers or packed 24-bit colors: VIEW SCREEN (0,0)-(639,479),&H101820,&HFFFFFF SCREEN selects a graphics mode by dimensions rather than by an old DOS mode number: SCREEN 640,480 SCREEN 800,600 SCREEN 1024,768 The requested dimensions must correspond to a mode supported by the platform. BITMAP GRAPHICS --------------- In addition to the extended GW-BASIC-style drawing commands: LOADBMP slot,file$ BITBLT slot,x,y[,keyColor] BITBLT slot,(x,y)[,keyColor] SAVEBMP file$ [,(x1,y1)-(x2,y2)] LOADBMP reads an uncompressed 24-bit or 32-bit Windows BMP into a bitmap slot from 0 through 65535. BITBLT draws the loaded bitmap at the requested physical framebuffer position and clips it to the screen. The destination can be written as flat x,y parameters or as a parenthesized (x,y) point. With keyColor, source pixels matching the low 24 bits of that 0xRRGGBB value are transparent. SAVEBMP writes an uncompressed 24-bit BMP. With no rectangle it saves the active graphics VIEW, or the full graphics screen when no VIEW is active. An explicit (x1,y1)-(x2,y2) rectangle saves exactly that framebuffer region. Examples: LOADBMP 0,"PICS\FOREST.BMP" BITBLT 0,(0,0) BITBLT 0,(100,80),&HFF00FF SAVEBMP "SCREEN.BMP" SAVEBMP "PART.BMP",(100,80)-(399,279) Bitmap pixels are allocated from BASIC data memory and count against FRE. Replacing a loaded slot reclaims its previous pixel block. CLEAR, NEW, RUN or LOAD reclaim all loaded bitmap slots. LOADBMP/BITBLT is intended for external image assets, SAVEBMP writes framebuffer regions to disk, and GET/PUT captures and restores framebuffer regions in BASIC arrays. SOFTWARE SPRITES ---------------- Sprites use two kinds of slots: image slots 0..65535 loaded pixel data + opacity mask instance slots 0..65535 image reference, position and visibility This separation means one loaded image can be drawn as any number of independent instances without loading or storing the pixel data repeatedly. Load a sprite image: LOADSPRITE image,file$[,transparentColor] Examples: LOADSPRITE 0,"SPRITES\ALIEN.BMP",&HFF00FF LOADSPRITE 1,"SPRITES\SHIP.BMP",&HFF00FF The BMP may be larger than the current screen; drawing is clipped. The practical limit is BASIC memory. LOADSPRITE accepts the same uncompressed 24-bit and 32-bit BMP forms as LOADBMP, with the same 8192-pixel per-side safety limit. If transparentColor is omitted, every source pixel is opaque. Create one or more instances from the same image: SPRITE 0,0,(100,80) SPRITE 1,0,(200,80) SPRITE 2,0,(300,80) The flat coordinate form is accepted too: SPRITE 3,0,400,80 All four instances share image slot 0. SPRITE creates/reassigns the instance and makes it visible. Move or control instances: MOVESPRITE 1,(210,90) MOVESPRITE 1,210,90 HIDESPRITE 2 SHOWSPRITE 2 DELSPRITE 3 MOVESPRITE restores the old background and redraws the affected sprite layer, so moving instances do not leave trails. DELSPRITE removes only the instance; the shared image remains loaded and may still be used by other instances. Coordinates are physical framebuffer pixels and are not transformed by WINDOW. Negative/off-screen positions are valid; visible portions are clipped. Instance position functions: X=SPRITEX(1) Y=SPRITEY(1) Pixel-perfect collision: IF SPRITECOLLIDE(0,1) THEN PRINT "HIT" SPRITECOLLIDE returns -1 only when both instances exist, are visible, their rectangles overlap, and at least one pair of opaque source pixels occupies the same position. Hidden instances never collide. A fast rectangle test is done first; only the overlap area is examined pixel-by-pixel. When a transparency color is supplied to LOADSPRITE, Thoreau builds a compact 1-bit opacity mask once while loading the image. Every instance sharing that image also shares its mask. For a 32x32 image the collision mask is only 128 bytes. Text/sprite layering is selectable: SPRITETEXT UNDER SPRITETEXT OVER UNDER is the default and keeps the original behavior: sprite pixels appear over normal text. OVER redraws text foreground pixels after sprite compositing, so HUD text remains visible above moving sprites. Text-cell background pixels are not made into an opaque top layer; if a solid HUD panel is wanted, draw its background explicitly with the normal graphics commands. Sprite images use the BASIC DATA arena and count against FRE(0). Re-loading an image slot returns its old pixel and mask storage to the reusable allocator. CLEAR, NEW, RUN and LOAD discard all sprite images and instances together. LANGUAGE REFERENCE ================== PROGRAM EDITING / EXECUTION --------------------------- AUTO Syntax: AUTO [start][,increment] Does: automatic line numbers; existing lines are marked with * and an immediate Enter preserves the existing line Example: AUTO 1000,10 CHAIN Syntax: CHAIN [MERGE] file$[,[line][,[ALL][,DELETE range]]] Does: load/overlay another program; COMMON controls transferred variables Example: CHAIN MERGE "PART2.BAS",2000 COMMON Syntax: COMMON var[,var...] Does: variables/arrays passed by CHAIN without ALL Example: COMMON SCORE%,PLAYER$ CONT Syntax: CONT Does: continue after STOP or an untrapped break Example: CONT DELETE Syntax: DELETE range Does: remove stored program lines Example: DELETE 1000-1990 EDIT Syntax: EDIT line | EDIT ERL Does: edit a stored line or the last error line Example: EDIT ERL FIND Syntax: FIND string$[,range] Does: case-insensitive search of program source; ranges: n, n-m, -m, n- Example: FIND "GOSUB",1000-5000 END Syntax: END Does: end program and close files Example: END HELP Syntax: HELP [name] Does: categorized built-in language reference; uses the full physical text screen and wraps at word boundaries, ignoring TXTWINDOW/VIEW PRINT while HELP is displayed Example: HELP LOADBMP LIST Syntax: LIST [range|ERL] [NOWAIT] Does: ERL lists the last error line; ranges: n, n-m, -m, n-; paging is standard, NOWAIT disables it; ESC aborts Example: LIST 1000-2000 NOWAIT LOAD Syntax: LOAD file$ Does: load ASCII BASIC program; omitted extension defaults to .BAS; closing quote may be omitted Example: LOAD "PIXELPROSE CREATEEXE Syntax: CREATEEXE file$ Does: create standalone Windows EXE from the current program; .EXE is added if omitted Platform: Windows only Example: CREATEEXE "PixelProse CREATEEFI Syntax: CREATEEFI file$ Does: create standalone UEFI application from the current program; .EFI is added if omitted Platform: UEFI only Example: CREATEEFI "PixelProse MERGE Syntax: MERGE file$ Does: merge ASCII program lines Example: MERGE "EXTRA.BAS" NEW Syntax: NEW Does: clear program and variables Example: NEW RENUM Syntax: RENUM [new][,old][,increment] Example: RENUM 1000,10,10 RUN Syntax: RUN [line|file$] Does: clear variables and run the stored program; a line number starts at that exact line; file$ is loaded first and defaults to .BAS when no extension is supplied; the closing filename quote may be omitted Example: RUN 1000 Example: RUN "GAME SAVE Syntax: SAVE file$[,A] Does: save ASCII BASIC program; omitted extension defaults to .BAS Example: SAVE "GAME",A STOP Syntax: STOP Does: print "Break in line", pause the program and preserve a continuation; CONT may resume after the STOP Example: STOP REM Syntax: REM comment or apostrophe comment Example: REM this is a comment FLOW / ERRORS / DIAGNOSTICS --------------------------- ERROR Syntax: ERROR n Does: raise an error Example: ERROR 5 FOR Syntax: FOR v=start TO limit [STEP step] ... NEXT Example: FOR I=1 TO 10 STEP 2 GOSUB Syntax: GOSUB line Does: call subroutine Example: GOSUB 9000 GOTO Syntax: GOTO line Does: branch Example: GOTO 1000 IF Syntax: IF condition THEN ... [ELSE ...] Does: conditional statement; in nested single-line forms each ELSE binds to the nearest unmatched IF, including across GOSUB/RETURN Example: IF SCORE>100 THEN 5000 ELSE 2000 NEXT Syntax: NEXT [v] Does: end FOR loop Example: NEXT I ON Syntax: ON expr GOTO/GOSUB ...; ON ERROR/BREAK GOTO line Example: ON CHOICE GOTO 1000,2000,3000 RESUME Syntax: RESUME [NEXT|0|line] Example: RESUME NEXT RETURN Syntax: RETURN Does: return from GOSUB Example: RETURN TROFF Syntax: TROFF Does: disable line-number tracing Example: TROFF TRON Syntax: TRON [line[-line]] Does: trace all lines or only the selected line/range Example: TRON 1000-2000 TRACE Syntax: TRACE var[,var...] Does: show selected scalar values as program lines execute; TRACE OFF clears watches Example: TRACE SCORE%,ROOM% WHILE Syntax: WHILE condition ... WEND Example: WHILE A<10 WEND Syntax: WEND Does: end WHILE loop Example: WEND ERL Syntax: ERL Does: line number of last error Example: PRINT ERL ERR Syntax: ERR Does: last error number Example: PRINT ERR VARINFO Syntax: VARINFO [SIMPLE|FULL|0|1] Does: list scalar variables; FULL adds type/value/address; output pauses each screen Example: VARINFO FULL ARRAYINFO Syntax: ARRAYINFO [SIMPLE|FULL|0|1] Does: list arrays; FULL adds type/size/address; output pauses each screen Example: ARRAYINFO FULL VARIABLES / DATA / CONVERSION ----------------------------- CLEAR Syntax: CLEAR Does: clear variables/data Example: CLEAR DATA Syntax: DATA values Does: embedded program data Example: DATA 10,20,"forest" DEFDBL Syntax: DEFDBL letters Does: default double type Example: DEFDBL A-Z DEFI64 Syntax: DEFI64 letters Does: default 64-bit integer type Example: DEFI64 A-Z DEFINT Syntax: DEFINT letters Does: default integer type Example: DEFINT I-N DEFLNG Syntax: DEFLNG letters Does: default long type Example: DEFLNG L DEFSNG Syntax: DEFSNG letters Does: default single type Example: DEFSNG S DEFSTR Syntax: DEFSTR letters Does: default string type Example: DEFSTR A-C DIM Syntax: DIM array(bounds) Does: dimension arrays Example: DIM MAP%(100) ERASE Syntax: ERASE array[,array...] Does: undefine arrays and return their storage for reuse; live array addresses do not move Example: ERASE MAP% OPTION Syntax: OPTION BASE 0|1 Does: default array lower bound Example: OPTION BASE 1 READ Syntax: READ variables Does: consume DATA Example: READ X,Y,NAME$ RESTORE Syntax: RESTORE [line] Does: reset DATA pointer Example: RESTORE 1000 SWAP Syntax: SWAP a,b Example: SWAP A,B CDBL Syntax: CDBL(x) Does: convert to double Example: X#=CDBL(A) CINT Syntax: CINT(x) Does: convert to integer Example: I%=CINT(X) CSNG Syntax: CSNG(x) Does: convert to single Example: S!=CSNG(X) CVD Syntax: CVD(s$) Does: MBF double from 8 bytes Example: X#=CVD(B$) CVI Syntax: CVI(s$) Does: integer from 2 bytes Example: I%=CVI(B$) CVS Syntax: CVS(s$) Does: MBF single from 4 bytes Example: S!=CVS(B$) MKD$ Syntax: MKD$(x) Does: 8-byte MBF double Example: B$=MKD$(X#) MKI$ Syntax: MKI$(n) Does: 2-byte integer Example: B$=MKI$(I%) MKS$ Syntax: MKS$(x) Does: 4-byte MBF single Example: B$=MKS$(S!) VARPTR Syntax: VARPTR(variable) Does: 64-bit address Example: PRINT HEX$(VARPTR(A)) HYPERCOMPLEX VARIABLES Syntax: name@ | name@(subscripts) | name@.R/.I/.J/.K/.E1..E7 Does: store complex, quaternion or octonion values in one native type; supports + - * / and ^ with a real scalar exponent Example: Q@=QUAT(1,2,3,4):PRINT Q@^.5 FUNCTIONS --------- DEF FN Syntax: DEF FNname(args)=expr Does: define a user function whose body is one expression Example: DEF FNSQUARE(X)=X*X IIF Syntax: IIF(condition,ifTrue,ifFalse) Does: evaluate condition, then evaluate and return only the selected branch; the unselected expression is not evaluated Example: DEF FNSAFE(X)=IIF(X=0,0,1/X) ABS Syntax: ABS(x) Does: absolute value; for @ values returns Euclidean magnitude Example: PRINT ABS(CPLX(3,4)) CPLX Syntax: CPLX(real,i) Does: construct a complex @ value Example: Z@=CPLX(3,4) QUAT Syntax: QUAT(real,i,j,k) Does: construct a quaternion @ value Example: Q@=QUAT(1,2,3,4) OCT Syntax: OCT(real,e1,e2,e3,e4,e5,e6,e7) Does: construct an octonion @ value Example: O@=OCT(1,2,3,4,5,6,7,8) CONJ Syntax: CONJ(x) Does: hypercomplex conjugate Example: PRINT CONJ(CPLX(3,4)) INV Syntax: INV(x) Does: multiplicative inverse; A@/B@ is defined as A@*INV(B@) Example: PRINT INV(QUAT(1,2,3,4)) NORM Syntax: NORM(x) Does: Euclidean magnitude Example: PRINT NORM(CPLX(3,4)) NORM2 Syntax: NORM2(x) Does: squared Euclidean norm Example: PRINT NORM2(CPLX(3,4)) COMP Syntax: COMP(x,n) Does: return hypercomplex component 0..7; component 0 is real Example: PRINT COMP(QUAT(1,2,3,4),3) ASC Syntax: ASC(s$) Does: character code Example: PRINT ASC("A") ATN Syntax: ATN(x) Does: arctangent Example: PRINT ATN(1) CHR$ Syntax: CHR$(n) Does: one-character string Example: PRINT CHR$(65) COS Syntax: COS(x) Does: cosine; accepts scalar or @ values Example: PRINT COS(CPLX(1,2)) COSH Syntax: COSH(x) Does: hyperbolic cosine; accepts scalar or @ values Example: PRINT COSH(QUAT(1,2,3,4)) EXP Syntax: EXP(x) Does: exponential; accepts scalar or @ values Example: PRINT EXP(CPLX(0,1)) FIX Syntax: FIX(x) Does: truncate toward zero Example: PRINT FIX(-3.7) HEX$ Syntax: HEX$(n) Does: hexadecimal string Example: PRINT HEX$(255) INSTR Syntax: INSTR([start,]string$,search$) Example: PRINT INSTR("FOREST","REST") INT Syntax: INT(x) Does: floor Example: PRINT INT(-3.7) LCASE$ Syntax: LCASE$(s$) Does: convert ASCII A-Z to lowercase Example: PRINT LCASE$("GORSE") UCASE$ Syntax: UCASE$(s$) Does: convert ASCII a-z to uppercase Example: PRINT UCASE$("gorse") LEFT$ Syntax: LEFT$(s$,n) Example: PRINT LEFT$("THOREAU",3) LEN Syntax: LEN(s$) Example: PRINT LEN("BASIC") LOG Syntax: LOG(x) Does: natural logarithm; @ values use the documented principal branch Example: PRINT LOG(QUAT(-1,0,0,0)) MID$ Syntax: MID$(s$,start[,len]) or MID$(s$,start[,len])=value$ Example: MID$(A$,2,3)="XYZ" OCT$ Syntax: OCT$(n) Does: octal string Example: PRINT OCT$(64) RIGHT$ Syntax: RIGHT$(s$,n) Example: PRINT RIGHT$("THOREAU",4) RND Syntax: RND[(x)] Does: random number Example: PRINT RND(1) SGN Syntax: SGN(x) Does: sign Example: PRINT SGN(-9) SIN Syntax: SIN(x) Does: sine; accepts scalar or @ values Example: PRINT SIN(CPLX(1,2)) SINH Syntax: SINH(x) Does: hyperbolic sine; accepts scalar or @ values Example: PRINT SINH(QUAT(1,2,3,4)) SPACE$ Syntax: SPACE$(n) Example: PRINT "A"+SPACE$(5)+"B" SQR Syntax: SQR(x) Does: square root; @ values use the documented principal root Example: PRINT SQR(CPLX(-1,0)) SQRT Syntax: SQRT(x) Does: alias for SQR; @ values use the documented principal root Example: PRINT SQRT(OCT(-1,0,0,0,0,0,0,0)) STR$ Syntax: STR$(x) Does: number to string; @ values use canonical component notation Example: A$=STR$(42) STRING$ Syntax: STRING$(n,char) Example: PRINT STRING$(20,"*") TAN Syntax: TAN(x) Does: tangent; accepts scalar or @ values Example: PRINT TAN(CPLX(1,2)) TANH Syntax: TANH(x) Does: hyperbolic tangent; accepts scalar or @ values Example: PRINT TANH(QUAT(1,2,3,4)) VAL Syntax: VAL(s$) Does: string to number Example: PRINT VAL("123.5") INPUT / OUTPUT -------------- CLS Syntax: CLS [@n] Does: clear screen/text window Example: CLS COLOR Syntax: COLOR fg[,bg] | COLOR r,g,b | COLOR r,g,b,rb,gb,bb Does: set foreground/background; 0-15 = palette, >15 = packed 0xRRGGBB Example: COLOR 255,136,0,16,16,16 CSRLIN Syntax: CSRLIN Does: current text row Example: PRINT CSRLIN INKEY$ Syntax: INKEY$ Does: nonblocking key string; supported extended keys return the classic two-byte form CHR$(0)+CHR$(DOS scan) Example: K$=INKEY$ Example: IF K$=CHR$(0)+CHR$(72) THEN PRINT "UP" KEYREPEAT Syntax: KEYREPEAT delayMilliseconds,rateHz | KEYREPEAT DEFAULT Does: custom typematic timing on Windows and raw USB HID UEFI; firmware UEFI fallback keeps firmware repeat timing Example: KEYREPEAT 0,30 INPUT Syntax: INPUT [prompt;] variables or INPUT #n,... Example: INPUT "Your name";N$ INPUT$ Syntax: INPUT$(count[,[#]n]) Does: read characters Example: A$=INPUT$(1) LOCATE Syntax: LOCATE [@n,]row,col Example: LOCATE 10,20 POS Syntax: POS(x) Does: current text column Example: PRINT POS(0) PRINT Syntax: PRINT expressions; PRINT USING; PRINT #; PRINT @; PRINT WRAP [width,]string$; PRINT JUSTIFY [width,]string$ Example: PRINT WRAP 60,TEXT$ SPC Syntax: SPC(n) Does: PRINT spacing Example: PRINT "A";SPC(5);"B" TAB Syntax: TAB(n) Does: PRINT tab position Example: PRINT TAB(20);"column 20" TXTWINDOW Syntax: TXTWINDOW col1,row1,col2,row2 sets the normal text region; bare TXTWINDOW restores full screen; TXTWINDOW @n,col1,row1,col2,row2 defines a named region Does: define a 1-based text-cell rectangle (columns and rows, not graphics x/y coordinates) Example: TXTWINDOW 1,20,80,30 TXTMAXX Syntax: TXTMAXX Does: text columns Example: PRINT TXTMAXX TXTMAXY Syntax: TXTMAXY Does: text rows Example: PRINT TXTMAXY WRITE Syntax: WRITE values or WRITE #n,values Example: WRITE "room",ROOM% FILES / DIRECTORIES ------------------- APPEND Syntax: APPEND Does: OPEN mode Example: OPEN "LOG.TXT" FOR APPEND AS #1 AS Syntax: AS Does: OPEN/FIELD syntax word Example: OPEN "SAVE.DAT" FOR OUTPUT AS #1 BLOAD Syntax: BLOAD file$[,address] Does: load GW memory image Example: BLOAD "IMAGE.BIN",&H10000 BSAVE Syntax: BSAVE file$,address,length Does: save GW memory image Example: BSAVE "IMAGE.BIN",&H10000,4096 CHDIR Syntax: CHDIR path$ Does: change directory Example: CHDIR "GAMES" CLOSE Syntax: CLOSE [#n,...] Does: close files Example: CLOSE #1 EOF Syntax: EOF(n) Does: end-of-file state Example: WHILE NOT EOF(1) FIELD Syntax: FIELD #n,width AS s$,... Does: map random-file record fields Example: FIELD #1,20 AS NAME$,4 AS SCORE$ DIR Syntax: DIR [pattern$][,S][,W][,P] Does: alias for FILES; names and paths print uppercase; S recurses, W wide listing, P pauses; ESC aborts listing/traversal Example: DIR "*.BAS",S,W,P FILES Syntax: FILES [pattern$][,S][,W][,P] Does: names and paths print uppercase; directories come first with [DIR] and case-insensitive sorting; wildcards are supported; S recurses, W uses wide output, P pauses; ESC aborts Example: FILES "*.BMP",W GET Syntax: GET (x1,y1)-(x2,y2),array or GET #n[,record] Does: graphics GET stores a full 24-bit framebuffer rectangle in a numeric array Example: GET (0,0)-(63,63),SPR& File example: GET #1,5 KILL Syntax: KILL filespec$ Does: delete one or more files; * and ? wildcards are supported; wildcard deletion is non-recursive and never removes directories Example: KILL "*.TMP" LOC Syntax: LOC(n) Does: file position/record Example: PRINT LOC(1) LOF Syntax: LOF(n) Does: file length Example: PRINT LOF(1) LSET Syntax: LSET field$=value$ Does: left-align random field Example: LSET NAME$="THOREAU" MKDIR Syntax: MKDIR path$ Does: create directory Example: MKDIR "SAVES" NAME Syntax: NAME old$ AS new$ Does: rename file/directory Example: NAME "OLD.SAV" AS "NEW.SAV" OPEN Syntax: OPEN file$ FOR mode AS #n or classic OPEN mode,#n,file$ Example: OPEN "SAVE.DAT" FOR INPUT AS #1 OUTPUT Syntax: OUTPUT Does: OPEN mode Example: OPEN "OUT.TXT" FOR OUTPUT AS #1 PUT Syntax: PUT (x,y),array[,PSET|PRESET|XOR|AND|OR] or PUT #n[,record] Does: graphics PUT restores 24-bit GET data; default graphics mode is XOR Example: PUT (200,100),SPR&,PSET File example: PUT #1,5 RMDIR Syntax: RMDIR path$ Does: remove empty directory Example: RMDIR "EMPTYDIR" RSET Syntax: RSET field$=value$ Does: right-align random field Example: RSET SCORE$=MKI$(1000) GRAPHICS -------- BITBLT Syntax: BITBLT slot,x,y[,keyColor] or BITBLT slot,(x,y)[,keyColor] Does: draw bitmap slot 0..65535 at a physical framebuffer position; optional keyColor is transparent Example: BITBLT 0,(100,80),&HFF00FF CIRCLE Syntax: CIRCLE [STEP](x,y),radius[,color[,start[,end[,aspect]]]] Does: draw a circle; color is palette 0-15 or packed 0xRRGGBB; start/end/aspect are currently ignored Example: CIRCLE (320,240),100,&HFF8800 DRAW Syntax: DRAW string$ Does: GW Graphics Macro Language (U,D,L,R,E,F,G,H,M,B,N,A,TA,C,S); C accepts palette or packed 24-bit RGB Example: COL&&=&HFF8800 : DRAW "C=COL&&;R40D40L40U40" GRAMAXX Syntax: GRAMAXX Does: graphics width Example: PRINT GRAMAXX GRAMAXY Syntax: GRAMAXY Does: graphics height Example: PRINT GRAMAXY GRAPITCH Syntax: GRAPITCH Does: framebuffer pixels per row Example: PRINT GRAPITCH LINE Syntax: LINE [[STEP](x1,y1)]-[STEP](x2,y2)[,color|r,g,b][,B|BF] or LINE INPUT Does: draw line/box/filled box; graphics color may be palette, packed 0xRRGGBB or RGB triple Example: LINE (10,10)-(200,100),255,136,0,BF LOADBMP Syntax: LOADBMP slot,file$ Does: load an uncompressed 24/32-bit BMP into slot 0..65535 Example: LOADBMP 0,"FOREST.BMP" LOADSPRITE Syntax: LOADSPRITE image,file$[,transparentColor] Does: load sprite image 0..65535 and build its shared opacity mask Example: LOADSPRITE 0,"SPRITES\ALIEN.BMP",&HFF00FF SPRITE Syntax: SPRITE instance,image,(x,y) or SPRITE instance,image,x,y Does: create/reassign/show instance 0..65535 using a loaded image Example: SPRITE 12,0,(100,80) MOVESPRITE Syntax: MOVESPRITE instance,(x,y) or MOVESPRITE instance,x,y Does: move an instance with background restoration; coordinates are physical Example: MOVESPRITE 12,(110,84) SHOWSPRITE Syntax: SHOWSPRITE instance Does: make an existing hidden instance visible Example: SHOWSPRITE 12 HIDESPRITE Syntax: HIDESPRITE instance Does: hide an instance; hidden sprites do not collide Example: HIDESPRITE 12 DELSPRITE Syntax: DELSPRITE instance Does: delete one instance without unloading its shared image Example: DELSPRITE 12 SPRITETEXT Syntax: SPRITETEXT UNDER | SPRITETEXT OVER Does: UNDER composites sprites over text; OVER redraws text foreground pixels above sprites, useful for HUDs and labels Example: SPRITETEXT OVER SPRITEX Syntax: SPRITEX(instance) Does: physical x coordinate of an existing instance Example: PRINT SPRITEX(12) SPRITEY Syntax: SPRITEY(instance) Does: physical y coordinate of an existing instance Example: PRINT SPRITEY(12) SPRITECOLLIDE Syntax: SPRITECOLLIDE(instance1,instance2) Does: -1 for at least one overlapping pair of opaque source pixels, else 0 Example: IF SPRITECOLLIDE(10,100) THEN PRINT "HIT" SAVEBMP Syntax: SAVEBMP file$ [,(x1,y1)-(x2,y2)] Does: save the active graphics VIEW, full screen, or an explicit framebuffer rectangle as an uncompressed 24-bit BMP Example: SAVEBMP "SCREEN.BMP" Example: SAVEBMP "PART.BMP",(100,80)-(399,279) PAINT Syntax: PAINT [STEP](x,y)[,paint|r,g,b[,border]] Does: flood fill; paint accepts palette/packed RGB or an RGB triple; border is palette/packed RGB Example: PAINT (100,100),32,64,128,&HFFFFFF POINT Syntax: POINT(x,y) Does: exact CGA colors return palette 0-15; otherwise returns packed 24-bit 0xRRGGBB; -1 off screen Example: PRINT HEX$(POINT(100,100)) PRESET Syntax: PRESET [STEP](x,y)[,color|r,g,b] Does: set pixel; explicit color accepts palette, packed 0xRRGGBB or RGB triple; default is background Example: PRESET (10,10),255,0,0 PSET Syntax: PSET [STEP](x,y)[,color|r,g,b] Does: set pixel; color accepts palette, packed 0xRRGGBB or RGB triple Example: PSET (10,10),255,136,0 SCREEN Syntax: SCREEN width,height; SCREEN(row,col[,attr]) reads text Example: SCREEN 1024,768 SCRNADR Syntax: SCRNADR Does: framebuffer address Example: PRINT HEX$(SCRNADR) VIEW Syntax: VIEW [SCREEN] (x1,y1)-(x2,y2)[,fill[,border]]; VIEW PRINT top TO bottom Does: graphics VIEW clips drawing; fill/border accept palette or packed 0xRRGGBB. SCREEN is GW coordinate semantics, not a display page. Example: VIEW SCREEN (0,0)-(639,479),&H101820,&HFFFFFF WINDOW Syntax: WINDOW [SCREEN] (x1,y1)-(x2,y2) Does: logical coordinates. SCREEN makes Y increase downward; it is not a display page. Example: WINDOW SCREEN (0,0)-(100,100) MEMORY / SYSTEM --------------- SYSTEM Syntax: SYSTEM Does: leave Thoreau BASIC; Windows closes the application; UEFI returns to the firmware/caller Example: SYSTEM KEYB Syntax: KEYB [xx] Does: UEFI only: show or switch the current keyboard layout; THOREAU.CFG beside the EFI accepts KEYB xx at startup; default is US Layouts: BE BR DK GR SU FR UK IT YU CF LA NL NO PL PO SV SG SF SP SL CZ HU US Example: KEYB GR THOREAU Syntax: THOREAU Does: enter DebuggerMode; STATE, STACK, FLOW, BREAKS, TIMERS and INTERNALS inspect the live interpreter; X restores the prior display/settings; THOREAU LANDMARKS, MEMMAP or INFO provides direct views Example: THOREAU THOREAUADR Syntax: THOREAUADR(name$) Does: 64-bit address of a named machine landmark Example: PRINT HEX$(THOREAUADR("FRAMEBUFFER")) DATE$ Syntax: DATE$ Does: current date Example: PRINT DATE$ FREEBOT Syntax: FREEBOT Does: bottom of free data memory Example: PRINT FREEBOT FREETOP Syntax: FREETOP Does: top of free data memory Example: PRINT FREETOP FRE Syntax: FRE(x) Does: free BASIC data bytes, including reusable blocks returned by ERASE/bitmap replacement Example: PRINT FRE(0) HIMEM Syntax: HIMEM Does: high memory address Example: PRINT HIMEM LOMEM Syntax: LOMEM Does: low memory address Example: PRINT LOMEM PEEK Syntax: PEEK(address) Does: read byte at 64-bit address Example: PRINT PEEK(HIMEM-1) POKE Syntax: POKE address,byte Example: POKE LOMEM,255 PEEK16 Syntax: PEEK16(address) Does: read unsigned 16-bit little-endian value Example: PRINT PEEK16(LOMEM) PEEK32 Syntax: PEEK32(address) Does: read unsigned 32-bit little-endian value Example: PRINT PEEK32(LOMEM) PEEK64 Syntax: PEEK64(address) Does: read raw 64-bit little-endian value as && Example: PRINT PEEK64(LOMEM) POKE16 Syntax: POKE16 address,value Does: write 16-bit little-endian value Example: POKE16 LOMEM,4660 POKE32 Syntax: POKE32 address,value Does: write 32-bit little-endian value Example: POKE32 LOMEM,&H12345678 POKE64 Syntax: POKE64 address,value Does: write all 64 bits of an && value Example: POKE64 LOMEM,123456789&& TIME$ Syntax: TIME$ Does: current time Example: PRINT TIME$ TIMER Syntax: TIMER Does: seconds since boot; TIMER(n) returns interval ms; TIMER(n)=ms sets; TIMER(n) ON/OFF controls timer n Example: TIMER(0)=1000 : ON TIMER(0) GOSUB 9000 : TIMER(0) ON WAITREL Syntax: WAITREL milliseconds Does: relative frame pacing; waits only for the remaining time since the previous WAITREL returned; late frames return immediately and re-anchor instead of catching up Example: WAITREL 16 COMMANDLINEARG$ Syntax: COMMANDLINEARG$(n) Does: 1-based command-line argument after the autostart program; empty string if absent Platform: Windows only Example: PRINT COMMANDLINEARG$(1) STARTUP.BAS Syntax: STARTUP.BAS Does: UEFI startup program automatically loaded and run when no explicit autostart program is supplied Platform: UEFI interpreter startup feature Example: Create STARTUP.BAS containing: LOAD "MENU" : RUN OPERATORS / SYNTAX WORDS ------------------------ AND Syntax: AND Does: bitwise/logical conjunction Example: IF A AND B THEN PRINT "both" BASE Syntax: BASE Does: used by OPTION BASE Example: OPTION BASE 1 BREAK Syntax: BREAK [LIST] lists breakpoints; BREAK line[,line...] sets; BREAK DELETE line removes; BREAK CLEAR clears. ON BREAK GOTO remains supported Example: BREAK 1000,2000 ELSE Syntax: ELSE Does: alternate IF branch Example: IF A=1 THEN PRINT "one" ELSE PRINT "other" EQV Syntax: EQV Does: logical equivalence Example: PRINT A EQV B IMP Syntax: IMP Does: logical implication Example: PRINT A IMP B LET Syntax: LET variable=expression Example: LET A=42 MOD Syntax: MOD Does: integer remainder Example: PRINT 17 MOD 5 NOT Syntax: NOT Does: bitwise/logical negation Example: PRINT NOT 0 OR Syntax: OR Does: bitwise/logical disjunction Example: IF A OR B THEN PRINT "yes" RANDOMIZE Syntax: RANDOMIZE [seed] Example: RANDOMIZE TIMER STEP Syntax: STEP Does: FOR increment or relative graphics point Example: FOR X=0 TO 100 STEP 5 ON TIMER Syntax: ON TIMER(n) GOSUB line Does: bind timer n (0..7) to a GOSUB handler Example: ON TIMER(0) GOSUB 9000 THEN Syntax: THEN Does: IF consequence Example: IF READY THEN GOTO 1000 TO Syntax: TO Does: FOR/VIEW PRINT range word Example: FOR I=1 TO 10 USING Syntax: USING Does: PRINT formatting word Example: PRINT USING "###.##";X XOR Syntax: XOR Does: bitwise/logical exclusive OR Example: PRINT A XOR B THOREAU MACHINE EXPLORER ======================== Enter it from BASIC with: THOREAU F12 enters the same protected DebuggerMode from the BASIC prompt, during INPUT, or while a program is running. The debugger starts on a cleared screen with normal key repeat and sprites temporarily hidden. X returns to the prompt or resumes the interrupted program after restoring the framebuffer, text grid, cursor, colors, text/graphics views, sprite presentation and KEYREPEAT settings. Numbers in the monitor are hexadecimal by default. Prefix a decimal value with D:, for example D:4096. Core monitor commands: STATE Summarize execution state, current/continuation locations, last pause or error, program/variable/file/stack counts, breakpoints, timers and tracing. STACK Show the live GOSUB and programmable-timer call stack, newest frame first. FLOW Show FOR, WHILE, ERROR/BREAK handler and single-line IF control frames. BREAKS Show the last pause, CONT target and active source-line breakpoints. TIMERS Show every configured programmable timer, handler, deadline and state. INTERNALS Show addresses and capacities of the interpreter's principal structures. L Show named machine/interpreter landmarks. Example: L M [address [length]] Hex/ASCII memory dump. M alone continues from the previous dump. Example: M LOMEM 100 M! address [length] UEFI only: force a read of a normally refused/protected region. Windows deliberately does not provide forced protected reads. Example: M! 100000 100 F start end byte Fill memory. Example: F 100000 1000FF 00 C start1 end1 start2 Compare two memory blocks. Example: C 100000 1000FF 200000 > address hex... Enter hexadecimal bytes. Example: > 100000 48 65 6C 6C 6F A address text... Enter ASCII bytes. Example: A 100000 HELLO H start end hex... Hunt for a hexadecimal byte sequence. Example: H 100000 110000 DE AD BE EF HA start end text... Hunt for ASCII text. Example: HA 100000 110000 THOREAU T start end dest Transfer/copy memory. Example: T 100000 1000FF 200000 SAVE file start end Save raw memory to a file. Example: SAVE dump.bin 100000 100FFF LOAD file address Load a raw file into memory. Example: LOAD dump.bin 200000 R address Describe the containing memory region. Example: R LOMEM W address Show nearest landmark and containing region. Example: W FRAMEBUFFER V address View BYTE/WORD/DWORD/QWORD and typed interpretations. Example: V LOMEM MAP Show the platform memory map. Example: MAP I Show compact machine information. Example: I Read-only storage / boot inspection: DISKS Enumerate disks / whole-media devices. Example: DISKS DISK n Show disk/media details. Example: DISK 0 SECTOR n lba [count] Dump raw sectors as hex/ASCII. Example: SECTOR 0 0 1 PARTITIONS n Show GPT/MBR partition information. Example: PARTITIONS 0 PARTITION n p Show one partition in detail. Example: PARTITION 0 1 VOLUMES Enumerate mounted/accessible filesystems. Example: VOLUMES DIRFS v [path] List a directory on a selected volume. Example: DIRFS 0 \EFI\BOOT CAT v file Display a file as text. Example: CAT 0 \STARTUP.NSH HEXFILE v file Display a file as hex/ASCII. Example: HEXFILE 0 \EFI\BOOT\BOOTX64.EFI BOOT Inspect UEFI BootOrder / Boot#### information where available. Example: BOOT OS Best-effort installed operating-system detection. Example: OS ? or HELP Show monitor help. X Return to BASIC. NOTES ===== - BASIC source files are ASCII text with line numbers. - CREATEEXE / CREATEEFI embed the currently loaded BASIC program, not external data files. Keep BMPs, save files and other runtime assets beside the generated application as required by the program. - CREATEEXE and CREATEEFI are direct-mode commands and require a program to be loaded. - The UEFI build and Windows build share the language core, but a few startup and platform commands differ as documented above. - UEFI keyboard layout configuration is stored in THOREAU.CFG beside the EFI. Windows keyboard input remains native to Windows and ignores this file. - SYSTEM is portable BASIC source: it exits the Windows application or returns the UEFI application to its firmware/caller. - Thoreau BASIC is free to use. Support development: paypal.me/gatesofintegrity Website: https://thoreaubasic.com