Debugging
Once you press F5, BitMagic behaves like any other VSCode debugger: stepping, breakpoints, hovers, disassembly, memory and jump to cursor, all covered below. Its own views, like the memory and layer viewers, are on The Debugger.
Launch configuration
A session is configured the same way as any VSCode debugger: a type: bmasm entry in the workspace’s .vscode/launch.json. See The launch config for its properties and how to add one. debugArgs takes the same flags as the standalone emulator, for example ["--warp"].
Build errors
If a build fails, the compiler’s errors appear as problems in the editor (a red marker on the offending line and an entry in the Problems panel), with the full log in the BitMagic output channel.
Stepping
Continue, step over, step into and step out all work against your .bmasm source lines, including code generated by the template engine. Where a line generated multiple instructions, stepping walks the instructions. The exception is code built up in a string variable and output as a block: it steps into a separate generated file instead of the original lines, see Multiline Template Code.
Breakpoints
- Source breakpoints: click the gutter next to a line.
- Conditional, hit-count and logpoints: see Watches and Breakpoints.
- Function breakpoints: not a named procedure, but a call typed into VSCode’s function breakpoint box.
vram(0x1b000)breaks on any read or write to that VRAM address; add a second address for a range, and"R","W"or"RW"to limit the direction, for examplevram(0x1b000, 0x1b200, "W").vsync()breaks on the next frame, andvsync(100)on a specific frame number. - Instruction breakpoints: set in the disassembly view.
- Exception breakpoints: three filters in the Breakpoints panel. Code Exception fires when an
.exceptiondirective is hit (on by default), File IO Exception when aLOADcall returns an error code (on by default), and BRK Hit when aBRKinstruction executes (off by default). - Startup breakpoints: the
breakpointsarray in the project file is a list of addresses to break on as soon as the machine starts.
Hovering over code
Hover over a name or an operand in a .bmasm file to see what it is and what it works out to. This works while you’re editing as well as while debugging; while a session is paused, the hover shows the machine as it is now.
While you’re editing, the hover comes from the last build that worked, which BitMagic makes in the background as you type:
- A name shows its full path, its type (constant, label, procedure,
byte,ushortand so on), whether it’s private, and its value. Names are looked up from the line you’re on, soloopinside a procedure finds that procedure’sloop. Private names in other scopes still show, as in the debugger. - An operand shows the value the build used and the addressing mode, then each name in it with its value, and the expression with the values put in.
- A directive such as
.constor.byteshows what its expression works out to, the same way. - Template code (
@(...)) shows the line it compiled to, and that line’s value. - A KERNAL routine also shows its documentation.
.const COUNT $10
adc #COUNT+1 ; hover: `#COUNT+1` = `$11` (17), immediate
; `COUNT` App:Main:COUNT, constant, `$10` (16)
; `$10+1`
Until a broken edit builds again, the hover shows the previous build, so a name you’ve only just added won’t have one yet.
While a session is paused, the hover is the value now, and expanding it shows how it was worked out:
- A variable shows its current value, read as its type.
- An indexed or indirect operand shows the value it loads now. Expanding it shows the register, the pointer for
(ptr),yand(ptr,x), and the address it ends up at. - An address from
$a000up is read from the current RAM or ROM bank, and says which. - IO registers (
$9f00to$9fff) aren’t read, as reading some of them changes the machine (VERA_DATA0moves VERA’s address on). The hover shows the address and says so.
lda (ptr),y ; paused, Y = 3: $99 (153)
; pointer $4000 at $22
; address $4003
The debugger’s hover uses the build being debugged, so it stays right while you edit during a session.
Disassembly
Open the disassembly view to step through raw instructions, including ROM code. Symbols from the symbols files and jump tables are applied, so KERNAL calls show by name.
Memory
The Variables pane exposes CPU.Ram, VERA.VRam, the RAM and ROM banks, and the SD card as memory blocks. VSCode’s hex editor can open any of them, and memory is writable while paused. The same memory can be read as typed values in an expression, for example CPU.Ram[0x0000].Short; see Watches and Breakpoints.
Jump to cursor
“Run to cursor” and setting the next statement are supported; the CPU’s PC is moved to the chosen line.
Not available
VSCode’s native data breakpoints (right-click a variable and choose Break on Value Change) aren’t supported; a vram() function breakpoint covers the VRAM case. Editing a value directly in the Variables pane isn’t supported either; use the hex editor instead.
Running in the official emulator
The command Run Project In The Official Emulator builds the project and runs it in the official X16 emulator instead of BitMagic’s. This is useful for checking behaviour against the reference implementation. It needs the official emulator, which the extension can download for you (see Settings).