...a kedze (aj sam na sebe) viem ze ludia su lenivi citat oficialnu dokumentaciu / zdrojak (co je mimobehom najpresnejsia dokumentacia), napisem sem taky ludskejsi pokec, ako BasicLib pouzivat.
A ako je uz taka programatorska tradicia, zacneme jednoduchym Hello world. Vlastne, uz sme zacali - v prvom prispevku tohto vlakna. Takze to sem len znovu skopirujem::
Kód:
INCLUDE BasicLib.asm
LINE : db bright : NUM 1 : LEND
LINE : db print,'"Hello world"' : LEND
Vygeneruje sa tento basic program:
Kód:
10 BRIGHT 1
20 PRINT "Hello world"
Makro
LINE nam otvori novy basicovy riadok. Do prelozeneho kodu vygeneruje cislo riadku a ulozi dlzku riadku.
Makro
LEND riadok uzatvara - vygeneruje kod 13 (enter) na konci riadku a je tiez potrebne pre spravny vypocet dlzky riadku. Dalej automaticky inkrementuje cislo riadku o dany krok tak, aby dalsia dvojica
LINE...
LEND logicky vygenerovala dalsie cislo riadku.
Mozno ste si vsimli, v tomto programe je este jedno makro:
NUM. Toto makro sluzi na generovanie ciselnej konstanty - do skompilovaneho kodu ulozi textovy tvar cisla, potom kod 14 a za nim 5 bajtov hodnoty cisla. Momentalne su podporovane iba cele kladne cisla 0-65535. Ak chcete zapornu hodnotu - proste dajte pred cislo znak '-'. Aj basic to tak robi - po kode 14 uklada len kladne hodnoty a pred cislom pouzije minus

V basicoch setriacich pamet sa casto pouzivaju usporne tvary cisel VAL "cislo". Aj taketo nieco vie makro NUM vygenerovat.
Pre tento ucel je k dispozicii logicka premenna
line_useval. Defaultne je nastavena na nulu ale ked si ju nastavime na nenulovu hodnotu, makro
NUM bude
generovat cisla pomoocu VAL.
Kód:
INCLUDE BasicLib.asm
line_useval = 1
LINE : db bright : NUM 1 : LEND
LINE : db print,'"Hello world"' : LEND
Vysledkom bude tento program:
Kód:
10 BRIGHT VAL "1"
20 PRINT "Hello world"
Vsimli ste si, ze makra
LINE a
LEND nam riadky automaticky cisluju po 10 (tak ako byva zauzivanym zvykom) ?
Co ale ak chcem nejake ine cisla riadkov ?
V takom pripade su k dispozicii tieto dve premenne:
line_number ... aktualne cislo riadku ktore sa ulozi pomocou makra LINE
line_step .... krok o kolko sa v makre LEND zvysi cislo riadku pri generovani dalsieho riadku
Takze ak chcem aby moj program zacinal na riadku 100 a riadky sa cislovali po 1 tak staci spravit:
Kód:
INCLUDE BasicLib.asm
line_number = 100
line_step = 1
LINE : db bright : NUM 1 : LEND
LINE : db print,'"Hello world"' : LEND
Vygenerovany program potom bude:
Kód:
100 BRIGHT 1
101 PRINT "Hello world"
Cislo riadku sa da samozrejme nastavit aj kdekolvek v ramci basic programu, napriklad:
Kód:
INCLUDE BasicLib.asm
LINE : db bright : NUM 1 : LEND
line_number = 9999
LINE : db print,'"Hello world"' : LEND
Basic program potom bude vyzerat:
Kód:
10 BRIGHT 1
9999 PRINT "Hello world"
BasicLib automaticky kontroluje, aby cisla riadkov neprekrocili maximalnu moznu hodnotu 16363. Ak by malo dojst k vygenerovaniu riadku s cislom vyssim, kompilacia skonci s chybou "Line number overflows".
Niekedy je ale potrebne cisla riadkov pouzit v programe, napriklad v prikazoch GOTO, GOSUB, RESTORE, SAVE LINE ... Co v takom pripade ?
Kedze aktualne cislo generovaneho riadku vzdy mame v premennej line_number, nie je nic jednoduchsie, nez vyuzit tuto premennu.
Kód:
INCLUDE BasicLib.asm
LINE : db bright : NUM 1 : LEND
goto_here = line_number
LINE : db print,'"Hello world"' : LEND
LINE : db goto : NUM goto_here : LEND
A my dostaneme takyto program:
Kód:
10 BRIGHT VAL"1"
20 PRINT "Hello world"
30 GO TO 20
Kedze line_number sa inkrementuje v makre LEND, tak nielen v ramci generovania aktualneho riadku, ale uz pred nim je premenna line_number nastavena na cislo riadku ktory sa bude najblizsie generovat. Preto si staci pred riadkom, na ktory budeme skakat, odpametat line_number do inej premennej a tuto inu premennu nasledne pouzit v prikaze GOTO.
Ak skaceme na dany riadok v ramci tohto riadku, mozeme v prikaze GOTO a v za nim nasledujucom makre NUM rovno pouzit premennu line_number.
Samozrejme funguju aj dopredne skoky, t.j. prikaz GOTO ktory skace na niektory riadok ktory je v programe dalej.
A teraz trosku zlozitejsie veci 
Ak chceme nacitat 16-bitove cislo v basicu, spravime to klasicky:
PEEK adresa + 256 * PEEK (adresa+1).Pokial chceme usporny tvar pomocou VAL, logicky nas napadne:
PEEK VAL "adresa" + VAL "256" * PEEK VAL "adresa+1".Lenze ! Naco zbytocne mat 3x VAL"" ked to staci iba raz ? Proste, cely vyraz zavrieme do jedineho VAL-u
VAL"PEEK adresa + 256 * PEEK (adresa+1)"Kedze samotna adresa nemusi byt vopred znama konstanta (ktoru vieme priamo napisat ako text), ale moze to byt nejaky label ktoreho hodnotu
sa dozvieme az kompilaciou, mali by sme mat moznost napisat aj takyto vyraz. Cize potrebujeme nieco, co nam ciselnu hodnotu previedie
do textovej podoby bez pouzitia VAL a generovania kodu 14 a 5 bajtov za nim.
A prave na toto je mozne vyuzit makro
DEC ktore rozvinie 16-bitovu celociselnu hodnotu na postupnost cislic.
Kód:
.. .....
adresa dw nieco ; Nejaka 16-bitova premenna niekde v kode
.. .....
INCLUDE BasicLib.asm
LINE
db let,'a=',val,'"',peek
DEC adresa
db '+256*',peek
DEC adresa + 1
db '"'
LEND
(tu mozete vidiet ze som jeden basic riadok kvoli prehladnosti rozpisal na viac asemblerovych riadkov)
Dajme tomu, ze po kompilacii bude mat label 'adresa' hodnotu #8002 alebo 32770. Potom ziskame takyto program:
Kód:
10 LET a=VAL "PEEK 32770+256*PEEK 32771"
Na zaver este zopar poznamok k pouzitym tokenom (uz som sa toho trosku dotkol v predchadzajucom prispevku):
Kedze som chcel aby sa tokeny pisali co najjendoduchsie, su napisane malymi pismenami. Pre niektore velmi dlhe prikazy (RANDOMIZE, CONTINUE) som zaviedol aj 4-pismenove skraty (
rand,
cont).
Niektore tokeny (and,or,not) mozu byt v konflikte s logickymi operatormi asembleru, tam som pridal 'x' na koniec nazvu (
andx,
orx,
notx).
Takze pokial sa vam na nejaky token vypise nejaka chyba (undefined a pod.) najlepsie je sa pozriet priamo do BasicLib ako je tam dany token napisany.
A pre pokrocilejsich programatorov isto nebude problem pripadny konflikt vyriesit vlastnou zmenou definicii priamo v BasicLib

Ak potrebujete v ramci projektu vytvorit viac basicov, potom
INCLUDE BasicLib staci iba raz, ale pre dalsie basicy je vhodne (ale nie nevyhnutne)
definovat zaciatocny riadok, napriklad
line_number = 10 aby riadky roznych basicov nesli pekne po sebe ako keby to bol jeden velky basic.
Kód:
INCLUDE BasicLib.asm
;Basic 1
LINE : db bright : NUM 1 : LEND
LINE : db print,'"Hello world"' : LEND
;Basic 2
line_number = 10
LINE : db bright : NUM 1 : LEND
LINE : db print,'"Goodbye world"' : LEND
A na uplny zaver len znovu zopakujem to co uz napisal mborik vo svojom prispevku: Ak by sa vam niektore tokeny bili s inymi labelmi ktore mate v kode, a nebude sa vam chciet konfliktne labely kompletne predefinovavat, pomoze ak cely basic vratane INCLUDE zabalite do modulu:
Kód:
MODULE moj_basic
INCLUDE BasicLib
....
ENDMODULE
Len v tomto pripade si dajte pozor, ak definujete nejaky label v ramci tohto modulu a chcete ho pouzit mimo modulu, potom je potrebne aby ste pouzili label v tvare Nazov_modulu.nazov_labelu. Napriklad:
Kód:
MODULE MOJ_BASIC
INCLUDE BasicLib
....
goto_here = line_number
....
ENDMODULE
...
; Kod mimo modulu s basicom:
ld bc,MOJ_BASIC.goto_here