Sheet
25. 3. 2026

Nikdy jsem nějak moc nepřišel na chuť compilátorům Basicu, ale program .asm z dílny Chrise Taylora se mi celkem zamlouvá. Napsat assembler kód přímo do Basic programu, spustíš normálně z Basicu příkazem RUN a vidíš výsledek.

NextBASIC Inline Assembler — Z80 assembler přímo v BASICu

Nikdy jsem nějak moc nepřišel na chuť compilátorům Basicu, ale program .asm z dílny Chrise Taylora se mi celkem zamlouvá. Napsat assembler kód přímo do Basic programu, spustíte normálně z Basicu příkazem RUN a vidíte výsledek.

Nástroj se jmenuje ASM a funguje jako dot command. Stačí zkopírovat soubor asm do složky /dot/ na SD kartě a máte k dispozici assembler dostupný z každého NextBASIC programu.


Jak to funguje

Princip je elegantně jednoduchý. Do svého NextBASIC programu napíšete .asm — tím spustíte assembler. Ten pak prochází následující řádky programu a hledá ty, které začínají středníkem ;. Obsah za středníkem bere jako assemblerový zdrojový kód a kompiluje ho do paměti. Jakmile narazí na řádek bez středníku, zastaví se a vrátí kontrolu BASICu.

Zkompilovaný strojový kód pak spustíte standardním způsobem přes USR.

Jedna důležitá věc ohledně mezer: pokud kód začíná těsně za středníkem bez mezery, assembler ho bere jako návěští (label). Pro instrukce musíte mít alespoň jednu mezeru za středníkem.


Minimální příklad

Začneme tím nejjednodušším možným programem — načteme hodnotu do registru BC a vrátíme ji do BASICu přes USR:

10 CLEAR $bfff   : REM Rezervujeme paměť pro kód
20 .asm            : REM Spustíme assembler
30 ;  org $c000
40 ;  ld bc, 42
50 ;  ret
60 PRINT "BC="; USR ($c000)

Spusťte program a uvidíte BC=42. Assembler zkompiloval instrukce do adresy $C000 (výchozí cíl), BASIC pak zavolal rutinu a vypsal hodnotu z registru BC. Změňte číslo na řádku 40 a spusťte znovu — okamžitá zpětná vazba.


Návěští a symbolické adresy

Assembler podporuje plnohodnotná symbolická návěští. Definujete je zápisem jména těsně za středník (bez mezery). Label pak můžete použít jako cíl skoku nebo jako konstantu — a forward reference funguje, label nemusí být definován před použitím.

Tady je klasický "Hello World" — tisk řetězce přes ROM rutinu:

 10 CLEAR $bfff
 20 .asm
 30 ;  org $c000
 40 ;  ld a, 2
 50 ;  call $1601  ; Otevřeme kanál 2 (obrazovka)
 60 ;  ld hl, msg
 70 ;nxtch             ← label (bez mezery za ;)
 80 ;  ld a, (hl)
 90 ;  or a
100 ;  ret z          ; Konec řetězce → return
110 ;  rst 16          ; Tiskni znak
120 ;  inc hl
130 ;  jr nxtch
140 ;msg db "Hello World",0
150 RANDOMIZE USR ($c000)

Sdílení dat mezi BASICem a assemblerem

Tohle je podle mě nejsilnější funkce celého nástroje. Assembler umí číst i zapisovat celočíselné proměnné NextBASIC (%a%z). BASIC tedy může předat parametry assembleru při kompilaci — a assembler může vrátit informace zpět do BASICu.

BASIC → Assembler: čtení proměnných při kompilaci

Proměnnou nastavenou v BASICu lze použít přímo v assemblerovém výrazu — včetně matematických operací:

 5 CLEAR $bfff
10 %z = 13          : REM Nastavíme BASIC proměnnou
20 .asm
30 ;  org $c000
40 ;  ld bc, %z*2    ; %z je 13, takže BC = 26
50 ;  ret
60 PRINT USR ($c000)  : REM Vytiskne 26

Assembler → BASIC: zápis adres přes LET

Pseudo-operátor LET umožňuje assembleru uložit hodnotu (typicky adresu zkompilované rutiny) do BASIC proměnné. Nemusíte tak ručně počítat, kde co v paměti skončilo — assembler vám adresy předá sám:

  5 CLEAR $bfff
 10 %z = 13
 20 .asm
 30 ;fn1               ← label první rutiny
 40 ;  ld bc, %z*2    ; BC = 26
 50 ;  ret
 60 ;fn2               ← label druhé rutiny
 70 ;  ld bc, 42
 80 ;  ret
 90 ;  LET %a = fn1   ; Adresa fn1 → BASIC proměnná %a
100 ;  LET %b = fn2   ; Adresa fn2 → BASIC proměnná %b
110 PRINT USR (%a)     : REM Zavolá fn1, vytiskne 26
120 PRINT USR (%b)     : REM Zavolá fn2, vytiskne 42

Assemblování do paměťových banků

ZX Spectrum Next nabízí rozšířenou paměť skrz 16KB banky. Assembler s tím pracuje nativně — pseudo-operátor BANK přesměruje výstup kompilace přímo do cílové banky. Číslo banky může pocházet přímo z BASIC proměnné:

10 BANK NEW %a          : REM Alokuj novou banku, číslo → %a
20 .asm
30 ;  BANK %a            ; Cíl kompilace = banka číslo %a
40 ;  ld bc, 42
50 ;  ret
60 PRINT BANK %a USR 0  : REM Spusť kód z banky

Reálný příklad: flood fill rutina

Tady vidíme spolupráci BASICu a assembleru v plné síle. Assembler zkompiluje rekurzivní flood fill algoritmus a pomocí LET pseudo-opu předá BASICu adresy datových buněk (x, y) uvnitř zkompilovaného kódu. BASIC pak volá rutinu opakovaně — jen POKEuje souřadnice do těchto adres a spouští USR.

 40 CLEAR $bfff
 50 PROC assemble()
 60 CIRCLE 64,110,30
 70 CIRCLE 128,80,60
 80 CIRCLE 192,110,30
 90 PROC fill(128,80)
100 PROC fill(64,110)
110 PROC fill(192,110)
120 STOP

130 DEFPROC fill(x,y)
140   POKE %x,x : POKE %y,192-y  : REM Zapíš souřadnice do rutiny
150   RANDOMIZE % USR $c000
160 ENDPROC

170 DEFPROC Assemble()
180 .asm
190 ;  ld de, (coords)
200 ;  call fill
210 ;  ret
220 ;fill
230 ;  call point
240 ;  ret nz
250 ;  call plot
260 ;  inc e
270 ;  call fill     ; Rekurzivně vpravo
280 ;  dec e
290 ;  dec e
300 ;  call fill     ; Vlevo
310 ;  inc e
320 ;  inc d
330 ;  call fill     ; Dolů
340 ;  dec d
350 ;  dec d
360 ;  call fill     ; Nahoru
370 ;  inc d
380 ;  ret
390 ;plot
400 ;  pixelad        ; Z80N instrukce
410 ;  setae          ; Z80N instrukce
420 ;  or (hl)
430 ;  ld (hl), a
440 ;  ret
450 ;point
460 ;  pixelad
470 ;  setae
480 ;  and (hl)
490 ;  ret
500 ;coords
510 ;x db 0
520 ;y db 0
530 ;  let %x = x     ; Adresa buňky X → BASIC %x
540 ;  let %y = y     ; Adresa buňky Y → BASIC %y
550 ENDPROC

Assemblování externího souboru

Od verze 0.8b lze assembleru předat přímo název externího .asm souboru — inline zápis do BASICu tedy není jediná možnost. Zdrojový soubor se píše jako normální assembler: bez čísel řádků a bez středníků na začátku řádků.

Soubor lze spustit dvěma způsoby. Přímo z příkazové řádky Nextu:

.asm hello.asm

Nebo z NextBASIC programu:

10 .asm basiclib.asm

Příklad — zdrojový soubor basiclib.asm (bez středníků, bez čísel řádků):

    org $c000  ; Cílová adresa
    ld bc, 42
    ret

A BASIC program, který ho zkompiluje a spustí:

10 CLEAR $bfff
20 .asm basiclib.asm   : REM Zkompiluj externí soubor
30 PRINT USR ($c000)      : REM Vytiskne 42

Tohle otevírá zajímavý workflow: kód píšete v ZED nebo jiném editoru jako čistý .asm soubor, a z BASICu ho jen zavoláte jedním řádkem. Větší assemblerové knihovny tak nemusí žít zakonzervované uvnitř BASIC programu — jsou to samostatné soubory, které lze sdílet nebo includovat z více projektů.


Přehled pseudo-operátorů

Assembler nabízí bohatou sadu pseudo-opů nad rámec standardních Z80 instrukcí:

Pseudo-op Popis
ORG Nastaví cílovou adresu kódu. Výchozí hodnota je $C000.
DB / DW / DS Definice dat — bajty, slova, rezervace bloku paměti.
DZ / DC Řetězce — DZ s nulovým terminátorem, DC s nastaveným high bitem posledního znaku.
EQU Definuje pojmenovanou konstantu.
LET Zapíše hodnotu (např. adresu rutiny) do NextBASIC celočíselné proměnné.
BANK Přesměruje výstup kompilace do konkrétní 16KB paměťové banky.
ALIGN Zarovná kód nebo data na zadanou hranici bajtů.
ASSERT Vyvolá chybu assemblování, pokud výraz není pravdivý. Užitečné pro sanity checks.
DISPLAY Vypíše zprávu nebo hodnotu výrazu během assemblování — užitečné pro ladění.
IF / ELSE / END Podmíněný překlad — různé varianty kódu podle hodnoty výrazu.
INCLUDE Načte a zkompiluje externí zdrojový soubor. Větší projekty lze rozdělit do více souborů.
OUTPUT Přesměruje zkompilovaný kód do souboru na SD kartě.
SAVENEX Vytvoří spustitelný NEX soubor přímo z BASICu.
BRK / NBRK Vloží breakpoint pro CSpect emulátor nebo hardwarový breakpoint na reálném hardwaru.
RELOC_START / END Podpora přemístitelného kódu — určeno pro tvorbu NextZXOS ovladačů.
VAR Proměnné návěští, jehož hodnota se může měnit mezi průchody assembleru.

Instalace a kde stáhnout

Nevím jak Vy, ale mě se tento program hodně líbí. Asi pravděpodobně nevyužiji assembler přímo v Basicu, neboť jsem Basic lama, ale kompilovat *.asm soubory s ním zkusím, textový editor ZED je celkem použitelný, tak uvidíme.

3S6n3c

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *