BASIC a strojové podprogramy

Radek Štěrba, RASTER

V tomto článku bych chtěl osvětlit, jak používat strojové podprogramy s voláním z BASICu.

Způsob volání: A=USR(Adresa,Parametr_1,...,Parametr_n)

ADRESA: Tato hodnota specifikuje místo v paměti, na kterém začíná volaný strojový podprogram. Tato adresa může být zadána buďto formou konkrétního čísla (resp. proměnné, která toto číslo obsahuje), ale často se můžete setkat s voláním přes adresu řetězce.

Co znamená ADR(A$): Zde je nutno užít podrobnějšího vysvětlení. Strojový podprogram je vlastně posloupnost čísel, která určují, co má procesor dělat. Tato čísla mohou být umístěna přímo v paměti, ale potom musíme zajistit, aby tam před prvním voláním opravdu byla. Při volání z BASICu se nabízí možnost tuto posloupnost čísel umístit do textového řetězce v podobě posloupnosti znaků (ASCI hodnoty jednotlivých znaků tvoří onu posloupnost čísel). Umístění řetězců v paměti však není pevně dáno, a proto takovýto stroj. podprogram voláme přes funkci ADR(..$) , která vrací, kde v paměti daný řetězec začíná.

S tímto řešením jsou však spojeny některé problémy:

  1. Pro nastavení řetězce na programovém řádku není možné používat všechny znaky (např. uvnitř řetězce nemůže být znak " nebo znak pro přechod na nový řádek). Existuje sice řešení - takový znak jednoduše vynechat (nahradit mezerou!) a pak ho tam dodat pomocí funkce ..$(pozice,pozice)=CHR$(číslo), ale to už není tak elegantní.
  2. Některé str. pprg. jsou napsány tak, že si vynucují umístění v paměti na nějaké adrese. U stringů toto nemůžeme zajistit. Jedinou možností je přenést ASCI hodnoty znaků v řetězci přímo do paměti na požadovanou adresu. Bez instrukce MOVE pro přesun (je pouze v TBASICu) je však toto zdlouhavé a neefektivní.

V TBASICu je možno použít:

MOVE ADR(..$),adresa,LEN(..$)

Potom již můžeme volat pprg. na této konkrétní adrese.

Z těchto důvodu vyplývá, že existují strojové pprg., které touto formou nelze bez problémů používat.

Strojový pprg. na konkrétní adrese: V tomto případě se nejčastěji používá způsob, kdy je str. pprg. umístěn v souboru a "nalouduje" se přes funkce pro čtení souboru přímo do paměti.

V TBASICu lze použít funkci BLOAD"zařízení:jménosouboru", která vše potřebné zajistí sama (str.pprg. však musel být uložen ve formátu BSAVE, ve kterém je dána adresa pro jeho umístění). Další možností je použít funkce OPEN.., BGET.., CLOSE, kterými dostaneme soubor do paměti na námi zadané místo.

V "čistém" BASICu je problém v tom, že funkce BLOAD ani BGET zde vůbec nejsou. Lze tedy použít kraťoučký str.pprg. (zadefinovaný pomocí stringu), který provádí obdobnou funkci jako TBasicovské BGET. Toto řešení vypadá sice poněkud složitě, ale věřte, že je nejelegantnější.

PARAMETRY: Při volání str. pprg. se za adresou zadávají parametry, které mu chceme předat. Je ovšem nutné vědět, jaké parametry ten či onen pprg. používá. Tyto informace by měly být ke každému str. pprg. dodány, neboť nedodržení počtu nebo pořadí parametrů může mít (narozdíl od BASICovských funkcí) za následek zhroucení systému (samozřejmě pouze softwarové části :-) ). Některé lepší pprg. mají nepovinné počty parametrů (pprg. sám rozpozná, kolik jich bylo použito a podle toho se chová). Jako parametry pro str.pprg. můžeme použít pouze celá nezáporná čísla (resp. proměnné - obsahující takto specifikovaná čísla) v rozsahu 0 až 65535 (tedy vnitřně reprezentované pomocí dvou bytů). Pokud je třeba předat do pprg. nějaký text, předává se přes ADR(..$) nebo přímo ADR("text"). Je třeba si však uvědomit, že ve skutečnosti nepředáváme tento text, ale pouze hodnotu, která určuje adresu paměti, kde se tento text nachází. Str. pprg. může (kromě jiné práce) i vracet hodnotu v proměnné, se kterou je volán (A=USR(..)). Tato hodnota může udávat např. výsledek nějaké početní operace, nebo označovat, zda požadovaná akce byla úspěšná (vrácením čísla chyby) apod.