# Editor ## Editor overview The editor provides powerful facilities for loading, saving, and modifying source code. Text is displayed in 40 columns to provide a much higher density interface than the VIC-20's native BASIC line editor. Navigation will be familiar to vi users. There are also a variety of commands to handle things like assembly, disassembly, etc. As with all work you do on your VIC-20, if you care about it, save often. ### Buffers Up to 8 source buffers may be stored in memory at a time, each up to 24KB in size. These are accessed via a key chord comprised of {c64-key}`Ctrl` and the number key for the corresponding buffer. You can also navigate to the _previous_ buffer with {c64-keys}`Ctrl + H` and the _next_ buffer with {c64-keys}`Ctrl + L`. ### Command shortcuts Below are the basic commands along with their associated key combinations. These commands are available regardless of insertion mode (see the _Editor Modes_ section below for more info on modes). | KEY | NAME | DESCRIPTION | |----------------------------|-----------------|-------------------------------------------------------------------------------------------------| | {c64-keys}`C= + A` | `ASSEMBLE `| assembles the active program | | {c64-keys}`C= + D` | `DEBUG `| begins debugging at the origin of the assembled program | | {c64-keys}`C= + B` | `SET BREAKPOINT`| sets a breakpoint at the current line | | {c64-keys}`C= + C` | `REFRESH `| refreshes the screen by redrawing the source buffer | | {c64-key}`Minus` | `FILE VIEWER `| list directory, shows the files on the current disk | | {c64-keys}`C= + N` | `NEW BUFFER `| creates a new source buffer and sets it as the active buffer | | {c64-keys}`C= + Q` | `CLOSE BUFFER `| closes the current buffer and opens the next one that is open (if a window has focus, closes that window instead) | | {c64-keys}`C= + Y` | `SHOW SYMBOLS `| lists the symbol table for the assembled program | | {c64-keys}`C= + M` | `SHOW MACROS `| lists the macros that are defined and allows viewing their definitions | | {c64-keys}`C= + E` | `NEXT ERROR `| navigates to the next error in the active buffer, wrapping at the end | | {c64-keys}`C= + X` | `DISMISS ERROR `| dismisses errors on the current source line | | {c64-keys}`C= + T` | `CHECK LINE `| checks and formats the current line | | {c64-keys}`C= + F` | `AUTOFORMAT `| toggles automatic formatting and syntax checking | | {c64-keys}`Shift + RETURN` | `FORCE NEWLINE `| inserts a newline and advances even if the completed line has an error | | {c64-key}`F3` | `SHOW BUFFERS `| displays a list of the currently open buffers | | {c64-keys}`C= + L` | `LINK `| links the object files in the project using the LINK file on disk | | {c64-key}`F8` | `MEMVIEW `| opens the memory viewer/editor | | {c64-key}`F5` | `BRKVIEW `| opens the breakpoint viewer/editor | | {c64-key}`F6` | `WATCHVIEW `| opens the watch viewer/editor | | {c64-keys}`Shift + Slash` | `HELP `| displays memory ranges and current resource usage | | {c64-keys}`C= + Plus` | `NEXT DRIVE `| Selects the next drive (limited to #15) | | {c64-keys}`C= + Minus` | `PREV DRIVE `| Selects the previous drive (limited to #8) | | {c64-key}`Colon` | `EX COMMAND `| Enters EX mode (see the EX commands section below for more on this) | ```{warning} Closing a source buffer with {c64-keys}`C= + Q` immediately discards any unsaved changes in that buffer. The editor does not ask for confirmation. ``` #### Help Press {c64-keys}`Shift + Slash` (`?`) to display the assembled program and debugger memory ranges, along with the current usage and limits (e.g. current and maximum number of labels used). Press any key to return to the editor. ```{figure} screenshots/help.png :alt: The help overlay showing memory ranges and assembler resource usage :align: center :width: 75% :class: screenshot The help overlay summarizes memory allocation and assembler resource usage ``` #### Drive selection The current drive selection is displayed with a `#` prefix in the status bar. {c64-keys}`C= + Plus` selects the _next_ available drive and {c64-keys}`C= + Minus` selects the _previous_ available drive. The valid device range is 8-15. #### Directory viewer Pressing {c64-key}`Minus` in command mode activates the directory viewer. This tool presents a paginated view of all files on the disk. Pressing {c64-key}`RETURN` while the cursor is on the desired file will load that file into a new buffer and switch to that buffer. ```{figure} screenshots/directory.png :alt: The directory viewer showing a list of source files :align: center :width: 75% :class: screenshot The directory viewer lists the files on the current disk. The highlighted row is the current selection. ``` While in the directory viewer, pressing {c64-key}`G` navigates to the last file in the directory and {c64-sequence}`GG` goes to the first one. Either {c64-key}`RUN/STOP` or {c64-keys}`C= + Q` dismisses the viewer and restores the screen you came from. #### Symbol viewer The symbol viewer, activated with {c64-keys}`C= + Y`, displays all the labels in the program along with their corresponding address. If no labels are defined, the viewer aborts and reports `NO LABELS` in the status bar. Float constants are shown in decimal/scientific notation. ```{figure} screenshots/symview.png :alt: The symbol viewer listing symbol values, names, source files, and line numbers, sorted by name :align: center :width: 75% :class: screenshot The symbol viewer shows each symbol's value and definition location. Here the symbols are sorted by name ``` | KEY | NAME | DESCRIPTION | |-----------------------|-------------|------------------------------------------------------------------| | {c64-key}`K` | `UP` | moves the selection up (the list scrolls at the top row) | | {c64-key}`J` | `DOWN` | moves the selection down (the list scrolls at the bottom row) | | {c64-key}`RETURN` | `GOTO` | goes to the line where the selected symbol is defined (needs debug information from the last assembly) | | {c64-key}`F1` | `SORT` | toggles the sort order between alphabetical and by address | | {c64-key}`RUN/STOP` | `EXIT` | dismisses the viewer and restores the screen you came from | | {c64-keys}`C= + Q` | `EXIT` | same as the RUN/STOP shortcut | The cursor keys work in place of the `DOWN` and `UP` commands. #### Macro viewer The macro viewer, activated with {c64-keys}`C= + M`, lists every macro that is currently defined and allows you to inspect the body of any of them. Macros are registered with the assembler when their definition is _assembled_ ({c64-keys}`C= + A`), so the list reflects the macros from your last assembly, not necessarily the macros that happen to be visible in the active buffer. If no macros have been defined, the viewer aborts and reports `NO MACROS` in the status bar. ```{figure} screenshots/macro-viewer.png :alt: The macro viewer listing the defined macros :align: center :width: 75% :class: screenshot The macro viewer lists the macros defined by the most recent assembly. ``` The viewer has two modes: **MACRO LIST**: the initial mode, titled `MACROS`. Each row is the name of one defined macro, in the order of their definition. The highlighted row is the current selection. **DEFINITION**: selecting a macro opens its definition. The screen is cleared and the top row shows the macro's name followed by its parameter names; the rows below it are the lines of the macro's body as defined. | KEY | MODE | DESCRIPTION | |----------------------------------------------------|------------|----------------------------------------------------------------------| | {c64-key}`K` | both | moves the selection up (macro list) or scrolls up (definition) | | {c64-key}`J` | both | moves the selection down (macro list) or scrolls down (definition) | | {c64-sequence}`GG` | both | goes to the first macro (or first line of the definition) | | {c64-key}`G` | both | goes to the last macro (or last line of the definition) | | {c64-key}`RETURN` | macro list | opens the definition of the selected macro | | {c64-key}`RUN/STOP` | definition | returns to the macro list | | {c64-key}`RUN/STOP` | macro list | exits the viewer and restores the editor screen | | {c64-keys}`C= + Q` | both | exits the viewer from either mode, without stopping at the macro list | Lists longer than the screen scroll automatically as the selection reaches the top or bottom row. Note that the viewer is read-only; it is a way to confirm _what_ the assembler actually recorded for a macro. See the [Assembler](assembler.md) document for the `.MAC` directive and the limits on macro count and size. #### Function (F key) commands | KEY | NAME | DESCRIPTION | |---------------|--------------------|----------------------------------------------------------------------------------------------| | {c64-key}`F1` | `RUN ` | saves Monster's state and transfers control to the last assembly (or enters BASIC if none) | | {c64-key}`F2` | `MEMORY CONFIG ` | selects which expansion blocks the user's program (and BASIC) run with | | {c64-key}`F3` | `BUFFERS ` | displays a list of the currently open buffers | | {c64-key}`F4` | `LOG ` | displays the active log file (if any) | | {c64-key}`F5` | `BREAKPOINTS ` | activates the breakpoint viewer | | {c64-key}`F6` | `WATCHES ` | activates the watch viewer | | {c64-key}`F7` | `MONITOR ` | opens the text-based monitor as a window (see the _Monitor_ section) | | {c64-key}`F8` | `MEMORY VIEWER ` | activates the memory viewer | ### EX commands Pressing {c64-key}`Colon` puts the editor in _EX_ mode. In this mode, a string is accepted from the user. The format of this string is a _command_ (usually one or two characters) followed by zero or more arguments. ```{example} For example, `:s HELLO.S` writes a file named `HELLO.S` to disk. ``` Uppercase filenames are recommended. Lowercase PETSCII codes may appear as graphic characters in VIC-20 directory listings, and quoted `.INC` and `.INCBIN` filenames must match the case of the filename on disk. The table below details the available commands in _EX_ mode. | COMMAND | NAME | ARGS | DESCRIPTION | |-----------|-----------------------|---------------------------------|-------------------------------------------------------------------------------------------------| | `a` | `ASSEMBLE FILE ` | Filename | assembles the given filename | | `B` | `EXPORT BINARY ` | Filename | exports the active assembly to a binary file (no .PRG header) | | `D` | `EXPORT DEBUG FILE ` | Filename | exports the loaded assembly, debug information, and symbol table as a debug (`.D`) file | | `L` | `LOAD DEBUG FILE ` | Filename | loads the given debug (`.D`) file (symbol table, debug information, and program data) | | `e` | `EDIT ` | Filename | loads the buffer with the contents of the given file | | `o` | `EXPORT OBJECT ` | Filename | exports the active assembly to an object file with the given filename | | `P` | `EXPORT .PRG ` | Filename | exports the active assembly to a .PRG file | | `r` | `RENAME ` | Name | renames the buffer to the given name | | `s` | `SAVE ` | Filename | saves the buffer to the given filename | | `S` | `SAVE ALL ` | N/A | saves all modified buffers that are open currently | | `x` | `SCRATCH ` | Filename | scratches (deletes) the given filename | #### Assemble file **Syntax:** `:a filename` **Behavior:** Assembles the contents of the given file. This is functionally the same as opening the given file and assembling it with debug information ({c64-keys}`C= + A`). Invoking the debugger will invoke it for the last assembled file (not the current source buffer) in this scenario. The debugger cares about the active debug information _not_ the active file. ```{example} `:a HELLO.S` ``` #### Export binary **Syntax:** `:B filename` **Behavior:** Exports the active assembly ({c64-keys}`C= + A`) to the given file as binary. This means no load address is prepended to the file. This can be useful if you are using Monster to create level data or other code loaded by your main program. It can also be used to export things like data tables for use with .INCBIN ```{example} `:B DATA.B` ``` #### Export debug file **Syntax:** `:D filename` **Behavior:** Exports the loaded assembly, debug information, and symbol table as a debug (`.D`) file. You may think of these as debuggable versions of your release binaries: a `.D` file can be loaded (`:L`) and debugged without having to reassemble/relink it. This command should be run after a successful assembly or link. ```{example} `:D HELLO.D` ``` #### Load debug file **Syntax:** `:L filename` **Behavior:** Loads the given debug (`.D`) file. The symbol table, debug information, and program data are all loaded into virtual memory so you can begin debugging, view symbols, etc. as if you had just assembled the program. ```{example} `:L HELLO.D` ``` #### Edit **Syntax:** `:e filename` **Behavior:** Loads the given filename to a new buffer and activates it. ```{example} `:e HELLO.S` ``` #### Export object **Syntax:** `:o filename` **Behavior:** Exports the active assembly to an object file with the given name. Assemble the source with {c64-keys}`C= + A` before running this command. The filename must have a `.o` (or `.O`) extension if you want the linker to pick it up at link time. See the [Linker](linker.md) document for more on object files and linking. ```{example} `:o HELLO.O` ``` #### Export .PRG **Syntax:** `:P filename` **Behavior:** Exports the active assembly ({c64-keys}`C= + A`) to the given file as a .PRG file. This means a load address is prepended to the file prior to export. This produces a standalone executable you can use when you are done working on your program. ```{example} `:P GAME.PRG` ``` #### Rename **Syntax:** `:r buffername` **Behavior:** Renames the active buffer to the given name. ```{example} `:r TEST2.S` ``` #### Save **Syntax:** `:s [filename]` or `:s@ [filename]` **Behavior:** Saves the active buffer to a file with the given name. If no name is given, the active buffer's name is used. ```{warning} The `@` suffix deletes the existing file before writing the replacement. If the subsequent save fails, the original file has already been deleted. ``` ```{example} `:s NEW.S`, `:s@ OLD.S`, and `:S@` (save all). ``` #### Save all **Syntax:** `:S` or `:S@` **Behavior:** Saves all buffers that have been modified since they were last saved. As with the _Save_ command, adding `@` to the command (`S@`) will overwrite existing files if they exist. ```{warning} `:S@` applies the delete-then-save operation to every modified buffer. A save failure can leave an original file deleted without a completed replacement. ``` ```{example} `:S@` ``` #### Scratch **Syntax:** `:x filename` **Behavior:** Deletes the file of the given name. ```{warning} `:x` scratches the file from disk immediately and does not ask for confirmation. Monster provides no undo for this operation. ``` ```{example} `:x TEST.S` ``` --- ## Editor modes The editor is a _modal_ editor, that is, it behaves differently depending on which _mode_ it is in. The modes are all accessed from the default one (called _command_ mode) and each returns to _command_ mode when {c64-key}`RUN/STOP` is pressed. Below is a list of the modes along with their function and details on how to enter them. ### Command mode This is the default mode. The primary function of command mode is to navigate around the source code and to enter other modes. Navigation behaves similarly to `vi` and many basic `vi` commands are supported. The following keys are handled in command mode. | KEY | NAME | DESCRIPTION | |--------------------------------------------|--------------|-----------------------------------------------------------------------------------------| | {c64-key}`HOME` | `HOME `| moves the cursor to column 0 | | {c64-key}`Colon` + _n_ | `GOTO LINE `| at the EX prompt, enter a line number to move the cursor to it | | {c64-key}`Ctrl` + {c64-key}`1`–{c64-key}`8`| `GOTO BUFFER`| opens the buffer corresponding to the number key that is pressed | | {c64-keys}`Ctrl + H` | `PREV BUFFER`| opens the buffer before the active one (if there is one) | | {c64-keys}`Ctrl + L` | `NEXT BUFFER`| opens the buffer after the active one (if there is one) | | {c64-keys}`C= + I` | `JUMP UP `| jumps forward to the next source position that was "jumped" to | | {c64-keys}`C= + O` | `JUMP BACK `| jumps back to the last source position that was "jumped" to | | {c64-key}`Dollar` | `END OF LINE`| moves the cursor to the end of the current line | | {c64-sequence}`;;` | `BANNER `| inserts a banner (full line of semicolons) below the cursor | | {c64-sequence}`GG` | `TOP OF FILE`| moves the cursor to the first character in the file | | {c64-sequence}`GD` | `GOTO DEF `| if the cursor is on a label reference, navigates to that label | | {c64-keys}`Shift + G` | `END OF FILE`| moves the cursor to the last line in the file | | {c64-key}`H` | `LEFT `| moves the cursor left | | {c64-key}`J` | `DOWN `| moves the cursor down | | {c64-key}`K` | `UP `| moves the cursor up | | {c64-key}`L` | `RIGHT `| moves the cursor right | | {c64-keys}`Shift + H` | `HOME `| moves the cursor to the top left of the screen | | {c64-keys}`Shift + L` | `LAST `| moves the cursor to the bottom left of the screen | | {c64-sequence}`D0` | `DELETE TO `| deletes everything on the line before the cursor | | {c64-keys}`Shift + D` / {c64-sequence}`D$` | `DELETE REST`| deletes the contents of the line after the cursor's position | | {c64-sequence}`DD` | `DELETE LINE`| deletes the next line | | {c64-sequence}`DW` | `DELETE WORD`| deletes the next word | | {c64-keys}`Shift + J` | `JOIN LINES `| moves the contents of the next line to the end of the current one | | {c64-key}`0` | `COLUMN 0 `| moves the cursor to the first column of the current line | | {c64-key}`A` | `APPEND CHAR`| enters insert mode and moves to the next character | | {c64-keys}`Shift + A` | `APPEND LINE`| enters insert mode and moves to the last character in the current line | | {c64-keys}`Shift + C` | `CHANGE LINE`| deletes from the cursor to the end of the line and enters insert | | {c64-key}`O` | `OPEN LINE `| opens a new line below the cursor and moves to it | | {c64-keys}`Shift + O` | `OPEN LINE ^`| opens a new line above the cursor and moves to it | | {c64-key}`S` | `SUB CHAR `| deletes the character under the cursor and enters insert mode | | {c64-keys}`Shift + S` | `SUB LINE `| deletes the line under the cursor and enters insert mode | | {c64-key}`P` | `PASTE BELOW`| pastes the contents of the copy-buffer to the line below the cursor | | {c64-keys}`Shift + P` | `PASTE ABOVE`| pastes the contents of the copy-buffer to the line above the cursor | | {c64-keys}`Shift + I` | `INSERT LINE`| enters insert mode and moves to the first character in the current line | | {c64-key}`Left-bracket` | `PREV BLOCK `| moves to the previous empty line or start of file if there isn't one | | {c64-key}`Right-bracket` | `NEXT BLOCK `| moves to the next empty line or end of file if there isn't one | | {c64-keys}`Ctrl + :` | `PREV BANNER`| moves to the previous comment banner - `;;;;;;;...` | | {c64-keys}`Ctrl + ;` | `NEXT BANNER`| moves to the next comment banner - `;;;;;;;...` | ### Insert mode Entering insert mode allows the user to enter text at the cursor location. Keystrokes are interpreted as their corresponding ASCII character value in this mode, so there are no special commands accessed via them. There are various keys that enter insert mode from command mode: {c64-key}`I`, {c64-key}`A`, {c64-keys}`Shift + A`, etc. Several ASCII punctuation characters do not appear on a VIC-20 keyboard. Monster maps them from the following VIC keys; the same combinations apply to VICE's virtual keyboard: | CHARACTER | VIC-20 KEY | |-----------------------|-------------------------| | backslash (`\`) | `£` | | caret (`^`) | up arrow | | underscore (`_`) | `SHIFT` + `-` | | grave accent (`` ` ``)| left arrow | | left brace (`{`) | `SHIFT` + `@` | | vertical bar (`\|`) | `SHIFT` + `£` | | right brace (`}`) | `SHIFT` + `*` | ### Visual mode In _visual_ mode (accessed via {c64-key}`V` in _command_ mode), the user can select a block of text which may then be deleted or copied. Below is the table of supported commands while in visual mode. Pressing {c64-key}`RUN/STOP` will return the user to _command_ mode. | KEY | NAME | DESCRIPTION | |--------------|-----------|------------------------------------------------------------------------| | {c64-key}`D` | `DELETE` | deletes the selected text _and_ copies it to the copy buffer | | {c64-key}`Y` | `YANK ` | copies the selected text (in visual mode) to the copy buffer | ### Visual line mode _Visual line_ mode, which is entered by pressing {c64-keys}`Shift + V` from _command_ mode, is similar to _visual_ mode, but selections include only entire lines. Upon entering _visual line_ mode, the current row is selected. Navigating to rows above or below will select additional lines. The delete and yank keys behave the same as they do in _visual_ mode. --- ### Copy buffer When text is deleted (delete line, delete word) or _yanked_, it is stored to a buffer where it may be recalled by the paste commands ({c64-key}`P`, paste below and {c64-keys}`Shift + P` paste above). When the paste command is executed, the buffer is cleared. The copy buffer is stored in a dedicated memory bank, so a selection may be as big as a source buffer (24KB). Because the editor is limited to 40 columns in width, the first and last lines are handled specially. If the first or last line will not fit, the paste is aborted. This is similar to how the BACKSPACE and JOIN LINE commands behave, which will error with a beep if the resulting line would not fit on screen. ### Line endings Files are stored with $0d line endings, but files saved with UNIX-style line endings ($0a) will be automatically converted when the file is loaded. ### Jump lists When the user "jumps" to a different position in the source (`gg`, `G`, `goto line`, `find`, `[`, and `]`) the editor saves the old position. To recall the positions that were "jumped" from are two commands: _jump-forward_ ({c64-keys}`C= + I`) and _jump-backward_ ({c64-keys}`C= + O`). ### Syntax checking With automatic formatting enabled, the editor checks a line when you press {c64-key}`RETURN` or navigate to another line or buffer. Navigating from a line checks the syntax of the line being left without formatting it (or preventing the move like RETURN does). In insert mode, {c64-key}`RETURN` checks and formats the completed line. If it has an error, it is displayed immediately and the newline is aborted to allow you to correct the error. Use {c64-keys}`Shift + RETURN` to force a newline to be inserted despite it containing an error. The invalid line is left unformatted. Press {c64-keys}`C= + T` to check the whole current line without inserting a newline, in either insert or command mode. If valid, the line is formatted using the current indentation setting, with the cursor following the same text. If invalid, its error is displayed and the line is left unformatted. {c64-keys}`C= + F` toggles both automatic formatting and syntax checking. When disabled, navigation and finishing a line do not check or format the source. {c64-keys}`C= + T` checks and formats the current line without affecting this setting. These checks do not assemble the program or assign addresses to labels. To allow incomplete programs to be edited, they accept undefined labels and an unset origin. Full assembly may therefore report errors that the editing checks did not catch. ### Error log The `ERRORS` window contains errors from live syntax checks during editing or the result of the assembly if one was just executed. In command mode, {c64-keys}`C= + E` goes to the next error in the active buffer, wrapping to its first error after the last one. To select an error in the window, enter the error log with {c64-keys}`C= + W` as you would any _window_, move the selection with the cursor keys, and press {c64-key}`RETURN` to jump to its source line. {c64-key}`RUN/STOP` returns focus to the editor while leaving the window open. Correcting a line removes its corresponding error the next time that line is checked (on newline or navigation to another line). A successful syntax check does not clear an error from full assembly, since some assembly errors cannot be detected by a syntax-only validation test. #### Dismissing errors Press {c64-keys}`C= + X` in the editor to dismiss all errors on the current line. This works in both insert and command mode. In the error window, press **DEL** (the INST/DEL key without SHIFT) or {c64-keys}`C= + X` to dismiss the selected error. Removing the last error closes the window. Dismissed errors remain hidden when you edit or navigate away from their lines. To check a dismissed line again without adding a newline, press {c64-keys}`C= + T` or complete the line again by pressing {c64-key}`RETURN` at the end of it. The error will reappear if the line still has a problem. #### Limits The error window holds up to **16 errors across all buffers**. Once full, additional errors are dropped. Full assembly has a separate limit of **8 recorded errors**. A further error stops assembly (fatal errors may stop it sooner). The editor can remember **64 dismissed lines**. If this table is full, another dismissal beeps and leaves the error visible, preserving the earlier dismissals. ### UDG editor Press {c64-keys}`C= + U` to enter the UDG (user-defined graphics) editor. This editor allows you to visually create simple graphics for your programs. Navigation is done with the same vi-like commands used in the main editor and graphics are created using the following commands: | COMMAND NAME | KEY | BEHAVIOR |-----------------|-------------------------|------------------------------------------------------------------------------------------------------| | ` PLOT COLOR 1` | {c64-key}`1` | Sets the selected position to the background color | | ` PLOT COLOR 2` | {c64-key}`2` | Sets the selected position to the character color (hires mode) or the border color (multicolor mode) | | ` PLOT COLOR 3` | {c64-key}`3` | Multicolor mode only. Sets the selected position to the character color | | ` PLOT COLOR 4` | {c64-key}`4` | Multicolor mode only. Sets the selected position to the auxiliary color | | ` CLEAR ` | {c64-keys}`Shift + CLR` | Sets all pixels in the UDG to the background color | | ` DONE ` | {c64-key}`RETURN` | Exits the editor and enters (or updates) the .db commands to create the graphic in the editor | | ` QUIT ` | {c64-key}`RUN/STOP` | Exits the editor without creating/updating the graphic contained in the editor | | `TOGGLE MODE ` | {c64-key}`M` | If in hires mode, switches to multicolor mode or vice versa | Entering the editor while on a line with an 8-byte ".db" definition (e.g. `.db $ff,$00,$ff,$00,$ff,$00,$ff,$00`) will pre-populate the UDG editor with the character defined by these directives. The blinking selection cursor begins on the top-left pixel. When it is visible, that corner may look misaligned; the ordinary outline appears when the cursor blinks off. The cursor does not alter the character data unless you plot a color. ```{figure} screenshots/editor-udg-1.png :alt: The UDG editor :align: center :width: 75% :class: screenshot The UDG editor activated on a row of .db directives ``` ```{toctree} :maxdepth: 2 interface ```