BBC 6502 Web Assembler (ChatGPT assisted)

modified
Ln 1, Col 1Ctrl+Enter: assembleCtrl+S: save sourceCtrl+Shift+S: Save As…
#StartEndBytes
AddressSymbol
Drop source/project files here
Assembler syntax

This is a generic two-pass NMOS 6502 assembler. Symbols are case-insensitive. A source can be a single file or a project using INCLUDE.

ENTRY start
ORG &1900
OSWRCH = &FFEE

start:
    LDX #0
.loop:
    LDA message,X
    BEQ done
    JSR OSWRCH
    INX
    BNE .loop
.done:
    RTS

message:
    EQUS "HELLO"
    EQUB 13,10,0

Numbers: &FF or $FF hexadecimal, %1010 binary, decimal integers. Expressions support + - * / % & | ^ << >>, parentheses, unary < low byte and > high byte. In prefix position * is the current assembly address.

Directives: ENTRY (mandatory on physical line 1), ORG, EQUB/.BYTE/DB, EQUW/.WORD/DW, EQUD/.DWORD/DD, EQUS/.TEXT, SKIP/DS/RES, FILL, ALIGN, ASSERT, and INCLUDE "file.asm".

Labels: name: and BBC/BeebAsm-style .name are accepted. Constants may use name = expression or name EQU expression.

Address-size control: a literal written with four or more hex digits, e.g. LDA &00F0, forces absolute addressing where available. You can also write LDA.ABS symbol or LDA.ZP symbol. This matters when reproducing exact binaries.

Undocumented NMOS opcodes: common forms are supported, including SLO RLA SRE RRA SAX LAX DCP ISC ANC ALR ARR AXS LAS AHX SHY SHX TAS. The assembler's NOP abs,X form uses opcode &DC; exact alternative illegal encodings can always be emitted with EQUB. Disable undocumented opcodes using the toolbar checkbox.

Mandatory source header: physical line 1 must be ENTRY <label-or-fixed-address> and physical line 2 must be ORG <fixed-address>. No blank or comment lines may precede them. ENTRY may forward-reference a label defined later in the source. The first ORG defines where compilation begins; later ORG directives change the assembly address and non-contiguous emitted ranges become separate segments.

Loader BASIC: source comments of the form ; @basic ENVELOPE1,1,0,0,0,1,1,1,100,-10,0,-10,100,0 are ignored by 6502 assembly but are copied, in source/INCLUDE order, into the tokenised BBC BASIC loader made by Save boot disk…. One @basic line becomes one BASIC line and runs after the loader selects MODE 7 but before machine-code installation. Star commands such as ; @basic *FX200,3 are also accepted. These directives never alter the machine-code binary.

Multi-ORG boot loading: when a source emits more than one segment, Save boot disk… automatically packs only the emitted bytes, stages that packed payload safely, then installs each segment at its own ORG address before entering the source-defined ENTRY. Gaps are not written to BBC memory and are not stored as zero padding in the DFS program payload.

jsbeeb key remapping: source comments such as ; @jsbeeb-key Z=CAPSLOCK and ; @jsbeeb-key X=CTRL are ignored by 6502 assembly but are passed to jsbeeb when Run in jsbeeb is used. Each line maps one host key to one BBC key and becomes a jsbeeb URL parameter such as KEY.Z=CAPSLOCK. These directives never alter the machine-code binary or downloaded SSD.

Multiple ORGs: emitted ranges are shown as separate segments. “Save binary” creates one flat file from the lowest to highest emitted address and fills gaps with the selected fill byte. Each individual segment can also be downloaded from the Segments tab.

Create bootable BBC DFS disk

The generated SSD contains !BOOT and one tokenised BBC BASIC program. For a single segment, the compiled bytes are installed at their assembled address. For a multi-ORG source, only emitted segment bytes are appended; the loader stages that packed payload at a safe temporary address, installs each segment at its declared address, then jumps to the source-defined ENTRY.

Run in jsbeeb creates the same SSD in memory, sends it inline to https://bbc.xania.org/ and requests an automatic Shift-Break, so the freshly assembled program boots immediately in the emulator. Any source-level ; @jsbeeb-key HOST=BBC mappings are added to the same jsbeeb URL automatically.

DFS filenames are limited to seven characters. Shift-Break boots this file; it can also be run with CHAIN "name".
Defined by physical line 1 of the source: ENTRY <label-or-fixed-address>.
Derived from emitted ranges created by the mandatory line-2 ORG and any later ORG directives.
Executable setup statements taken from ; @basic ... comments in the assembled source and its INCLUDE files. They run before machine-code segment installation.
Mappings taken from ; @jsbeeb-key HOST=BBC comments in the assembled source and its INCLUDE files. They affect only Run in jsbeeb.