Hlavní navigace

PC-BASIC: reinkarnace populárního i zatracovaného GW-BASICu

23. 9. 2021
Doba čtení: 40 minut

Sdílet

 Autor: Rob Hagemans
V první polovině osmdesátých let patřilo k dobrému vychování dodávat domácí i osobní počítače vybavené nějakým dialektem programovacího jazyka BASIC. Výjimkou není ani IBM PC, pro které byl dodáván mj. i GW-BASIC, později QBasic.

Obsah

1. PC-BASIC – reinkarnace populárního i zatracovaného GW-BASICu

2. Interpretry a překladače jazyka BASIC vyvinuté společností Microsoft

3. Programovací jazyk BASIC na platformě IBM PC

4. GW-BASIC

5. Klasický špagetový kód – čísla řádků a příkazy GOTO a GOSUB

6. Strukturované příkazy pro programové smyčky

7. Celočíselné datové typy

8. Formátování textového výstupu

9. Grafický výstup, přímý přístup do obrazové paměti

10. Dobré stránky GW-BASICu

11. Reakce na (asynchronní) události

12. Doménově specifické podjazyky – příkazy DRAWPLAY

13. Definice uživatelských funkcí, přiřazení typu proměnným na základě jejich jména

14. Inherentní omezení GW-BASICu

15. Moderní náhrada GW-BASICu – PC-BASIC

16. Instalace PC-BASICu

17. Ukázky použití PC-BASICu

18. Od GW-BASICu ke QBasicu

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. PC-BASIC – reinkarnace populárního i zatracovaného GW-BASICu

„GW-BASIC is arguably the ne plus ultra of Microsoft's family of line-numbered BASICs stretching back to the Altair–and perhaps even of line-numbered BASIC in general.“

Počítače IBM PC, které začaly být na trh dodávány prakticky přesně před čtyřiceti lety, se v mnoha ohledech podobaly dalším dobovým domácím a osobním mikropočítačům. Příkladem je existence interpretru jazyka BASIC, kterým byly vybaveny prakticky všechny domácí osmibitové mikropočítače (abecedně Apple, Atari, Commodore, Sinclair, Timex, včetně počítačů vyráběných o několik let později v ČSSR). Původní IBM Advanced Basic (BASICA) byl v DOSu nahrazen slavným GW-BASICem, kterému je věnován dnešní článek. Na GW-BASIC lze nahlížet jako na konečný výsledek vývoje „klasických“ BASICů s čísly řádků, nestrukturovanými příkazy GOTO a GOSUB a plnou interaktivitou (zde doplněnou o příkazy TRON a TROFF, které umožňují trasování programů bez nutnosti použití debuggeru). I pro autory tohoto BASICu – společnost Microsoft – se jednalo o určité ukončení jedné historické éry, protože její další programovací jazyky již byly založeny na modernějších principech.

Poznámka: na tomto místě je nutné zdůraznit, že ke GW-BASICu existovaly alternativy. Samozřejmě se jednalo o překladače jazyků zaměřených na profesionály ©, popř. o relativně nový Turbo Pascal. Může to znít paradoxně, ale největším konkurentem GW-BASICu byly tabulkové procesory. A skutečně – mnoho programů vytvořených v GW-BASICu souviselo s typicky domácími či firemními informačními minisystémy a pomocnými programy – vedení knihy jízd, výpočet složeného úroku, výpočet, kolik bankovek a mincí musí účtárna převzít z banky, aby dala zaměstnancům výplatu (ty se dávaly „v obálce“), úlohy z lineárního programování (řezné plány), výpočet docházky, různé úlohy ze stavebnictví a strojnictví, vykreslení interpolačních a aproximačních křivek pro naměřená data atd. A mnoho z takto koncipovaných aplikací lze snadněji provést právě v tabulkových procesorech.

2. Interpretry a překladače jazyka BASIC vyvinuté společností Microsoft

Velmi důležitým hráčem na poli interpretrů a překladačů programovacího jazyka BASIC byla společnost Microsoft, která ostatně stále dodává Visual Basic .NET, což je ovšem jazyk, který se původnímu klasickému BASICu už příliš nepodobá. Microsoft, původně přímo Bill Gates a Paul Allen, se vývojem a přímým či nepřímým prodejem nějaké formy BASICu začala zabývat již v roce 1975, kdy vznikl Altair BASIC naprogramovaný v assembleru osmibitového mikroprocesoru Intel 8080. Mimochodem, právě kvůli rozšiřování pirátských kopií Altair BASICu napsal Bill Gates slavný Open Letter to Hobbyist. Později společnost Microsoft vytvořila i další varianty BASICu, a to pro různé počítačové platformy. Ty nejdůležitější milníky (pokud vynecháme řadu Visual BASIC) jsou vypsány v tabulce:

# Název jazyka Rok vzniku Poznámka
1 Altair BASIC 1975 verze 4k a 8k
2 Applesoft BASIC 1977 pro řadu Apple II
3 Commodore BASIC 1977 pro slavný Commodore C64
4 Level I BASIC 1977 pro počítače TRS-80
5 Level II BASIC 1978 pro počítače TRS-80
6 Color BASIC 1980
7 MBASIC 1980 pro počítače s CP/M, vyžaduje 28kB RAM
8 IBM BASIC (IBM Personal Computer BASIC) 1981 taktéž Cassette BASIC
9 Atari Microsoft BASIC 1982 pro osmibitová Atari
10 Microsoft Basic-86 1982  
11 MSX BASIC 1983 platforma MSX
12 Extended Color BASIC 1983?  
13 Disk Extended Color BASIC 1984  
14 BASIC 1.0 (pro Thomson computers) 1986  
15 GW-BASIC 1983 – 1988 dodáván společně s DOSem
16 QBasic 1991 dodáván společně s DOSem od verze 5.0
17 QuickBASIC 1985 – 1990 překladač
Poznámka: Mimochodem – vydání GW-BASICu časově odpovídá vydání dalšího velmi populárního jazyka – Turbo Pascalu. Skutečně – první verze Turbo Pascalu vznikla taktéž v roce 1983, ovšem přelomový byl až Turbo Pascal 5.5 z roku 1989, který tak předešel následovníka GW-BASICu, jímž byl QBasic (a Microsoft se určitě nechal inspirovat textovým uživatelským rozhraním Turbo Pascalu):
# Název jazyka Datum vydání
1 Turbo Pascal 1 20.11.1983
2 Turbo Pascal 2 17. 4.1984
3 Turbo Pascal 3 17. 9.1986
4 Turbo Pascal 4 20.11.1987
5 Turbo Pascal 5 24. 8.1988
6 Turbo Pascal 5.5 2. 5.1989
7 Turbo Pascal 6 23.10.1990
8 Turbo Pascal for Windows 1.0 13. 2.1991
9 Turbo Pascal for Windows 1.5 8. 6.1992
10 Borland Pascal 7 27.10.1992

Obrázek 1: Uživatelské rozhraní slavného Turbo Pascalu 5.5.

3. Programovací jazyk BASIC na platformě IBM PC

GW-BASIC byl určen pro provoz na počítačích IBM PC či na kompatibilních strojích, takže se na chvíli zastavme u tohoto fenoménu. Programovací jazyk BASIC, resp. přesněji řečeno jeho různé více či méně dokonalé dialekty, byl na IBM PC původně portován, teprve později vznikla verze přímo využívající nové vlastnosti mikroprocesorů Intel 8088. Ostatně už originální PC od společnosti IBM bylo standardně vybaveno interpretrem BASICu, který se spustil v případě, že nebyl nalezen boot sektor operačního systému. Vzhledem k tomu, že počítače IBM PC začaly být zákazníkům, především firmám, nabízeny již v roce 1981, tj. v dobách kralování osmibitových domácích mikropočítačů, byly i první modely IBM PC vybaveny, podobně jako naprostá většina osmibitových počítačů, interpretrem programovacího jazyka BASIC uloženého v paměti ROM.

Obrázek 2: Fotografie obrazovky počítače IBM PC se spuštěným interpretrem BASICu, v němž je napsán velmi jednoduchý program.

Na originálním IBM PC byla kapacita této paměti ROM rovna 40 kB, přičemž BASIC z této kapacity využíval 32 kB a zbylých 8 kB sloužilo pro uložení BIOSu (v dalších modelech IBM PC se kapacita ROM kvůli podpoře většího množství zařízení zvyšovala, typicky na hodnotu 64 kB). Interpret BASICu uložený v ROM se spouštěl snadno – v případě, že počítač po svém zapnutí nenašel v disketové jednotce disketu s operačním systémem (podpora pro pevné disky byla zavedena až s modelem PC XT v roce 1983, tedy až o dva roky později), spustil se automaticky interpret BASICu. Dialekt programovacího jazyka BASIC uložený v ROM se sice nazýval IBM Cassette BASIC (i když se na obrazovce ohlašoval nápisem „IBM Personal Computer Basic“), ve skutečnosti se však jednalo o interpret BASICu vytvořený firmou Microsoft, která ho licencovala firmě IBM jako jeden z prvních softwarových produktů pro počítače PC vůbec. Poté následoval operační systém MS-DOS, ale o této poměrně historické události si však řekneme více podrobností v jiném článku. Při převodu BASICu na počítače IBM PC použila firma Microsoft svůj BASIC určený pro operační systém CP/M – viz též předchozí kapitolu věnovanou tomuto tématu.

4. GW-BASIC

Zatímco IBM Cassette BASIC byl používán pouze na originálních počítačích IBM PC a nikoli na mnohých klonech (díky kterým se platforma IBM PC tak rozšířila), další dialekt programovacího jazyka BASIC byl dostupný všem uživatelům, protože měl formu běžné (spustitelné) aplikace určené pro operační systém MS-DOS. Jedná se o GW-BASIC vytvořený opět firmou Microsoft. Vývoj tohoto programovacího jazyka a taktéž standardizaci jeho příkazů napříč několika operačními systémy a platformami vedl Greg Whitten, který do firmy Microsoft nastoupil již v roce 1979 a měl tak velmi nízké číslo zaměstnance (sám uvádí, že pokud si dobře pamatuje, měl číslo 16). Název tohoto programovacího jazyka zvolil sám Bill Gates, přičemž písmena „GW“ oficiálně znamenaly zkratku dvousloví „Gee-Whiz“, pravděpodobně se však původně jednalo o iniciály Grega Whittena. GW-BASIC se stal mezi uživateli počítačů IBM PC (především v dobách PC XT) velmi populární, i když se jednalo o dialekt, který se nijak zvlášť neodlišoval od dialektů BASICu dostupných na osmibitových mikropočítačích – dokonce bylo možné používat pouze jeden segment paměti, tj. 64 kB, i když samotný MS-DOS dokázal obsloužit 640 kB, resp. 1 MB pokud započítáme i oblast BIOSu, grafické paměti, popř. BIOSu síťové karty.

Obrázek 3: Úvodní obrazovka GW-BASICu po jeho spuštění v emulátoru PC (zde se konkrétně jedná o DOSBOX).

GW-BASIC, který je možné považovat za vrcholnou formu „klasického“ BASICu s čísly řádků, nestrukturovanými příkazy, pouze globálními proměnnými a neexistencí uživatelských datových typů, se na platformě IBM PC stal velmi populární. Je to ostatně logické, protože byl dostupný všem uživatelům, tedy i neprogramátorům (a obecně lidem, kterým nestálo za to investovat čas do koupě překladače profesionálního jazyka, popř. lidem, kterým počítač nepatřil a přesto si chtěli vyzkoušet něco naprogramovat). Z tohoto důvodu bylo pro GW-BASIC vytvořeno obrovské množství programů na amatérské bázi a doposud existují fanoušci buď přímo GW-BASICu nebo jeho moderní reinkarnace PC-BASICu, o němž se zmíníme v dalším textu.

5. Klasický špagetový kód – čísla řádků a příkazy GOTO a GOSUB

Jak jsme si již řekli v úvodních kapitolách, je GW-BASIC posledním zástupcem klasických BASICů založených na číslech řádků a nestrukturovaných skocích GOTO, popř. skocích do podprogramu GOSUB. Teprve QBasic, což je přímý nástupce GW-BASICu, představuje poměrně masivní odklon od tohoto stylu programování. Nicméně si ukažme, jak vypadá použití příkazů GOTO a GOSUB, protože ty jsou esencemi klasického BASICu (první BASIC vůbec měl jen 15 příkazů a mezi nimi GOTO a GOSUB pochopitelně figurovalo).

Výpočet největšího společného dělitele:

1 REM *****************************
2 REM Vypocet nejvetsiho spolecneho
3 REM delitele.
4 REM
5 REM Uprava pro GW-BASIC
6 REM
7 REM *****************************
8 REM
9 REM
10 PRINT "X=";
20 INPUT X
30 PRINT "Y=";
40 INPUT Y
50 IF X=Y THEN PRINT "GCD: ";X:END
60 IF X>Y THEN X=X-Y:GOTO 50
70 IF X<Y THEN Y=Y-X:GOTO 50
999 END

Příkaz ON GOTO je velmi silný a současně i nebezpečný – provede skok na n-tý řádek na základě hodnoty výrazu, tedy pro hodnotu 1 se provede skok na první specifikovaný řádek atd.:

1 REM *****************************
2 REM Příkaz ON GOTO
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 PRINT "1. File operations"
20 PRINT "2. Edit operations"
30 PRINT "3. Quit"
40 INPUT A
50 ON A GOTO 1000, 2000, 3000
999 END
1000 PRINT "File operations"
1010 END
2000 PRINT "Edit operations"
2010 END
3000 PRINT "Quit"
3010 END

Podobný příklad, ovšem využívající skok do podprogramu GOSUB. Návrat z podprogramu zpět zajišťuje příkaz RETURN (menu s nabídkou se bude stále opakovat):

1 REM *****************************
2 REM Příkaz ON GOSUB
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 PRINT "1. File operations"
20 PRINT "2. Edit operations"
30 PRINT "3. Quit"
40 INPUT A
50 ON A GOSUB 1000, 2000, 3000
60 GOTO 10
999 END
1000 PRINT "File operations"
1010 RETURN
2000 PRINT "Edit operations"
2010 RETURN
3000 PRINT "Quit"
3010 RETURN
Poznámka: tyto příklady používají GOTO „civilizovaně“, ovšem ve skutečnosti lze skutečně relativně snadno naprogramovat dokonalý špagetový kód.

6. Strukturované příkazy pro programové smyčky

GW-BASIC podporuje dva formáty strukturovaných programových smyček. Prvním typem smyčky je smyčka FOR-NEXT, která je použita v prakticky všech BASICech – ovšem její chování není všude stejné! A druhým typem smyčky je WHILE-WEND. Posléze byla do QBasicu přidána i univerzální smyčka DO-LOOP, u níž lze zvolit test na začátku a/nebo i na konci.

Nejtypičtější příklad použití počítané smyčky FOR-NEXT:

1 REM *****************************
2 REM Smyčka typu FOR-NEXT
3 REM v základní formě.
4 REM
5 REM Úprava pro GW-BASIC
6 REM *****************************
7 REM
8 REM
9 REM
10 FOR I=0 TO 10
20   PRINT I
30 NEXT I

Specifikovat je možné i krok určující změnu počitadla smyčky po každé iteraci:

1 REM *****************************
2 REM Smyčka typu FOR-NEXT
3 REM se specifikací kroku.
4 REM
5 REM Úprava pro GW-BASIC
6 REM *****************************
7 REM
8 REM
9 REM
10 FOR I=0 TO 10 STEP 2
20   PRINT I
30 NEXT I

Některé BASICy v dalším programu do smyčky vstoupí a vypíšou hodnotu 10, což je nekorektní chování (příkladem je Atari BASIC). GW-BASIC korektně nevypíše nic:

1 REM *****************************
2 REM Smyčka typu FOR-NEXT
3 REM ve formě, kdy je horní limit
4 REM menší než limit horní.
5 REM
7 REM Úprava pro GW-BASIC
7 REM *****************************
8 REM
9 REM
10 FOR I=10 TO 0
20   PRINT I
30 NEXT I

V GW-BASICu se mezní hodnoty počitadla i kroku vyhodnocují před vstupem do smyčky, takže další příklad představuje konečnou smyčku:

1 REM *****************************
2 REM Smyčka typu FOR-NEXT
3 REM s průběžnou změnou horního
4 REM limitu.
5 REM
6 REM Úprava pro GW-BASIC
7 REM *****************************
8 REM
9 REM
10 MAX=10
20 FOR I=0 TO MAX
30   PRINT I,MAX
40   MAX=MAX+1
50 NEXT I

Nepatrně složitější příklad s dvojicí nepřímo vnořených smyček pro výpočet konstanty π:

1 REM *****************************
2 REM Vypocet konstanty Pi.
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 N=1
20 FOR I=1 TO 10
25   GOSUB 1000:REM VYPOCET PI
30   PRINT I,N,PI
35   N=N*2
40 NEXT I
999 END
1000 REM
1001 REM SUBRUTINA PRO VYPOCET PI
1002 REM
1010 PI=4
1020 FOR J=3 TO N+2 STEP 2
1030   PI=PI*(J-1)/J*(J+1)/J
1040 NEXT J
1050 RETURN

Smyčka typu WHILE-WEND použitá při výpočtu největšího společného dělitele:

1 REM *****************************
2 REM Výpočet největšího společného
3 REM dělitele postavený na smyčce
4 REM typu WHILE-WEND.
5 REM
6 REM Uprava pro GW-BASIC
7 REM *****************************
8 REM
9 REM
10 PRINT "X=";
20 INPUT X
30 PRINT "Y=";
40 INPUT Y
50 WHILE X<>Y
60   IF X>Y THEN X=X-Y
70   IF X<Y THEN Y=Y-X
80 WEND 
90 PRINT "GCD: ";X
91 END

Nepatrně složitější příklad s dvojicí nepřímo vnořených smyček pro výpočet konstanty π. Tentokrát se ovšem používají smyčky WHILE-WEND:

1 REM *****************************
2 REM Výpočet hodnoty konstanty PI
3 REM postavený na smyčce
4 REM typu WHILE-WEND.
5 REM
6 REM Uprava pro GW-BASIC
7 REM *****************************
8 REM
9 REM
10 N=1
20 WHILE N<=2000
25   GOSUB 1000: REM COMPUTE_PI
30   PRINT N,PI
35   N=N*2
40 WEND 
999 END
1000 REM
1001 REM SUBRUTINA PRO VYPOCET PI
1010   PI=4
1015   J=3
1020   WHILE J<=N+2
1030     PI=PI*(J-1)/J*(J+1)/J
1040     J=J+2
1050   WEND 
1060 RETURN

7. Celočíselné datové typy

Poměrně velký rozdíl mezi BASICy od Microsoftu a některými dalšími interpretry BASICu spočívá v tom, že se pro výpočty používají odlišné datové typy. Microsoft BASICy a tudíž i GW-BASIC totiž podporují šestnáctibitová celá čísla se znaménkem, reálné hodnoty založené na formátu Microsoftu (tedy ne na IEEE 754) a pochopitelně taktéž řetězce. Zcela jsou tedy vynechány hodnoty single a double odpovídající IEEE 754.

Typ proměnné bylo možné určit postfixovým znakem:

% typ int
$ typ string
Poznámka: později byl do QBasicu přidán i prefix # pro typ double.

První demonstrační příklad v této kapitole představuje implementaci algoritmu bublinkového řazení, v němž se používají pouze reálná čísla:

1 REM *****************************
2 REM Bubble sort
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 DIM A(20)
11 FOR I=0 TO 20
12 A(I)=INT(100*RND(1))
13 NEXT I
14 GOSUB 100:REM TISK OBSAHU POLE
20 FOR I=19 TO 0 STEP -1
21 PRINT ".";
25 FOR J=0 TO I
30 IF A(J)<A(J+1) THEN X=A(J):A(J)=A(J+1):A(J+1)=X
35 NEXT J
40 NEXT I
49 PRINT ""
50 PRINT "SORTED:"
60 GOSUB 100:REM TISK OBSAHU POLE
99 END
100 REM TISK OBSAHU POLE
101 FOR I=0 TO 20
102 PRINT I,A(I)
103 NEXT I
104 RETURN

Druhý demonstrační příklad je odlišný, protože používá jen celočíselné datové typy. Navíc je napsán malými písmeny, což GW-BASIC toleruje:

1 rem ********************************
2 rem Bubble sort pro pole typu single
3 rem
4 rem Uprava pro Microsoft BASIC
5 rem
6 rem Upraveno do podoby benchmarku
7 rem
8 rem ********************************
9 rem
10 rem casovac
11 t1 = timer
12 rem
20 rem vlastni benchmark
21 max%=200
22 dim a%(max%)
23 for i%=0 to max%
24 a%(i%)=int(100*rnd(1))
25 next i%
26 gosub 100:rem tisk obsahu pole
27 for i%=max%-1 to 0 step -1
28 print ".";
29 for j%=0 to i%
30 if a%(j%)<a%(j%+1) then x=a%(j%):a%(j%)=a%(j%+1):a%(j%+1)=x
31 next j%
32 next i%
33 print ""
34 print "sorted:"
35 gosub 100:rem tisk obsahu pole
40 rem precteni casovace
42 t2=timer
50 print "finished in ";t2-t1;" seconds"
99 end
100 rem tisk obsahu pole
101 for i%=0 to max%
102 print i%,a%(i%)
103 next i%
104 return
Poznámka: druhý příklad je pochopitelně značně rychlejší.

8. Formátování textového výstupu

GW-BASIC měl poměrně silné možnosti v oblasti formátování dat, které se mají zobrazit na textové konzoli počítače IBM PC. Základním příkazem pro tisk dat byl pochopitelně příkaz PRINT převzatý z prapůvodního BASICu:

1 REM *****************************
2 REM Základní tvar příkazu PRINT
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 PRINT "HELLO WORLD!"
20 PRINT 1+2
999 STOP

Čárkou a středníkem bylo možné zobrazit více hodnot, buď oddělených TABy (čárka) nebo spojených (středník):

1 REM *****************************
2 REM Další tvary příkazu PRINT
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 PRINT "HELLO", "WORLD", "!"
20 PRINT 1, 2, 6*7
30 PRINT "HELLO"; "WORLD"; "!"
40 PRINT 1; 2; 6*7
999 STOP

Mnohem více možností nabízel příkaz PRINT USING, kterým bylo možné specifikovat šířku jednotlivých sloupců a tím pádem i způsob jejich vizuálního oddělení:

1 REM *****************************
2 REM Příkaz PRINT USING
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 A$="FOO"
20 B$="BAR"
30 PRINT USING "!"; A$; B$
40 PRINT USING"\\"; A$; B$
50 PRINT USING"\ \"; A$; B$
60 PRINT USING"\  \"; A$; B$
70 PRINT USING"\   \"; A$; B$;"!"
999 END

Při formátování numerických hodnot je možné zvolit počet míst před desetinnou čárkou a za desetinnou čárkou (resp. tečkou), a to specifikací počtu cifer znakem # (bez počítání):

1 REM *****************************
2 REM Příkaz PRINT USING
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 X = 1.23
20 PRINT X
30 PRINT USING "##"; X
40 PRINT USING "####"; X
50 PRINT USING "##.##"; X
60 PRINT USING "##.#####"; X
999 END

Další možností je oddělení tisíců, milionů atd. čárkou (protože ta není v anglosaském světě použita jako oddělovač desetinných cifer):

1 REM *****************************
2 REM Příkaz PRINT USING
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 X = 1234567890
20 PRINT X
30 PRINT USING "##"; X
40 PRINT USING "##,.##"; X
999 END

9. Grafický výstup, přímý přístup do obrazové paměti

GW-BASIC podporoval i grafický výstup, i když omezený na možnosti grafických karet CGA, EGA a v některých variantách i na Hercules (jinými slovy – ani VGA ani SVGA režimy podporovány nebyly).

V tomto příkladu je ukázán způsob vykreslení průběhu funkce sin v grafickém režimu číslo 9 kompatibilním s kartami EGA a CGA. Grafické příkazy jsou zvýrazněny:

1 REM *****************************
2 REM Vykreslení průběhu funkce sin
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
20 GOSUB 1000: REM SET_GRAPHICS
30 GOSUB 2000: REM DRAW_AXIS
40 REM PLOT FUNCTION
50 FOR X=0 TO 319
60   Y=79-70*SIN((X-160)*90/80*3.14/180)
70   IF Y<0 OR Y>159 THEN GOTO 90
80   PSET (X,Y), 2
90 NEXT X
999 STOP
1000 REM
1010 REM SET GRAPHICS MODE
1020 REM
1030 SCREEN 9
1060 RETURN
2000 REM
2010 REM DRAW AXIS
2020 REM
2040 LINE (160,0)-(160,159)
2050 LINE (0,80)-(319,80)
2060 RETURN
Poznámka: povšimněte si způsobu zápisu souřadnic pixelů v PSET i koncových bodů úsečky v LINE.

Další demonstrační příklad používá režim s šestnácti barvami a rozlišením 640×350 (EGA) pro zobrazení moaré. Mj. je zde použit operátor pro dělení modulo:

1 REM *****************************
2 REM Circle moire
3 REM v grafickem rezimu 7 (16 barev)
4 REM
5 REM Uprava pro GW-BASIC
6 REM
7 REM *****************************
8 REM
9 REM
10 SCREEN 7
20 FOR Y=0 TO 349
30 FOR X=0 TO 639
40 C=INT(X*X/40+Y*Y/40)
50 PSET (X, Y), C MOD 16
80 NEXT X
90 NEXT Y
999 END

A konečně v posledním graficky orientovaném příkladu se používá přímý přístup do obrazové paměti, který je mnohem rychlejší, než volání příkazu PSET. Nejprve je nutné nastavit segment obrazové paměti, což je pro kartu EGA adresa 0×a000(0) a poté použít slavný příkaz POKE pro zápis do paměti v rámci tohoto segmentu:

1 REM *****************************
2 REM Vyplneni obrazovky nahodnym
3 REM vzorem v rezimu SCREEN 9
4 REM
5 REM Uprava pro GW-BASIC
6 REM
7 REM *****************************
8 REM
9 REM
10 SCREEN 9
20 DEF SEG = &hA000
30 FINAL=640*350/8
40 FOR I=0 TO FINAL
50 POKE I,255*RND(1)
60 NEXT I
999 END
Poznámka: podobně je možné využít grafické režimy karty VGA v QBasicu.

10. Dobré stránky GW-BASICu

GW-BASICu sice můžeme vytknout celou řadu problematických rysů (budeme o nich ostatně mluvit ve čtrnácté kapitole), ovšem na druhou stranu obsahuje i zajímavé vlastnosti a řeší některé problémy starších BASICů. Například relativně velké množství interpretrů BASICu ignoruje mezery mezi klíčovými slovy, hodnotami a proměnnými. To může vést k problémům, protože například proměnné začínající stejně jako klíčové slovo, budou zpracovány špatně, tedy jako příkaz, za nímž následuje nějaký výraz:

1 REM *****************************
2 REM Jmeno promenne zacinajici na
3 REM slovo PRINT
4 REM
5 REM Uprava pro GW-BASIC
6 REM
7 REM *****************************
8 REM
9 REM
10 ED=42
20 PRINTED=0
30 PRINTED=42
999 END
Poznámka: mnohé BASICy tento problém „řeší“ jednoduše – povolují jen jednopísmenné názvy proměnných :-)

Dalším výhodným rysem GW-BASICu a ostatně i většiny interpretrů BASICu vyvinutých společností Microsoft, je podpora polí s větším počtem dimenzí. Připomeňme si, že mnohé jednodušší dialekty BASICu podporovaly jednorozměrná či dvourozměrná pole s číselnými hodnotami (tedy vlastně vektory a matice) a řetězce považované za jednorozměrná pole znaků. Naproti tomu v GW-BASICu mohly mít pole libovolný typ a teoretický počet dimenzí byl omezen na 255 (takže vlastně neomezen, když vezmeme v úvahu pouze cca 60kB dostupné RAM). Ovšem s touto vlastností souvisí i odlišný přístup k podřetězcům, neboť například „atarácký“ zápis A$(od, do) není možné použít – znamená něco jiného, totiž přístup do dvourozměrného znakového pole. Namísto toho jsou dostupné funkce LEFT$, RIGHT$ a MID$, které v Microsoftích interpretrech přežily pravděpodobně až do současnosti:

1 REM *****************************
2 REM Prace s retezci, manipulace
3 REM s obsahem retezcu.
4 REM
5 REM Uprava pro GW-BASIC
6 REM
7 REM *****************************
8 REM
9 REM
30 A$="HELLO WORLD!"
40 PRINT A$
50 PRINT LEFT$(A$, 5)
60 PRINT RIGHT$(A$, 6)
70 PRINT MID$(A$, 7, 5)
999 END

A konečně – GW-BASIC pracuje se svými příkazy poměrně volným stylem, na rozdíl od C či Pascalu, kde se striktně rozlišuje jazyková konstrukce od volání procedury či funkce. To například umožňuje, aby existoval příkaz SWAP pro prohození obsahu dvou proměnných – a to bez toho, aby se do jazyka zaváděly reference či ukazatele:

1 REM *****************************
2 REM Prikaz SWAP pro prohozeni
3 REM obsahu dvou promennych.
4 REM
5 REM Uprava pro GW-BASIC
6 REM
7 REM *****************************
8 REM
9 REM
10 A$="FOO "
20 B$="BAR "
30 C$="BAZ "
40 PRINT A$ C$ B$
50 SWAP A$, B$
60 PRINT A$ C$ B$
999 END

11. Reakce na (asynchronní) události

Některé rysy GW-BASICu jsou velmi nízkoúrovňové a dokonce se tento programovací jazyk z určitého pohledu nachází až pod assemblerem (pouze globální proměnné atd.). Na druhou stranu zde však nalezneme vysokoúrovňové a na dobu vzniku elegantní jazykové konstrukce. Jedna z těchto konstrukcí slouží pro naprogramování reakce při vzniku nějaké asynchronní události. Tato konstrukce začíná slovem ON, za kterým následuje typ události a poté buď příkaz skoku GOTO nebo skoku do podprogramu GOSUB.

Příkladem může být reakce na vznik chyby v programu, tedy konstrukce, která se v jiných BASICech řeší příkazem TRAP a v některých moderních programovacích jazycích konstrukcí try-catch. Při vzniku chyby se automaticky naplní proměnné ERL a ERR na číslo řádku a číslo (kód) chyby:

1 REM *****************************
2 REM Ukázka reakce na chybu
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 ON ERROR GOTO 1000
11 A = 10
12 PRINT A/0
999 END
1000 REM
1001 REM error handler
1002 REM
1003 PRINT "Chyba na radku:"; ERL
1004 PRINT "Kod chyby:"; ERR
1005 RESUME NEXT

Zajímavější je reakce na „tik“ časovače, přičemž frekvence tiků je zadána v sekundách (časovač je navíc nutné povolit). V následujícím programu je handler na řádku 1000 volán pravidelně každou sekundu:

1 REM *****************************
2 REM Ukázka handleru udalosti
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 ON TIMER(1) GOSUB 1000
20 PRINT "Waiting for timer ticks..."
30 TIMER ON
40 GOTO 30
999 END
1000 REM
1001 REM handler
1002 REM
1003 PRINT "tick"
1004 RETURN

Reagovat je možné i na stisk klávesy, popř. na stisk kombinace přeřaďovače (Alt, Shift, Ctrl) a klávesy. Zde konkrétně reagujeme na stisk klávesy Esc:

1 REM *****************************
2 REM Ukázka handleru klavesnice
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 KEY 15, CHR$(0) + CHR$(1)
20 ON KEY(15) GOSUB 1000
30 PRINT "Waiting for user input..."
40 KEY (15) ON
50 GOTO 50
999 END
1000 REM
1001 REM handler
1002 REM
1003 PRINT "stlacena klavesa Esc"
1004 RETURN
Poznámka: prvních 15 kláves lze taktéž změnit, ovšem tím se modifikuje chování celého prostředí GW-BASICu.

A konečně se podívejme na demonstrační příklad s několika paralelně zpracovanými handlery – pro časovač i pro stisknutou klávesu:

1 REM *****************************
2 REM Ukázka pouziti vice handleru
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 KEY 15, CHR$(0) + CHR$(1)
20 ON KEY(15) GOSUB 1000
30 ON TIMER(1) GOSUB 2000
40 PRINT "Waiting for user input and timer ticks..."
50 TIMER ON
80 KEY (15) ON
90 GOTO 90
999 END
1000 REM
1001 REM prvni handler
1002 REM
1003 PRINT "stlacena klavesa Esc"
1004 RETURN
2000 REM
2001 REM druhy handler
2002 REM
2003 PRINT "tick"
2004 RETURN

12. Doménově specifické podjazyky – příkazy DRAWPLAY

GW-BASICu dokonce nalezneme i dvojici doménově specifických podjazyků, které mají praktické použití a jsou specifické pro interpretry Microsoftu. Prvním z těchto DSL je Graphics Macro Language (GML) použitý v příkazu DRAW. V tomto jazyku lze jednopísmennými příkazy doplněnými o parametry vykreslit různé tvary. Mezi podporované příkazy patří například U (up), H (diagonally up and left), N (move), C (color) atd.

Výsledek je tak podobný doménově specifickému jazyku použitému v SVG pro specifikaci cest, popř. jazyku HPGL/PLT, který byl použit pro ovládání plotterů i pro přenos vektorové grafiky mezi různými systémy:

1 REM *****************************
2 REM Příkaz DRAW
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 SCREEN 1
20 A=20
30 DRAW "U=A; R=A; D=A; L=A;"
999 END

Další příklad DSL příkazu DRAW:

1 REM *****************************
2 REM Příkaz DRAW
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 CLS
20 SCREEN 1
30 PSET (60, 125)
40 DRAW "E100; F100; L199"
999 END

Podobný doménově specifický jazyk je využitý příkazem PLAY pro přehrání melodie. Tento jazyk umožňuje zápis not, specifikaci oktávy, spuštění hudby na pozadí (!), modifikaci délky tónů atd. Následuje velmi jednoduchý příklad použití tohoto jazyka:

1 REM *****************************
2 REM Příkaz PLAY
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 PLAY "EDCDEEE2DFEDC"
999 END

13. Definice uživatelských funkcí, přiřazení typu proměnným na základě jejich jména

GW-BASIC, na rozdíl od většiny vyšších programovacích jazyků, neumožňuje deklaraci plnohodnotných uživatelských funkcí a procedur. Namísto toho existuje pouze možnost deklarace jména pro jediný výraz (což je vlastně obdoba lambdy). Tímto způsobem je možné zapsat jednoduché funkce, v nichž se nevyskytují sekvence příkazů, smyčky ani rozhodovací konstrukce:

1 REM *****************************
2 REM Definice nové funkce
3 REM s voláním této funkce.
4 REM
5 REM Uprava pro GW-BASIC
6 REM
7 REM *****************************
8 REM
9 REM
30 DEF FN AVG(X,Y)=(X+Y)/2
40 FOR I=0 TO 10
50 PRINT FN AVG(0,I)
60 NEXT I
999 END
Poznámka: zde není Microsoft kompatibilní sám se sebou, protože některé jiné BASICy od Microsoftu nevyžadovaly explicitní použití FN na řádku 50.

O postfixových znacích, které určují typ proměnné ($ pro řetězce atd.) jsme si již řekli v předchozím textu. GW-BASIC navíc ještě umožňuje tyto postfixy vynechat v případě, že určíme, které proměnné (z abecedního rozsahu) budou jakého typu. Příkladem je použití deklarace DEFINT, kterou určíme, že například proměnné I, J, K, L, M a N budou typu celé číslo, a to bez použití postfixu:

1 REM *****************************
2 REM Použití specifikace DEF INT
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 DEFINT I-N
20 I=20
30 PRINT I
40 J!=20
50 PRINT J!
999 END

Podobně lze určit, že proměnné A až F budou typu řetězec:

1 REM *****************************
2 REM Použití specifikace DEF STR
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 DEFSTR A-F
20 A="Foo bar"
30 PRINT A
40 B=20
50 PRINT B
999 END
Poznámka: stále je však možné postfixový znak použít – v tomto případě bude mít přednost před deklaracemi DEFINT, DEFSTR atd.

14. Inherentní omezení GW-BASICu

I přes některé zajímavé vlastnosti GW-BASICu v tomto jazyku nalezneme i mnohá inherentní omezení, která prakticky znemožňují jeho použití pro větší projekty. Některá z těchto omezení jsou teoreticky snadno řešitelná. Například se jedná o omezení na maximální velikost kódu 64kB, což je relativně snadno řešitelná problematika. Ovšem samotný návrh jazyka znemožňuje jeho použití pro složitější programový kód, a to zejména z těchto důvodů:

  1. Nelze vytvářet uživatelsky definované datové typy
  2. Program nelze strukturovat do menších celků – procedur a funkcí (jen lze vytvořit jednovýrazové funkce)
  3. Podobně neexistuje možnost specifikace modulů, ideálně s vlastním jmenným prostorem
  4. Není řešena viditelnost proměnných, takže i teoretické strukturování do podprogramů má své zásadní limity
  5. Velmi omezeny jsou taktéž možnosti rekurze – sice jsou řešitelné, ale programově, nikoli na úrovni jazyka

Přitom řešení prakticky všech výše uvedených problémů je popsáno ve slavné knize Algorithms + Data Structures = Programs, kterou Niklaus Wirth napsal již v roce 1976. Do BASICu se (na rozdíl od C, Pascalu a Moduly) tyto novinky (nebo spíš „novinky“) dostaly až v QBasicu, což je ideový pokračovatel GW-BASICu.

Příklad definice procedury v QBasicu (odpovídá proceduře v Pascalu nebo funkci bez návratové hodnoty v C):

SUB globalname[parameterlist][STATIC]
        [statements]
[EXIT SUB]
        [statements]
END SUB

Příklad definice funkce:

FUNCTION name [parameterlist][STATIC]
        [statements]
        name = expression
        [statements]
END FUNCTION

A konečně příklad definice vlastního datového typu v QBasicu:

TYPE Card
        Suit AS STRING * 9
        Value AS INTEGER
END TYPE

Mezi další nepříjemné vlastnosti GW-BASICu patří některé přepínače, které globálně mění chování interpretru. Týká se to především přepínače OPTION BASE, jímž se určuje dolní mez indexů polí:

1 REM *****************************
2 REM Použití přepínače OPTION BASE
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 OPTION BASE 0
15 DIM A(10)
20 FOR I=0 TO 10
30 A(I)=10*I
40 NEXT I
50 REM TISK POLE
60 FOR I=0 TO 10
70 PRINT A(I)
80 NEXT I
999 END

Druhý příklad, kdy je dolní index pole nastaven na jedničku:

1 REM *****************************
2 REM Použití přepínače OPTION BASE
3 REM
4 REM Uprava pro GW-BASIC
5 REM
6 REM *****************************
7 REM
8 REM
9 REM
10 OPTION BASE 1
15 DIM A(10)
20 FOR I=1 TO 10
30 A(I)=10*I
40 NEXT I
50 REM TISK POLE
60 FOR I=1 TO 10
70 PRINT A(I)
80 NEXT I
999 END
Poznámka: na první pohled se může jednat o užitečnou vlastnost (a pro malé programy skutečně je velmi užitečná), ovšem prakticky znemožňuje použití a porozumění knihovnám či částem kódu napsaných jinými programátory s odlišným nastavením.

15. Moderní náhrada GW-BASICu – PC-BASIC

Klasický GW-BASIC je možné provozovat i dnes v DOSBoxu. Jeho kód byl totiž zveřejněný pod licencí MIT, takže ho lze přeložit a používat (samotný kód je v assembleru, což pochopitelně překlad komplikuje). Alternativně je ovšem možné využít projekt nazvaný PC-BASIC, což je reimplementace GW-BASICu s využitím Pythonu a dalších podpůrných knihoven. Tento zajímavý projekt naleznete na adrese https://robhagemans.github­.io/pcbasic/. PC-BASIC se snaží být kompatibilní i na úrovni chyb, které GW-BASIC má. Podporuje i binární soubory s tokenizovaným kódem, takže lze (teoreticky) obnovit i staré programy. Kromě plné kompatibility s GW-BASICem je zaručena kompatibilita s BASICA (pro původní IBM PC), Tandy 1000 BASIC aj.

Pochopitelně je emulován i grafický subsystém IBM PC – lze dokonce zvolit, která grafická karta má být emulována. Kromě plné emulace vzhledu textového režimu IBM PC lze PC-BASIC spustit v běžném linuxovém terminálu, ovšem v tomto případě nebudou funkční grafické režimy.

16. Instalace PC-BASICu

Instalace PC-BASICu může být snadná v případě, že je tento balíček součástí repositářů vaší distribuce Linuxu. V takovém případě je instalace triviální a může vypadat následovně:

$ sudo apt-get install python3-pcbasic
 
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  libblas3 libgfortran5 liblapack3 python3-numpy python3-parallel
  python3-serial
Suggested packages:
  gfortran python-numpy-doc python3-pytest python3-numpy-dbg
  python-pcbasic-doc python3-wxgtk3.0 | python3-wxgtk
The following NEW packages will be installed:
  libblas3 libgfortran5 liblapack3 python3-numpy python3-parallel
  python3-pcbasic python3-serial
0 upgraded, 7 newly installed, 0 to remove and 4 not upgraded.
Need to get 6 908 kB of archives.
After this operation, 32,5 MB of additional disk space will be used.
Do you want to continue? [Y/n]
Poznámka: povšimněte si paradoxu současného IT. Emulace interpretru programovacího jazyka GW-BASIC, jehož (jediný) spustitelný soubor měl velikost přibližně 80 kilobajtů (a běžel v operačním systému o velikosti zhruba 60 kB), zabere celých 32,5 MB – a to nepočítáme fakt, že ke své plné funkci vyžaduje interpret Pythonu (zhruba 5,5 MB), glibc, knihovny systému X, jádro operačního systému atd.

Pro další operační systému jsou připravené balíčky, které lze nalézt na adrese http://robhagemans.github­.io/pcbasic/download.html (mimochodem si povšimněte dobového fontu i designu celé stránky).

17. Ukázky použití PC-BASICu

PC-BASIC je navržen jako klasický interpret s editorem, tedy bez integrovaného vývojového prostředí (neboli vypadá stejně, jako původní GW-BASIC). Při spuštění interpretru se specifikuje jméno zdrojového souboru, který se má zpracovat. Kromě toho je možné nastavit nativní rozlišení (nebude se provádět zvětšení nebo zmenšení), popř. specifikovat, že se má použít přímo konzola (terminál) a nikoli emulace grafických možností IBM PC:

Obrázek 4: Až na první dva řádky je prostředí i chování PC-BASICu prakticky shodné s GW-BASICem.

Obrázek 5: Spuštění PC-Basicu v linuxovém terminálu.

Obrázek 6: Spuštění v režimu mapování pixelů v poměru 1:1.

V případě chyby ve vlastním PC-BASICu je zobrazena tato BSOD:

Obrázek 7: BSOD s chybou při běhu PC-BASICu.

18. Od GW-BASICu ke QBasicu

Jedním z nejznámějších a pravděpodobně i nejpoužívanějších dialektů programovacího jazyka BASIC na osobních počítačích kompatibilních s IBM PC je bezesporu QBasic firmy Microsoft, která tento BASIC začala dodávat společně s MS DOSem 5.0 (kde nahradil GW-BASIC z předchozích verzí DOSu) a později byl dostupný například i pro operační systémy Windows 95 a jako jedna z přídavných utilit i pro Windows NT. Jedná se, na rozdíl od podobně pojmenovaného QuickBASICu, o interpret BASICu, což znamená, že programy se nepřekládaly do strojového kódu, ale „pouze“ byly prováděny interpretrem, se všemi přednostmi ale i zápory tohoto řešení. Mezi přednosti patřilo především to, že QBasic po svém spuštění prakticky nepotřeboval přistupovat k paměťovému zařízení (disketové jednotce, pevnému disku), což mělo velký význam především tehdy, pokud byl počítač vybaven pomalejším pevným diskem (psala se doba PC AT a disků s kapacitami typicky 20 MB, 40 MB a 80 MB, diskovou cache bylo možné zapnout, ale na úkor volné kapacity RAM). Taktéž spuštění či znovuspuštění programu bylo takřka okamžité, protože odpadl čas potřebný pro překlad zdrojového textu do strojového kódu mikroprocesoru.

Obrázek 8: Úvodní zpráva zobrazená po spuštění QBasicu.

Na druhou stranu bylo provádění programů nepoměrně pomalejší než kdyby došlo k jejich překladu před spuštěním, takže se zde opět ukázal klasický rozpor mezi interpretry a překladači. QBasic taktéž programátorům kladl některá omezení, která vyplývala například z toho, že interpret běžel, ostatně jako celý MS DOS, v reálném (popř. virtuálním) režimu mikroprocesoru 80×86, což mj. znamenalo, že operační paměť byla rozdělena na segmenty o velikosti 64 kB. Právě kvůli segmentování paměti byla omezena například velikost polí, maximální délka řetězců ale i celková velikost všech globálních proměnných. Posledním záporem QBasicu byl nedostatečný rozsah základních knihoven dodávaných k tomuto jazyku (například v porovnání s tehdy velmi populárním Turbo Pascalem nebo konkurenčním GFA BASICem). QBasic nabízel základní operace pro práci se soubory, grafickými režimy dostupnými přes BIOS (ovšem nikoli režimy VESA) a taktéž procedury pro ovládání PC Speakeru (reproduktoru zapojeného na jednobitový výstup obvodu 8253). Některá z omezení byla diktována snahou o zpětnou kompatibilitu s GW-BASICem.

Obrázek 9: Ve vývojovém prostředí QBasicu je zabudované i okno s nápovědou.

Poznámka: rozpor mezi interpretry a překladači částečně překlenul Turbo Pascal s překladačem, který byl na dobu vzniku (a použitý hardware) až neskutečně rychlý, čímž se smazala jedna z nevýhod překladače. Z novějších jazyků touto vlastností vyniká zejména jazyk Go.

V předchozím textu jsme se zmínili o nedostatečně vybavené základní knihovně QBasicu. Prakticky žádné další procedury ani funkce kromě těch zmíněných výše nebyly ve standardní knihovně dostupné, takže se není čemu divit, že se postupně začaly objevovat například sady procedur pro práci s myší, ovládání pamětí EMS a XMS, knihovny pro tvorbu uživatelského rozhraní v textovém režimu podobné Turbo Vision atd. Nicméně QBasic měl kromě svých záporů (a těch bylo relativně velké množství) i mnoho předností. První a možná i nejdůležitější předností tohoto jazyka bylo to, že byl nainstalován prakticky na jakémkoli počítači s MS DOSem 5.0 či některém pozdějším operačním systému firmy Microsoft, včetně již zmíněných Windows NT. To s sebou přinášelo poměrně mnoho výhod, protože bylo možné distribuovat programy přímo ve zdrojovém kódu s poměrně velkou jistotou, že je cíloví uživatelé budou moci spustit (mezitím se na Linuxu úspěšně rozšiřoval Perl a s menší razancí i Python, Tcl atd. ostatně i Linux oslaví třicátiny).

Poznámka: jedná se tedy o stejnou strategii, jako v případě GW-BASICu.

Obrázek 10: Dobová a velmi dobře známá hra Gorily spuštěná pomocí interpretru QBasicu.

Společně s QBasicem bylo dodáváno i několik programů, z nichž nejpopulárnější byly hry Gorillas (jednodušší variace na známé hry Tank Wars či Scorched Earth) a Nibbles (starodávná hra, která byla později zpopularizovaná podobnou hrou určenou pro mobilní telefony Nokia). Právě díky přítomnosti QBasicu na prakticky každém počítači s MS DOSem či Windows bylo možné tyto hry spouštět i na těch počítačích o nichž jejich uživatelé/administrátoři tvrdili, že na nich žádné hry nebyly a nejsou (kanceláře, školy :-)

Obrázek 11: Profesionální alternativou ke QBasicu je či lépe řečeno byl QuickBasic vybavený lepším debuggerem, překladačem atd.

Další předností QBasicu bylo jednoduše ovladatelné a velmi snadno použitelné vývojové prostředí (některé chyby byly odhaleny již po přechodu na předchozí či následující textový řádek, programy bylo možné krokovat atd.). Poslední kladnou vlastností QBasicu byla jeho syntaxe a sémantika, která byla již v prakticky všech ohledech odlišná od původních BASICů „staré školy“. To mj. znamenalo, že v QBasicu se programy zapisovaly strukturovaně, tj. bez nutnosti používat čísla řádků a s nimi souvisejícího příkazu GOTO, který však zůstal kvůli zpětné kompatibilitě zachován. Dále byly podporovány funkce a procedury s parametry a lokálními proměnnými (navíc se zdrojové kódy funkcí editovaly odděleně, takže nedošlo k jejich nechtěnému promíchání) a všechny proměnné i parametry mohly mít přidělen datový typ. Výsledné programy se tedy svojí strukturou podobaly spíše programům zapisovaným v Pascalu nežli programům v klasickém BASICu (totéž ostatně platí pro GFA BASIC, ovšem nikoli pro výše popsaný GW-BASIC).

Poznámka: většina dobových „moderních“ BASICů se držela tohoto pojmenování spíše z komerčních důvodů, než kvůli podobě s původním BASICem.

Obrázek 12: Editor s otevřeným programem pro výpočet Mandelbrotovy množiny.

Pro ilustraci způsobu zápisu programů následuje ukázka jednoduché aplikace pro (relativně pomalý) výpočet Mandelbrotovy množiny, která byla odladěna v QBasicu v DOSBOXu (povšimněte si určování typu proměnných s využitím speciálního znaku umístěného za jejich jménem – viz též sedmou kapitolu):

Root školení Linux

SCREEN 13
cy! = -1.5
FOR j% = 0 TO 199
    cx! = -2.5
    FOR i% = 0 TO 319
        iter% = 0
        zx! = 0: zy! = 0
        zx2! = 0: zy2! = 0
        DO
            zx2! = zx! * zx!
            zy2! = zy! * zy!
            zy! = 2! * zx! * zy! + cy!
            zx! = zx2! - zy2! + cx!
            iter% = iter% + 1
        LOOP WHILE iter% < 100 AND zx2! + zy2! < 4!
        PSET (i%, j%), iter%
        cx! = cx! + 4! / 320
    NEXT i%
    cy! = cy! + 3! / 200
NEXT j%
Poznámka: až na některé „podivnosti“ typu parametrů procedury PSET se jedná o relativně dobře čitelný strukturovaný programový kód.

Obrázek 13: Výsledek běhu demonstračního příkladu.

19. Repositář s demonstračními příklady

Všechny dnes popisované demonstrační příklady určené pro GW-BASIC i pro PC-BASIC (ovšem kompatibilní i s QBasicem) byly uloženy do Git repositáře, který je dostupný na adrese https://github.com/tisnik/8bit-fame. Příklady si můžete v případě potřeby stáhnout i jednotlivě bez nutnosti klonovat celý (dnes již poměrně rozsáhlý) repositář:

Příklad Stručný popis Adresa
1d_array.bas Práce s jednodimenzionálním polem (vektorem) https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/1d_array.bas
2d_array.bas Práce s dvoudimenzionálním polem (maticí) https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/2d_array.bas
bubble_sort.bas Implementace algoritmu bublinkového řazení https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/bubble_sort.bas
def_func.bas Definice nové funkce, zavolání této funkce https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/def_func.bas
def_int.bas Definice jmen proměnných typu int (celé číslo) https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/def_int.bas
def_str.bas Definice jmen proměnných typu string (řetězec) https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/def_str.bas
draw1.bas Kreslení obrazců příkazem DRAW https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/draw1.bas
draw2.bas Kreslení obrazců příkazem DRAW https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/draw2.bas
factorial.bas Výpočet faktoriálu https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/factorial.bas
for_next_basic.bas Základní použití programové smyčky FOR-NEXT https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/for_next_basic.bas
for_next_illegal.bas Smyčka FOR-NEXT, která by neměla proběhnout ani jedenkrát https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/for_next_illegal.bas
for_next_max_variable.bas Horní hranice ve smyčce FOR-NEXT určená proměnnou, jejíž hodnota se mění https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/for_next_max_variable.bas
for_next_step.bas Smyčka FOR-NEXT s explicitní hodnotou kroku https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/for_next_step.bas
for_next_step_variable.bas Smyčka FOR-NEXT, v níž je hodnota kroku určena proměnnou https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/for_next_step_variable.bas
function_sin_plot.bas Vykreslení průběhu funkce sinus v grafickém režimu https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/function_sin_plot.bas
GCD.bas Výpočet největšího společného dělitele založený na nestrukturovaném příkazu GOTO https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/GCD.bas
harmonic.bas Test přesnosti výpočtů FP hodnot https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/harmonic.bas
moire.bas Moiré (vzorek) vykreslený v grafickém režimu https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/moire.bas
on_gosub1.bas Rozeskok typu ON-GOSUB https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/on_gosub1.bas
on_gosub2.bas Rozeskok typu ON-GOSUB https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/on_gosub2.bas
on_goto.bas Rozeskok typu ON-GOTO https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/on_goto.bas
on_key.bas Reakce na události – stisk klávesy https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/on_key.bas
on_timer.bas Reakce na události – tik časovače https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/on_timer.bas
on_key_and_timer.bas Reakce na události – časovač a/nebo stisk klávesy https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/on_key_and_timer.bas
option_base0.bas Příkaz OPTION BASE pro určení dolního indexu polí https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/option_base0.bas
option_base1.bas Příkaz OPTION BASE pro určení dolního indexu polí https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/option_base1.bas
PI.bas Výpočet konstanty Pi iterativním výpočtem https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/PI.bas
play1.bas Přehrání hudby příkazem PLAY https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/play1.bas
print1.bas Základní použití příkazu PRINT https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/print1.bas
print2.bas Další možnosti použití příkazu PRINT https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/print2.bas
printed1.bas Proměnné, které začínají jménem příkazu PRINT https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/printed1.bas
printed2.bas Proměnné, které začínají jménem příkazu PRINT https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/printed2.bas
print_using1.bas Použití příkazu PRINT USING pro formátovaný výstup https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/print_using1.bas
print_using2.bas Použití příkazu PRINT USING pro formátovaný výstup https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/print_using2.bas
print_using3.bas Použití příkazu PRINT USING pro formátovaný výstup https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/print_using3.bas
rem_statement.bas Příkaz REM zkrácený na apostrof https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/rem_statement.bas
snowcrash.bas Vykreslení náhodného vzorku na obrazovku, přímý přístup do obrazové paměti https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/snowcrash.bas
sort.bas Třídicí algoritmus, první verze https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/sort.bas
sort_int.bas Třídicí algoritmus, úprava pro celá čísla https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/sort_int.bas
sort_int_int.bas Třídicí algoritmus, úprava pro celá čísla https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/sort_int_int.bas
sort_int_int_lowercase.bas Třídicí algoritmus zapsaný malými písmeny https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/sort_int_int_lowercase.bas
sort_int_lowercase.bas Třídicí algoritmus zapsaný malými písmeny https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/sort_int_lowercase.bas
statement_trap.bas Zachycení chyby příkazem ON ERROR (jinde TRAP) https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/statement_trap.bas
strings.bas Operace s řetězci https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/strings.bas
swap.bas Prohození obsahu dvou proměnných příkazem SWAP https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/swap.bas
while_GCD.bas Výpočet největšího společného dělitele, využití smyčky WHILE-WEND https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/while_GCD.bas
while_wend1.bas Základní použití smyčky WHILE-WEND https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/while_wend1.bas
while_wend2.bas Další příklady použití smyčky WHILE-WEND https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/while_wend2.bas
while_wend3.bas Další příklady použití smyčky WHILE-WEND https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/while_wend3.bas
while_wend_pi.bas Výpočet konstanty Pi, jsou zde použity smyčky WHILE-WEND https://github.com/tisnik/8bit-fame/blob/master/GW-BASIC/while_wend_pi.bas

20. Odkazy na Internetu

  1. Fifty Years of BASIC, the Programming Language That Made Computers Personal
    https://time.com/69316/basic/
  2. BBC BASIC i QBasic oslavují svá kulatá výročí
    https://www.root.cz/clanky/bbc-basic-i-qbasic-oslavuji-sva-kulata-vyroci/
  3. What are the best BASIC-like programming languages?
    https://www.slant.co/topic­s/9807/~basic-like-programming-languages
  4. List of BASIC dialects
    https://en.wikipedia.org/wi­ki/List_of_BASIC_dialects
  5. GW-BASIC Documentation
    https://hwiegman.home.xs4a­ll.nl/gwbasic.html
  6. Microsoft Open-Sources GW-BASIC
    https://devblogs.microsof­t.com/commandline/microsoft-open-sources-gw-basic/
  7. GW-BASIC na GitHubu
    https://github.com/microsoft/GW-BASIC
  8. Welcome to GW-BASIC
    http://www.antonis.de/qbe­books/gwbasman/
  9. GWBASIC User's Manual
    http://www.antonis.de/qbe­books/gwbasman/index2.html
  10. The basics of BASIC, the programming language of the 1980s
    https://www.youtube.com/wat­ch?v=seM9SqTsRG4
  11. GW-BASIC User's Guide
    https://hwiegman.home.xs4all.nl/gw-man/index.html
  12. PC-BASIC 1.2.14 documentation
    http://robhagemans.github­.io/pcbasic/doc/1.2/
  13. PEEK and POKE
    https://en.wikipedia.org/wi­ki/PEEK_and_POKE
  14. GW-BASIC | DRAW Statement (video na Youtube)
    https://www.youtube.com/wat­ch?v=4I1CELY13M4
  15. Rozdíly mezi GW-BASIC a QBasicem
    https://hwiegman.home.xs4a­ll.nl/extern/Differences%20Bet­ween%20GW-BASIC%20and%20QBasic.htm
  16. GW-Basic Programs
    https://gwbasicprograms.blog­spot.com/p/gw-basic-programs.html
  17. GW-BASIC Resource
    https://gw-basic.netlify.app/
  18. A page about GWBASIC Games & Other Programs
    http://peyre.x10.mx/GWBASIC/
  19. Basic BASIC, 2nd Edition, James S. Coan
    https://drive.google.com/uc?ex­port=download&id=1Z12L7SO_gfNg3Ma_0­eH2_Kz15YM-9dHl
  20. Advanced BASIC, James S. Coan
    https://drive.google.com/uc?ex­port=download&id=1JafSpV_BLyl­WHMd16rDPorwv9wV9bLcy
  21. Structured BASIC, 2nd Edition, James F. Clark (naskenovaná kniha)
    https://drive.google.com/uc?ex­port=download&id=1pT8y-8yJYS_SqvxF0fBHm6S-dlAt-Uy2
  22. Last Book of GW-Basic
    https://www.geocities.ws/jo­seph_sixpack/btoc.html
  23. SCIENTIFIC PROGRAMS WRITTEN IN BASIC (for PCs)
    https://web.archive.org/web/20160323064356/htt­p://www.scn.org/~bh162/ba­sic_programs.html
  24. Why I love programming on FreeDOS with GW-BASIC
    https://opensource.com/ar­ticle/21/6/freedos-gw-basic
  25. Quite BASIC (web-based classic BASIC online programming environmen)
    http://www.quitebasic.com/
  26. GFA-BASIC
    http://sites.google.com/si­te/gfabasic16/
  27. E-mail od tvůrce GW-Basicu
    http://www.classiccmp.org/pi­permail/cctech/2005-April/042999.html
  28. General Electric GE-400
    http://www.feb-patrimoine.com/PROJET/ge400/ge-400.htm
  29. GE-400 Time-sharing information systems:
    http://www.computerhistory­.org/collections/accession/102646147
  30. A brief history of the development of BASIC (pravděpodobně již nefunkční odkaz)
    http://www.phys.uu.nl/~ber­gmann/history.html
  31. History of BASIC (PDF)
    http://www.q7basic.org/His­tory%20of%20BASIC.pdf
  32. Dartmouth College Computation Center. 1964.-The original Dartmouth BASIC manual
    http://www.bitsavers.org/pdf/dar­tmouth/BASIC_Oct64.pdf
  33. The Original BASIC
    http://www.truebasic.com/
  34. BASIC – Beginners All-purpose Symbolic Instruction Code
    http://hopl.murdoch.edu.au­/showlanguage.prx?exp=176
  35. The History of the Mainframe Computer
    http://www.vikingwaters.com/htmlpa­ges/MFHistory.htm
  36. Dartmouth Time Sharing System
    http://en.wikipedia.org/wi­ki/Dartmouth_Time_Sharing_Sys­tem
  37. General Electric (Wikipedia)
    http://en.wikipedia.org/wi­ki/General_Electric
  38. GE 225 vs. IBM 1401
    http://ed-thelen.org/GE225-IBM1401.html
  39. A GE-225 is found
    http://ed-thelen.org/comp-hist/GE225.html
  40. G.E. 200 Series Computers
    http://www.smecc.org/g_e__200_se­ries_computers.htm
  41. DTSS – Dartmouth Time Sharing System
    http://dtss.dartmouth.edu/index.php
  42. John G. Kemeny: BASIC and DTSS: Everyone a Programmer
    http://dtss.dartmouth.edu/e­veryoneaprogrammer.php
  43. GE-200 series (Wikipedia)
    http://en.wikipedia.org/wiki/GE-200_series
  44. GE-400 series (Wikipedia)
    http://en.wikipedia.org/wiki/GE-400_series
  45. GE-600 series (Wikipedia)
    http://en.wikipedia.org/wiki/GE-600_series
  46. ZX Basic Manual
    http://www.worldofspectrum­.org/ZXBasicManual/
  47. ZX81 BASIC Programming
    http://www.worldofspectrum­.org/ZX81BasicProgramming/
  48. Sinclair BASIC History
    http://scratchpad.wikia.com/wi­ki/Sinclair_BASIC_History
  49. Sinclair BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Sinclair_BASIC
  50. Sinclair BASIC (Wikipedia EN)
    http://en.wikipedia.org/wi­ki/Sinclair_BASIC
  51. Beta BASIC (Wikipedia EN)
    http://en.wikipedia.org/wi­ki/Beta_BASIC
  52. Beta BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Beta_BASIC
  53. BETA BASIC NEWSLETTER No 8
    http://spectrum128.ru/hel­p/BetaBasicNewsletter8.pdf
  54. R. T. RUSSELL: The home of BBC BASIC
    http://www.rtrussell.co.uk/
  55. R. T. RUSSELL: A History of BBC BASIC
    http://www.cix.co.uk/~rrus­sell/bbcbasic/history.html
  56. SuperBASIC (Wikipedia EN)
    http://en.wikipedia.org/wi­ki/SuperBASIC
  57. SuperBASIC (Wikipedia CZ)
    http://en.wikipedia.org/wi­ki/SuperBASIC
  58. Laser Basic/Laser Compiler
    http://www.sincuser.f9.co­.uk/049/laser.htm
  59. Laser BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Laser_BASIC
  60. BBC BASIC
    http://www.bbcbasic.co.uk/bbcba­sic.html
  61. BBC BASIC
    http://mdfs.net/Software/BBCBasic/
  62. BBC BASIC (Z80) for the ZX Spectrum
    http://mdfs.net/Software/BBCBa­sic/Spectrum/
  63. BBC BASIC (Wikipedia CZ)
    http://en.wikipedia.org/wi­ki/BBC_BASIC
  64. BeebWiki – 8-bit Acorn Computer Wiky
    http://beebwiki.jonripley­.com/Main_Page
  65. Porovnání osmibitů
    http://porovnani8bitu.spa­ces.live.com/
  66. Rosetta Code – Main Page
    http://rosettacode.org/wiki/Main_Page
  67. Rosetta Code – Category Basic
    http://rosettacode.org/wi­ki/Category:BASIC
  68. QBasicJedi
    http://www.freewebs.com/qbasicjedi/
  69. QBasic/QuickBasic Downloads
    http://www.freewebs.com/qba­sicjedi/qbdownloads.html
  70. QuickBASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/QuickBASIC
  71. QBasic.com
    http://www.qbasic.com/
  72. QBasic (Wikipedia)
    http://cs.wikipedia.org/wiki/QBasic
  73. Dialling with QBASIC
    http://www.mysundial.ca/tsp/qba­sic.html
  74. BASIC (Wikipedia EN)
    http://en.wikipedia.org/wiki/BASIC
  75. BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wiki/BASIC
  76. Turbo BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Turbo_BASIC
  77. More BASIC Computer Games
    http://www.atariarchives.or­g/morebasicgames/
  78. How to build an interpreter in Java, Part 1: The BASICs
    http://www.javaworld.com/jw-05–1997/jw-05-indepth.html
  79. INTEGER BASIC Reference
    http://www.landsnail.com/a2ref2.htm
  80. APPLESOFT Reference
    http://www.landsnail.com/a2ref.htm
  81. Applesoft Lite: Applesoft BASIC for the Replica-1
    http://cowgod.org/replica1/applesoft/
  82. Simons' BASIC
    http://en.wikipedia.org/wi­ki/Simons'_BASIC
  83. Simon's Basic
    http://www.lemon64.com/?ma­inurl=http%3A//www.lemon64­.com/museum/list.php%3Fli­neoffset%3D54%26genre%3Dma­nualmisc
  84. BASIC
    http://www.c64-wiki.com/index.php/BASIC
  85. C64 Wiki: Simons Basic
    http://www.c64-wiki.de/index.php/Simons_Basic
  86. Simons' Basic (evaluation)
    http://www.atarimagazines­.com/creative/v9n11/60_Si­mons_Basic.php
  87. Bill Gates' Personal Easter Eggs in 8 Bit BASIChttp://www.pagetable.com/?p=43
  88. Třicet let od vydání revolučního Turbo Pascalu 5.5
    https://www.root.cz/clanky/tricet-let-od-vydani-revolucniho-turbo-pascalu-5–5/
  89. Let's make a small and simple GW-BASIC program!
    https://www.youtube.com/wat­ch?v=OyPUn74nj-s