Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions apps/debug80-vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
[Book 1 — Getting started](https://debug80.com/debug80-book/book1/), which goes from
installing the extension to stepping through a program on real hardware.

Debug80 turns VS Code into a practical development environment for Z80 assembly
and Glimmer programs. It builds your project, runs it inside an integrated Z80 runtime,
Debug80 turns VS Code into a practical development environment for Z80 assembly,
Glimmer, and Nucleus programs. It builds your project, runs it inside an integrated Z80 runtime,
maps machine addresses back to source with native D8 debug maps, and exposes the
state you need while debugging: breakpoints, stepping, registers, flags, memory,
terminal I/O, and hardware-specific panels.
Expand Down Expand Up @@ -71,6 +71,19 @@ are available at [debug80.com](https://debug80.com/).
- **Glimmer language support**: `.glim` projects compile through Glimmer and AZM,
retain source-level breakpoints and diagnostics, and embed full Z80/AZM syntax
highlighting inside `begin`/`end` bodies.
- **Nucleus language support**: `.nu` files have language-aware editing, target
discovery, positioned compiler diagnostics, and builds through the standalone
`nucleus` command. The build retains canonical `.nobj` and native `.d8.json`
sidecars beside its launchable `.hex` artifact. Debug80 imports that D8 map
through its ordinary validator for source breakpoints and PC-to-source lookup.
Nucleus sidecars retain byte columns, while the initial debugger experience is
line-oriented.
A project-local `nucleus-target.json` must provide the validated memory layout
and all external service destinations; Debug80 never substitutes the
compiler's synthetic proof addresses.
The initial backend treats the selected `.nu` file as a one-part manifest.
Ordered multi-file Nucleus projects require the planned project-manifest
integration.

## Quick Start

Expand Down Expand Up @@ -103,13 +116,14 @@ Target discovery uses a small set of entry-point conventions to suggest targets:
- files ending in `.main.z80`
- files named `main.asm`
- files named `main.z80`
- files named `main.nu`
- `.glim` files containing a top-level `program` declaration

Glimmer `part` files are not offered as standalone targets because they do not
declare a complete program.

These names are conventions, not requirements. Use the `+` control beside the
target selector to add any `.asm`, `.z80`, or complete Glimmer program in the
target selector to add any `.asm`, `.z80`, `.nu`, or complete Glimmer program in the
project. Sources may live at the project root, under `src/`, or in other
subdirectories. Removing a target with the `-` control changes `debug80.json`;
it does not delete the source file or its existing build artifacts.
Expand Down Expand Up @@ -143,7 +157,7 @@ Debug80 contributes commands for the normal project workflow:
current debug session.
- **Debug80: Select Workspace Folder** and **Debug80: Select Active Target**:
switch the active project context.
- **Debug80: Set Program File**: choose the source entry point from an editor or
- **Debug80: Set Program File**: select the source entry point from an editor or
Explorer context menu.
- **Debug80: Open Project Configuration Panel**: open the active project config.
- **Debug80: Open Auxiliary Source**: open bundled or project-provided platform
Expand Down Expand Up @@ -175,6 +189,12 @@ npm test

Debug80 packages its assembler dependency inside the VSIX. Published users should
not need `npm link`, sibling checkouts, or globally installed assembler binaries.
The initial Nucleus integration is deliberately separate: install the standalone
Nucleus package so its `nucleus` command is on `PATH`, or set `NUCLEUS_COMPILER`
to the command path before starting VS Code. Bundling a released compiler image
is the next integration step.
Set `NUCLEUS_TARGET_PROFILE` to override the default project-local
`nucleus-target.json` path.

## Documentation

Expand Down
40 changes: 40 additions & 0 deletions apps/debug80-vscode/docs/nucleus-source-maps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Nucleus Source Maps in Debug80

For each build, Debug80 requests three related artifacts from the standalone
Nucleus compiler: canonical NOBJ, launchable Intel HEX, and a native D8
source-map sidecar. The
backend publishes the three files as one generation. A missing or empty file,
a compiler diagnostic, or a publication error leaves the previous generation
unchanged.

The sidecar is written beside the HEX file with the same base name:

```text
build/main.nobj
build/main.hex
build/main.d8.json
```

The normal Debug80 D8 validator and source manager load the map. Source
breakpoints and PC-to-source lookup therefore use the same path as AZM and
Glimmer targets; the Nucleus backend does not parse compiler listings or infer
source from compiler addresses.

Nucleus records 1-based byte columns in D8. Debug80's initial Nucleus behavior
binds and steps at line granularity because the current importer does not keep
columns through every internal lookup. Column-aware stepping is a separate
change.

The standalone Node host can also compile banked targets and emit one D8 map
per physical bank. Those maps use the existing D8 memory-bank metadata and
Debug80 external address-space identity. Debug80's Nucleus application loader
currently accepts one flat Intel HEX image, so the launch backend rejects a
target profile whose `bankCount` is greater than one before invoking the
compiler. It does not flatten a banked object or invent a bank-selection
policy. Use the standalone CLI when banked NOBJ and per-bank D8 artifacts are
required.

The event protocol used to produce the sidecar is documented in the Nucleus
repository. It is active only while the host-instrumented Z80 compiler runs.
Once compilation finishes, ports `$D8..$DF` return to ordinary emulated-device
handling for target programs.
27 changes: 27 additions & 0 deletions apps/debug80-vscode/language-configuration/nucleus.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"comments": {
"lineComment": "#"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use Nucleus's actual line-comment delimiter

When a user invokes Toggle Line Comment, this configuration inserts #, which the compiler rejects: packages/nucleus/docs/specification.md defines // as the sole comment form and identifies hash as invalid syntax. The new TextMate grammar likewise matches #.*$, so valid // comments are not highlighted while invalid text is. Update both the language configuration and grammar to recognize //.

Useful? React with 👍 / 👎.

},
"brackets": [
["(", ")"],
["[", "]"]
],
"autoClosingPairs": [
{ "open": "(", "close": ")" },
{ "open": "[", "close": "]" },
{ "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "'", "close": "'", "notIn": ["string", "comment"] }
],
"surroundingPairs": [
["(", ")"],
["[", "]"],
["\"", "\""],
["'", "'"]
],
"folding": {
"markers": {
"start": "^\\s*(?:record|sub|if|elseif|else|while|for|handle)\\b",
"end": "^\\s*end\\b"
}
}
}
36 changes: 29 additions & 7 deletions apps/debug80-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"onLanguage:asm-collection",
"onLanguage:z80-asm",
"onLanguage:z80-macroasm",
"onLanguage:glim"
"onLanguage:glim",
"onLanguage:nucleus"
],
"main": "./out/extension/extension.js",
"contributes": {
Expand All @@ -73,7 +74,8 @@
"*.asm": "z80-asm",
"*.z80": "z80-asm",
"*.asmi": "z80-asm",
"*.glim": "glim"
"*.glim": "glim",
"*.nu": "nucleus"
},
"editor.tokenColorCustomizations": {
"textMateRules": [
Expand Down Expand Up @@ -356,6 +358,16 @@
".glim"
],
"configuration": "./language-configuration/glim.json"
},
{
"id": "nucleus",
"aliases": [
"Nucleus"
],
"extensions": [
".nu"
],
"configuration": "./language-configuration/nucleus.json"
}
],
"grammars": [
Expand All @@ -368,6 +380,11 @@
"language": "glim",
"scopeName": "source.glim",
"path": "./syntaxes/glim.tmLanguage.json"
},
{
"language": "nucleus",
"scopeName": "source.nucleus",
"path": "./syntaxes/nucleus.tmLanguage.json"
}
],
"breakpoints": [
Expand All @@ -391,6 +408,9 @@
},
{
"language": "glim"
},
{
"language": "nucleus"
}
],
"commands": [
Expand Down Expand Up @@ -541,21 +561,21 @@
"explorer/context": [
{
"command": "debug80.setEntrySource",
"when": "resourceExtname == .asm || resourceExtname == .z80 || resourceExtname == .glim",
"when": "resourceExtname == .asm || resourceExtname == .z80 || resourceExtname == .glim || resourceExtname == .nu",
"group": "navigation@9"
}
],
"editor/context": [
{
"command": "debug80.setEntrySource",
"when": "resourceExtname == .asm || resourceExtname == .z80 || resourceExtname == .glim",
"when": "resourceExtname == .asm || resourceExtname == .z80 || resourceExtname == .glim || resourceExtname == .nu",
"group": "navigation@9"
}
],
"editor/title/context": [
{
"command": "debug80.setEntrySource",
"when": "resourceExtname == .asm || resourceExtname == .z80 || resourceExtname == .glim",
"when": "resourceExtname == .asm || resourceExtname == .z80 || resourceExtname == .glim || resourceExtname == .nu",
"group": "navigation@9"
}
],
Expand All @@ -578,7 +598,8 @@
"wla-dx-asm",
"asm",
"z80",
"glim"
"glim",
"nucleus"
],
"configurationAttributes": {
"launch": {
Expand All @@ -601,7 +622,8 @@
"description": "Assembler backend to use (inferred from the source extension when omitted)",
"enum": [
"azm",
"glimmer"
"glimmer",
"nucleus"
]
},
"azm": {
Expand Down
7 changes: 7 additions & 0 deletions apps/debug80-vscode/src/debug/launch/assembler-backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { AzmLaunchOptions } from '../session/types';
import type { AssembleResult } from './assembler';
import { AzmBackend } from './azm-backend';
import { GlimmerBackend } from './glimmer-backend';
import { NucleusBackend } from './nucleus-backend';

const azmSourceExtensions = new Set(['.asm', '.inc', '.z80']);

Expand Down Expand Up @@ -48,6 +49,9 @@ function inferAssemblerBackend(asmPath: string | undefined): string | undefined
if (extension === '.glim') {
return 'glimmer';
}
if (extension === '.nu') {
return 'nucleus';
}

return undefined;
}
Expand All @@ -66,6 +70,9 @@ export function resolveAssemblerBackend(
if (id === 'glimmer') {
return new GlimmerBackend();
}
if (id === 'nucleus') {
return new NucleusBackend();
}

throw new Error(`Unknown assembler backend: "${assembler}"`);
}
Loading
Loading