EndBASIC: moderní reinkarnace klasického jazyka BASIC

9. 5. 2024
Doba čtení: 29 minut

Sdílet

Autor: ccwoodcock, podle licence: CC-BY
Na úterní článek, v němž jsme se mj. věnovali i moderním reinkarnacím klasického jazyka BASIC dnes částečně navážeme. Ukážeme si některé možnosti a omezení EndBASICu, což je nový příspěvek do světa interpretrů BASICu.

Obsah

1. EndBASIC: moderní reinkarnace klasického BASICu

2. Specifické vlastnosti klasických BASICů

3. Přepis algoritmu do EndBASICu

4. Od špagetového kódu ke strukturovanému programování

5. GOTO a výpočet největšího společného dělitele

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

7. Počítaná programová smyčka FOR-NEXT

8. Smyčka typu WHILE-WEND s podmínkou na začátku

9. Výpočet konstanty π varianta s FOR-NEXTWHILE-WEND

10. Alokace polí

11. Řetězce

12. Data jako součást zdrojového kódu

13. Strukturovaný příkaz pro rozvětvení

14. Kombinace textové a grafické plochy

15. Ovládání textové konzole

16. Grafický výstup

17. Ukázky grafického výstupu

18. Závěrečné zhodnocení

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

20. Odkazy na Internetu

1. EndBASIC: moderní reinkarnace klasického BASICu

Na úterní článek, v němž jsme se mj. věnovali i moderním reinkarnacím klasického BASICu v podobě, v jaké si ho mnozí pamatujeme z dob kralování osmibitových domácích mikropočítačů, dnes částečně navážeme. Ukážeme si totiž některé možnosti, ale nutno dodat, že taktéž omezení EndBASICu, což je interpret BASICu naprogramovaný v Rustu. To je dosti neobvyklá kombinace technologií, protože původní BASICy byly psány většinou v čistém assembleru. EndBASIC se do jisté míry snaží napodobit chování klasických interpretrů BASICu, ovšem nabízí i některá vylepšení. Na druhou stranu však uvidíme, že některé jazykové konstrukce nejsou v EndBASICu povoleny nebo se chovají odlišně, což je škoda, protože se v mnoha ohledech jedná o poměrně zajímavý (nostalgický) projekt, který však není zpětně kompatibilní asi s žádným klasickým BASICem.

Obrázek 1: Online varianta EndBASICu.

EndBASIC si můžete stáhnout pro váš operační systém ze stránky https://www.endbasic.dev/ a spouštět ho lokálně. Aby vše pracovalo korektně, tedy i grafické příkazy, je nutné mít nainstalovánu knihovnu SDL2; bez ní sice bude EndBASIC funkční, ale bez grafického výstupu.

2. Specifické vlastnosti klasických BASICů

Ještě před vlastním popisem EndBASICu si krátce připomeňme, jak vlastně vypadaly programy psané pro interpretry BASICů běžících na osmibitových domácích mikropočítačích. Příkladem může být program pro seřazení prvků v poli pomalým a naivním algoritmem bublinkového řazení (bubble sort). Realizace tohoto programu v Atari BASICu může vypadat například následovně:

1 REM *****************************
2 REM Bubble sort
3 REM
4 REM Uprava pro Atari 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(0))
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 STOP
100 REM TISK OBSAHU POLE
101 FOR I=0 TO 20
102 PRINT I,A(I)
103 NEXT I
104 RETURN
998 REM finito
999 STOP

Povšimněte si několika faktů:

  • Čísla řádků jsou povinná
  • Všechny proměnné jsou globální a automaticky definované při prvním použití
  • Jedinými datovými typy jsou reálná čísla, řetězce (zde nepoužité) a 1D či 2D pole reálných čísel
  • Pole jsou indexována od nuly
  • Indexy prvků polí končí až stanoveného limitu (tedy v našem případě včetně 20)
  • Podmínka IF je nestrukturovaným příkazem platným do konce řádku (a nelze rozdělit na více řádků)
  • Jedinými strukturovanými příkazy je smyčka FOR-NEXT a dvojice příkazů GOSUBRETURN
  • Počítané smyčky mění počitadlo od dolní meze až do horní meze včetně (zde tedy při tisku pole od 0 do 20 včetně)

Výše uvedené chování při alokaci polí i při tvorbě počítané programové smyčky zamezuje mnoha typických chybám &plusm;1 (naproti tomu C a od něj odvozené jazyky se chovají odlišně a poněkud méně intuitivně).

Realizace téhož algoritmu, tentokrát v TurboBASICu XL (tedy pro stejnou platformu), je poněkud odlišná. Opět se nejdříve podívejme na zdrojový kód, který posléze krátce okomentujeme:

1 REM BUBBLE SORT
2 REM IMPLEMENTACE PRO TURBO-BASIC XL
3 REM
4 REM ----------------------------
5 REM
9 SIZE=20
10 DIM A(SIZE)
11 FOR I=0 TO SIZE
12   A(I)=RAND(100)
13 NEXT I
14 EXEC PRINT_ARRAY
20 FOR I=SIZE-1 TO 0 STEP -1
21   PRINT ".";
25   FOR J=0 TO I
30     IF A(J)<A(J+1)
31       X=A(J):A(J)=A(J+1):A(J+1)=X
32     ENDIF
35   NEXT J
40 NEXT I
49 PRINT ""
50 PRINT "SORTED:"
60 EXEC PRINT_ARRAY
99 END
100 ------------------------------
101 REM TISK OBSAHU POLE
102 PROC PRINT_ARRAY
103   FOR I=0 TO SIZE
104     PRINT I,A(I)
105   NEXT I
106 ENDPROC

Oproti původnímu kódu můžeme najít mnoho užitečných změn:

  • Strukturovaný kód je odsazen
  • Je podporován strukturovaný příkaz IF-(THEN)-ENDIF
  • Existuje zde podpora pro pojmenované procedury (podprogramy): PROC a ENDPROC
  • Je podporován „speciální komentář“ zobrazený jako řada ----------, ovšem interně reprezentovaný jediným tokenem

Další úprava byla provedena pro Microsoft BASIC. Jedná se o program, který je teoreticky nezávislý na HW (měl by běžet i na jiných strojích), ovšem kvůli použití HW časovače je zdrojový kód jako celek opět nepřenosný na jiné platformy. Důležitou změnou typickou právě pro Microsoft BASIC, je podpora celočíselného datového typu, který je použit tehdy, pokud se za jméno proměnné vloží znak procenta. Výsledný běh programu je díky tomu mnohonásobně rychlejší (někdy i řádově rychlejší) oproti použití reálných čísel (na HW bez matematického koprocesoru):

1 REM ********************************
2 REM Bubble sort pro pole typu single
3 REM
4 REM Uprava pro Microsoft BASIC
5 REM
6 REM ********************************
7 REM
8 REM
9 REM
10 REM VYMAZANI CASOVACE
11 POKE 18,0
12 POKE 19,0
13 POKE 20,0
20 REM VLASTNI BENCHMARK
21 MAX%=50
22 DIM A(MAX%)
23 FOR I%=0 TO MAX%
24 A(I%)=INT(100*RND(0))
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
41 REM (PLATNE PRO PAL)
42 T=((PEEK(18)*65536+PEEK(19)*256+PEEK(20))/50)
50 PRINT "FINISHED IN ";T;" SECONDS"
99 END
100 REM TISK OBSAHU POLE
101 FOR I%=0 TO MAX%
102 PRINT I%,A(I%)
103 NEXT I%
104 RETURN

V případě přepisu na slavné ZX Spectrum bylo nutné provést několik úprav. Především se to týká polí, které jsou indexovány od jedničky (u některých BASICů existuje volba indexování od 0 nebo od 1). Taktéž se funkce RND volá bez závorek a je nutné používat příkaz LET pro přiřazení:

Obrázek 2: Inicializace pole a tisk pole; realizace v BASICu pro ZX Spectrum (používám emulaci 128k a nikoli původního 48k vlastně jen z toho důvodu, protože můj notebook nemá na klávesnici napsané původní Sinclairovské příkazy :-).

Obrázek 3: Hlavní část algoritmu bublinkového řazení. Prohození hodnot jsem zde realizoval na více řádků kvůli větší čitelnosti.

Přecházíme na platformu IBM PC a slavný GW-BASIC. Úprava pro tento ve své době oblíbený dialekt BASICu může vypadat takto:

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

Opět si povšimněte odsazení strukturovaných příkazů (programové smyčky). Jinak se toto řešení do značné míry podobá TurboBASICu či Microsoft BASICu.

3. Přepis algoritmu do EndBASICu

Přímý přepis algoritmu bublinkového řazení do EndBASICu je, ač je to s podivem, relativně složitý, protože se změnila především sémantika některých operací (syntaxe taktéž, ovšem to lze poměrně snadno překonat). První změnou je fakt, že pole se alokují podobně jako v jazycích odvozených od céčka: specifikuje se kapacita pole a nikoli index posledního prvku (kapacita tedy musí být o jedničku vyšší). Dále se používají strukturované podmínky if-then-end if a u počítaných programových smyček for se u klíčového slova next nesmí použít jméno proměnné (to je podle mého názoru škoda, byla to skvělá kontrola korektnosti zápisu). A navíc je možné namísto čísel řádků používat pojmenovaná návěští, podobně jako v mnoha dalších programovacích jazycích i v assemblerech:

rem *****************************
rem Algoritmus bubble sort
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
dim a(21)
 
for i=0 to 20
  a(i)=int(100*rnd(1))
next
 
gosub @PRINT_ARRAY
 
for i=19 to 0 step -1
  print ".";
  for j=0 to i
    if a(j)<a(j+1) then
        x=a(j)
        a(j)=a(j+1)
        a(j+1)=x
    end if
  next
next
print ""
print "sorted:"
 
gosub @PRINT_ARRAY
end
 
@PRINT_ARRAY
rem Tisk obsahu pole
for i=0 to 20
  print i,a(i)
next
return
Poznámka: takto realizovaný program by měl být dobře čitelný i pro programátory, kteří BASIC neznají. V určitých ohledech je čitelnější než Python :-), například se to týká realizace počítaných programových smyček.

Výsledky získané tímto programem:

 0             90
 1             55
 2             54
 3             17
 4             90
 5             16
 6             10
 7             55
 8             62
 9             25
 10            46
 11            29
 12            10
 13            45
 14            78
 15            91
 16            32
 17            86
 18            73
 19            14
 20            41
....................
sorted:
 0             91
 1             90
 2             90
 3             86
 4             78
 5             73
 6             62
 7             55
 8             55
 9             54
 10            46
 11            45
 12            41
 13            32
 14            29
 15            25
 16            17
 17            16
 18            14
 19            10
 20            10

4. Od špagetového kódu ke strukturovanému programování

V klasických interpretrech BASICu se striktně používala čísla řádků (jen tak se daly odlišit přímé příkazy od zápisu programu), nestrukturované jazykové konstrukce založené na příkazu GOTO a globální proměnné. Mnohdy ani nebylo možné definovat vlastní procedury nebo funkce. EndBASIC 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). EndBASIC čísla řádků podporuje (ale nevyžaduje) a podporuje i původní sémantiku příkazu GOTO:

Použití čísel řádků a příkazu GOTO pro skok na konkrétní řádek:

rem *****************************
rem
rem Klasický příkaz GOTO s čísly
rem řádků
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
10 print "hello"
20 goto 10

Namísto čísel řádků je možné použít pojmenované návěští, což jsme si již ostatně ukázali na příkladu algoritmu bublinkového řazení. Specialitou EndBASICu je, že návěští musí začínat znakem @:

rem *****************************
rem
rem Příkaz GOTO a textové návěští
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
@opak
print "hello"
goto @opak

5. GOTO a výpočet největšího společného dělitele

Podobně lze realizovat výpočet největšího společného dělitele bez čísel řádků. Povšimněte si strukturované konstrukce if-then, kterou se EndBASIC odlišuje od starších variant klasických BASICů:

rem *****************************
rem
rem Výpočet největšího společného
rem dělitele.
rem
rem Úprava pro EndBASIC
rem (využití GOTO)
rem
rem *****************************
 
 
 
print "x=";
input x
print "y=";
input y
rem "Vypocet"
 
@loop
if x=y then
    print "gcd:"; x
end if
if x>y then
    x=x-y
    goto @loop
end if
if x<y then
    y=y-x
    goto @loop
end if
 
end

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

EndBASIC 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 smyčka 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. I tento typ smyčky EndBASICu najdeme. Popišme si ji nejdříve, a to příkladem z dokumentace:

DO
    PRINT "Infinite loop"
LOOP
 
DO
    a = a + 1
LOOP UNTIL a = 10
 
DO
    a = a + 1
LOOP WHILE a < 10
 
a = 0
DO UNTIL a = 10
    a = a + 1
LOOP
 
a = 0
DO WHILE a < 10
    a = a + 1
LOOP

Tato smyčka tedy odpovídá jak strukturované konstrukci repeat-until, tak i while-end.

7. Počítaná programová smyčka FOR-NEXT

Nejtypičtější příklad použití počítané smyčky FOR-NEXT. Povšimněte si, jak se pracuje s počáteční a koncovou hodnotou počitadla:

rem *****************************
rem
rem Smyčka typu FOR-NEXT
rem v základní formě.
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
for i=0 to 10
  print i
next

Výsledky ukazují, že počitadlo dosáhlo obou mezních hodnot:

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
 10

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

rem *****************************
rem
rem Smyčka typu FOR-NEXT
rem se specifikací kroku.
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
for i=0 to 10 step 2
  print i
next

Výsledky:

 0
 2
 4
 6
 8
 10

Některé BASICy v dalším programu do smyčky vstoupí a vypíšou hodnotu 10, což je nekorektní chování (příkladem je například již zmiňovaný Atari BASIC). EndBASIC, ostatně podobně jako GW-BASIC, v tomto případě korektně nevypíše nic:

rem *****************************
rem
rem Smyčka typu FOR-NEXT
rem ve formě, kdy je horní limit
rem menší než limit horní.
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
for i=10 to 0
  print i
next

EndBASIC ovšem do smyčky nevstoupí a tudíž ani nevypíše počáteční hodnotu počitadla.

Otestujme si ještě, kdy a jak se kontroluje mezní hodnota počitadla. Některé BASICy jsou v tomto ohledu velmi flexibilní a umožňují změnu mezí v každé iteraci. EndBASIC ovšem tuto flexibilitu postrádá (a těžko rozhodnout, zda je to dobře nebo špatně):

rem *****************************
rem
rem Smyčka typu FOR-NEXT
rem s průběžnou změnou horního
rem limitu.
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
max=10
for i=0 to max
  print i,max
  max=max+1
next

Tato konstrukce není v EndBASICu korektní:

endbasic: 13:1: Cannot redefine max as a variable

Totéž platí pro pokus o změnu kroku:

rem *****************************
rem
rem Smyčka typu FOR-NEXT
rem s průběžnou změnou kroku
rem změny počitadla smyčky.
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
s=1
for i=0 to 20 step s
  print i,s
  s=s+1
next i

Opět se nejedná o platný zápis:

endbasic: 14:20: STEP needs a literal number

8. Smyčka typu WHILE-WEND s podmínkou na začátku

V mnoha klasických BASICech byl podporován pouze jeden typ programové smyčky, a to konkrétně počítané smyčky typu FOR-NEXT; ostatní typy smyček bylo nutné simulovat kombinací příkazů IF a GOTO. Později byla přidána podpora pro další strukturované příkazy, což mj. znamenalo přidání syntaxe pro programovou smyčku WHILE, jejíž ukončující příkaz se jmenoval WEND. I tento typ smyčky je v EndBASICu podporován, takže si můžeme upravit program pro výpočet největšího společného dělitele takovým způsobem, aby tuto smyčku využíval:

rem *****************************
rem
rem Výpočet největšího společného
rem dělitele.
rem
rem Úprava pro EndBASIC
rem (využití smyčky WHILE-WEND)
rem
rem *****************************
 
 
 
print "x=";
input x
print "y=";
input y
 
while x<>y
  if x>y then x=x-y
  if x<y then y=y-x
wend
 
print "gcd: ";x
 
end
Poznámka: povšimněte si, jakým způsobem se zapisuje nerovnost. Tento styl zápisu mimochodem podporovaly i první verze programovacího jazyka Python.

9. Výpočet konstanty π varianta s FOR-NEXTWHILE-WEND

Následuje nepatrně složitější příklad s dvojicí nepřímo vnořených smyček pro výpočet konstanty π. Nejprve si uveďme variantu s počítanou programovou smyčkou FOR-NEXT:

rem *****************************
rem
rem Výpočet konstanty Pi.
rem
rem Uprava pro EndBASIC
rem
rem *****************************
 
 
 
n=1
for i=1 to 10
  gosub @calc_pi
  print i,n,pi_approx
  n=n*2
next
end
 
@calc_pi
rem
rem Subrutina pro výpočet Pi
rem
pi_approx=4.0
for j=3 to n+2 step 2
    pi_approx=pi_approx*(j-1)/j*(j+1)/j
next
return

Postupně se zlepšující výsledek:

 1             1             3.5555555555555554
 2             2             3.5555555555555554
 3             4             3.4133333333333327
 4             8             3.3023935500125976
 5             16            3.230036466411717
 6             32            3.188127169447139
 7             64            3.165482060034797
 8             128           3.1536988490958007
 9             256           3.147686899556424
 10            512           3.1446501625172125

Podobným způsobem ovšem můžeme použít strukturovanou programovou smyčku WHILE-END. Tentokrát ovšem nebudeme muset používat pomocné počitadlo i; smyčka bude řízena přímo hodnotou uloženou v proměnné n:

REM *****************************
REM
REM Výpočet hodnoty konstanty PI
REM postavený na smyčce
REM typu WHILE-WEND.
REM
rem Úprava pro EndBASIC
REM
REM *****************************
 
 
 
n=1
while n<=2000
   gosub @calc_pi
   print n,pi_approx
   n=n*2
wend
end
 
rem
rem Subrutina pro vypocet pi
rem
@calc_pi
pi_approx=4.0
j=3
while j<=n+2
  pi_approx=pi_approx*(j-1)/j*(j+1)/j
  j=j+2
wend
return

Výsledky by měly odpovídat předchozímu řešení:

 1             3.5555555555555554
 2             3.5555555555555554
 4             3.4133333333333327
 8             3.3023935500125976
 16            3.230036466411717
 32            3.188127169447139
 64            3.165482060034797
 128           3.1536988490958007
 256           3.147686899556424
 512           3.1446501625172125
 1024          3.143124017028201

10. Alokace polí

V EndBASICu se pole alokují příkazem DIM, podobně jako v klasických BASICech. Ovšem je nutné si dát pozor na to, že se zadává velikost pole v každém rozměru a nikoli index posledního prvku v dané dimenzi. To znamená, že je zde sémantický rozdíl v příkazu:

DIM A(10)

Tento zápis má tři možné sémantiky lišící se podle použitého BASICu:

  1. pole, jehož prvky mají indexy 0, 1, … 10 (jedenáct prvků)
  2. pole, jehož prvky mají indexy 1, 2, … 10 (deset prvků)
  3. pole, jehož prvky mají indexy 0, 1, … 9 (deset prvků) – případ EndBASICu

V EndBASICu je taktéž možné používat vícerozměrná pole; nejsme zde tedy omezeni na jednu až dvě dimenze tak, jako v mnoha klasických BASICech:

dim a(10)
dim b(10, 10)
dim c(10, 10, 20)
dim d(10, 20, 30, 40)
rem atd.

Příklad práce s jedenáctiprvkovým jednorozměrným polem:

rem *****************************
rem
rem Práce s jednorozměrnými poli
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
rem Definice pole
dim a(11)
 
rem Naplnění pole
for i=0 to 10
  a(i)=10*i
next
 
rem Tisk pole
for i=0 to 10
  print a(i)
next
 
end

Výsledky:

 0
 10
 20
 30
 40
 50
 60
 70
 80
 90
 100

Dtto, ale s dvourozměrným polem:

rem *****************************
rem
rem Práce s dvourozměrnymi poli
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
rem Deklarace pole
dim m(6,6)
 
rem Naplnění pole
for i=0 to 5
  for j=0 to 5
    m(i,j)=i*j
  next
next
 
rem Tisk pole
for i=0 to 5
  for j=0 to 5
    print m(i,j),
    next
  print
next
 
end

Opět si ukažme výsledky:

 0             0             0             0             0             0
 0             1             2             3             4             5
 0             2             4             6             8             10
 0             3             6             9             12            15
 0             4             8             12            16            20
 0             5             10            15            20            25

Navíc je možné použít funkce lbound% a ubound% pro zjištění nejmenšího a největšího indexu v dané dimenzi (nebo v jediné dimenzi jednorozměrného pole):

dim A(10)
 
rem vypíše 0
print lbound%(A)
 
rem vypíše 9
print ubound%(A)

11. Řetězce

Po cca čtyřiceti letech, které uplynuly od doby kralování klasických BASICů, se poněkud pozměnily řetězce. Namísto ASCII znaků (či spíše podmnožiny ASCII znaků) nyní mohou řetězce obsahovat Unicode znaky a interně používají kódování UTF-8. Jinak ovšem v EndBASICu nalezneme běžnou sadu funkcí pro zpracování řetězců. Programátorům jsou k dispozici tři „klasické“ funkce určené pro převody mezi znaky, řetězci a číselnými hodnotami – ASC% (převod znaku na jeho Unicode hodnotu – sic), CHR$ (opak ASC%) a STR$ (opak VAL, převod čísla na řetězec).

Navíc jsou i v EndBASICu dostupné funkce LEFT$, RIGHT$ a MID$ přidané do BASICu původně Microsoftem, které v Microsoftích interpretrech přežily pravděpodobně až do současnosti.

rem *****************************
rem
rem Práce s řetězci, manipulace
rem s obsahem řetězců.
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
A$="HELLO WORLD!"
print A$
print left$(A$, 5)
print right$(A$, 6)
print mid$(A$, 7, 5)
end
HELLO WORLD!
HELLO
WORLD!
ORLD!

Mimochodem – takto vytvořený řetězec není nutné alokovat pomocí DIM.

12. Data jako součást zdrojového kódu

Tradiční BASICy kromě polí neumožňovaly práci se strukturovanými datovými typy, takže se všechny problémy musely řešit právě jen s využitím polí (a to většinou s omezením na jednorozměrná a dvourozměrná pole). Tato pole bylo možné inicializovat s využitím hodnot (dat), která byla součástí vlastního programu a konkrétně byla uložena na řádcích začínajících příkazem DATA. Přečtení jedné hodnoty (a interní posun na další hodnotu) je realizován příkazem (nikoli funkcí) READ. To ovšem znamená, že tyto hodnoty nebyly pevně spojeny s poli a bylo je například možné ihned vypsat, vykreslit na obrazovku formou pixelu, přehrát jako zvu atd. Jednalo se tedy až o kupodivu velmi flexibilní systém.

Výpis tří hodnot uložených v sekci DATA může být realizován takto:

rem *****************************
rem
rem Data jako součást zdrojového
rem kódu
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
for i = 1 to 3
    read a$
    print a$
next
 
data "FOO", "BAR", "BAZ"

Výsledky:

FOO
BAR
BAZ

Příkazem RESTORE je možné nastavit interní ukazatel na další prvek znovu na začátek (popř. na zadaný programový řádek), takže lze prvky načítat neustále dokola:

rem *****************************
rem
rem Data jako součást zdrojového
rem kódu
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
for j = 1 to 5
    restore
    for i = 1 to 3
        read a$
        print a$
    next
next
 
data "FOO", "BAR", "BAZ"

Nyní se budou hodnoty na výstupu opakovat:

FOO
BAR
BAZ
FOO
BAR
BAZ
FOO
BAR
BAZ
FOO
BAR
BAZ
FOO
BAR
BAZ

13. Strukturovaný příkaz pro rozvětvení

Kromě strukturovaného rozeskoku IF-THEN-END IF obsahuje programovací jazyk EndBASIC i strukturované rozvětvení, které se do jisté míry podobá řídicí struktuře switch známé z céčka. Ovšem realizace podobné konstrukce v EndBASICu nevyžaduje zápis klíčového slova break a navíc se jedná o nepatrně flexibilnější řešení, jak je to ostatně patrné z následujícího příkladu, který detekuje sudé a liché hodnoty v rozsahu 0 až 10 (povšimněte si větve typu „default“) zapisované pomocí case else:

for i = 0 to 10
    select case i
        case 1, 3, 5, 7, 9
            print i, "odd"
        case 2, 4, 6, 8, 10
            print i, "even"
        case else
            print i, "something else"
    end select
next

Výsledky:

 0            something else
 1            odd
 2            even
 3            odd
 4            even
 5            odd
 6            even
 7            odd
 8            even
 9            odd
 10           even

Vždy je vybrána pouze jedna větev (resp. maximálně jedna větev), což znamená, že v další variantě se větev case 0 nikdy nevybere, protože hodnota 0 je testována i ve větvi předchozí:

for i = 0 to 10
    select case i
        case 1, 3, 5, 7, 9
            print i, "odd"
        case 0, 2, 4, 6, 8, 10
            print i, "even"
        case 0:
            print i, "zero"
        case else
            print i, "something else"
    end select
next

Výsledky odpovídají popisu:

 0            even
 1            odd
 2            even
 3            odd
 4            even
 5            odd
 6            even
 7            odd
 8            even
 9            odd
 10           even

Oprava předchozího programu tak, aby se větev case 0 korektně vybrala pro vstupní nulovou hodnotu:

for i = 0 to 10
    select case i
        case 1, 3, 5, 7, 9
            print i, "odd"
        case 2, 4, 6, 8, 10
            print i, "even"
        case 0:
            print i, "zero"
        case else
            print i, "something else"
    end select
next

A takto vypadají výsledky po výše popsané úpravě:

 0            zero
 1            odd
 2            even
 3            odd
 4            even
 5            odd
 6            even
 7            odd
 8            even
 9            odd
 10           even

14. Kombinace textové a grafické plochy

V EndBASICu je možné, podobně jako u některých dobových osmibitových mikropočítačů, na ploše obrazovky zkombinovat text (zdrojový kód atd.) s grafikou. To vede k tomu, že některé příkazy, například příkaz COLOR ovlivňují jak barvu textu, tak i vykreslovaných grafických entit. Navíc je nutné rozlišovat rozměry obrazovky v pixelech (dvě funkce) a ve znacích (jiné dvě funkce). A konečně, smazání plochy znamená smazání jak textu, tak i grafiky.

Poznámka: aby byly grafické příkazy dostupné, je nutné mít nainstalovánu knihovnu SDL2. Navíc je nutné při spouštění uvést volbu –console=graphics, popř. nastavit rozlišení volbou endbasic –console=graphics:640×480.

Obrázek 4: Podporováno je pouze šestnáct základních barev.

15. Ovládání textové konzole

Pro ovládání textové konzole (to zahrnuje i tvorbu her, menu atd.) postačují pouze čtyři příkazy:

Příkaz Význam
CLS vymazání celé obrazovky (i případné grafiky)
COLOR nastavení barvy popředí a pozadí
LOCATE přenastavení textového kurzoru na zadané souřadnice
PRINT tisk znaku, číselné hodnoty nebo řetězce na zadaných souřadnicích

Obrázek 5: Kombinace příkazů COLOR a PRINT.

16. Grafický výstup

Pro vykreslení grafických entit a pro ovládání „grafické části“ plochy se používá následujících sedm příkazů a dvojice funkcí:

Příkaz Stručný popis
GFX_PIXEL vykreslení pixelu
GFX_LINE vykreslení úsečky
GFX_CIRCLE vykreslení kružnice
GFX_CIRCLEF vykreslení kruhu
GFX_RECT vykreslení obrysu osově orientovaného obdélníka
GFX_RECTF vykreslení osově orientovaného obdélníka
GFX_SYNC zakáže nebo povolí obnovu obsahu plochy po každém grafickém příkazu
GFX_WIDTH% šířka grafické plochy v pixelech
GFX_HEIGHT% výška grafické plochy v pixelech

Význam většiny těchto příkazů a funkcí je pravděpodobně zřejmý, ovšem zastavme se u GFX_SYNC. Ten umožňuje pozastavit vykreslování na obrazovku – vše se bude vykreslovat na pozadí pokud se zavolá GFX_SYNC FALSE (a to včetně vstupního textu!). Posléze se každým dalším voláním GFX_SYNC obrazovka překreslí. Tímto způsobem je možné do určité míry nahradit double buffering a mj. tím dosáhnout i urychlení vykreslování. Výchozí chování, tj. okamžité překreslení obrazovky, se dosáhne příkazem GFX_SYNC TRUE.

17. Ukázky grafického výstupu

Vykreslení několika úseček barvami s indexem 0 až 15 (více barev není podporováno!):

rem *****************************
rem
rem Nastavení barvy a použití
rem příkazu pro kresbu úsečky.
rem
rem Úprava pro EndBASIC
rem
rem *****************************
 
 
 
for i=0 to 80
    color i mod 16
    gfx_line i * 5, 0, 0, 400-i*5
    gfx_line 640 - i * 5, 0, 639, 400-i*5
next

Obrázek 6: Kombinace textu a grafiky v grafické konzoli.

V dalším příkladu je realizováno vykreslení vzorku (nejedná se však o fraktál) na obrazovku. Stále jsme omezeni pouze na patnáct základních barev a postarší verze EndBASICu nepodporovaly operátor MOD, takže bylo nutné jeho chování zapsat smyčkou:

rem *****************************
rem
rem Circle moire
rem v grafickém režimu (16 barev)
rem
rem Úprava pro EndBASIC (bez MOD)
rem
rem *****************************
 
 
 
for y = 0 to 400
    for x = 0 to 400
        c = int(x*x/20+y*y/20)
        while c > 15
            c = c - 16
        wend
        color c
        gfx_pixel x, y
    next
next

Výsledek:

Obrázek 7: Moiré vykreslené předchozím příkladem.

Nová verze EndBASICu již operátor MOD podporuje, takže lze vše zapsat v lidštější podobě:

rem *****************************
rem
rem Circle moire
rem v grafickém režimu (16 barev)
rem
rem Úprava pro EndBASIC (s MOD)
rem
rem *****************************
 
 
 
for y = 0 to 400
    for x = 0 to 400
        c = int(x*x/20+y*y/20)
        c = c MOD 16
        color c
        gfx_pixel x, y
    next
next

18. Závěrečné zhodnocení

I přes některé zajímavé vlastnosti EndBASICu v tomto jazyku nalezneme i mnohá inherentní omezení, která prakticky znemožňují jeho použití pro větší projekty. 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ů:

bitcoin školení listopad 24

  1. Nelze vytvářet uživatelsky definované datové typy
  2. Program nelze strukturovat do menších celků – procedur a funkcí
  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
  6. V neposlední řadě je interpretace programů velmi pomalá, možná na úrovni BASICů běžících na HW s 1000× menším výkonem

Pokud si ovšem chcete vyzkoušet, jak se zhruba programovalo v dobách BASICů a osmibitových mikropočítačů, není EndBASIC špatnou volbou, i když podle mého názoru zajímavější a více „stylové“ je využití PC-BASICu, se kterým jsme se seznámili v tomto článku (tam si totiž můžete prakticky vyzkoušet i příkazy POKE a PEEK).

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

Všechny dnes popsané demonstrační příklady určené pro spuštění v EndBASICu 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
1 labels1.bas použití čísel řádků a příkaz GOTO https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/labels1.bas
2 labels2.bas příkaz GOTO a skok na pojmenované návěští https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/labels2.bas
3 gcd_goto.bas výpočet největšího společného dělitele, založeno na příkazech GOTO https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/gcd_goto.bas
4 gcd_while.bas výpočet největšího společného dělitele, založeno na smyčce WHILE-WEND https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/gcd_whi­le.bas
       
5 for_next_basic.bas základní forma počítané smyčky FOR-NEXT https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/for_nex­t_basic.bas
6 for_next_step.bas specifikace kroku v počítané programové smyčce, modifikátor STEP https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/for_nex­t_step.bas
7 for_next_swapped_limits.bas prohození mezí smyčky (nemělo by se do ní vstoupit) https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/for_nex­t_swapped_limits.bas
8 for_next_max_variable.bas pokus o modifikaci horního limitu počítané programové smyčky https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/for_nex­t_max_variable.bas
9 for_next_step_variable.bas pokus o modifikaci kroku počítané programové smyčky https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/for_nex­t_step_variable.bas
       
10 PI.bas výpočet konstanty π, založeno na smyčce FOR-NEXT https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/PI.bas
11 while_wend_pi.bas výpočet konstanty π, založeno na smyčce WHILE-WEND https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/whi­le_wend_pi.bas
       
12 1d_array.bas jednorozměrná pole v EndBASICu https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/1d_array.bas
13 2d_array.bas dvourozměrná pole v EndBASICu https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/2d_array.bas
14 bubble_sort.bas realizace algoritmu bublinkového řazení https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/bub­ble_sort.bas
       
15 data1.bas data mohou být součástí programu https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/data1.bas
16 data2.bas data mohou být součástí programu https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/data2.bas
       
17 gfx_test.bas test základních grafických schopností EndBASICu https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/gfx_test.bas
18 moire_no_mod.bas moiré, varianta bez operátoru MOD https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/mo­ire_no_mod.bas
19 moire_with_mod.bas moiré, varianta s operátorem MOD https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/mo­ire_with_mod.bas
       
20 select_case1.bas strukturovaný rozeskok realizovaný příkazy SELECT-CASE https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/se­lect_case1.bas
21 select_case2.bas strukturovaný rozeskok realizovaný příkazy SELECT-CASE https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/se­lect_case2.bas
22 select_case3.bas strukturovaný rozeskok realizovaný příkazy SELECT-CASE https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/se­lect_case3.bas
       
23 strings.bas základní příkazy pro operace s řetězci https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/strings.bas
       
24 do_loop1.bas nekonečná smyčka typu DO-LOOP https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/do_lo­op1.bas
25 do_loop2.bas smyčka DO-LOOP s testem na konci https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/do_lo­op2.bas
26 do_loop3.bas smyčka DO-LOOP s testem na konci https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/do_lo­op3.bas
27 do_loop4.bas smyčka DO-LOOP s testem na začátku https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/do_lo­op4.bas
28 do_loop5.bas smyčka DO-LOOP s testem na začátku https://github.com/tisnik/8bit-fame/blob/master/EndBASIC/do_lo­op5.bas

20. Odkazy na Internetu

  1. BASIC oslavil 60 let (zprávička)
    https://www.root.cz/zpravicky/basic-oslavil-60-let/
  2. Online IDE s interpretrem BASICu
    https://8bitworkshop.com/v3.11.0/
  3. gotBASIC.com
    https://gotbasic.com/atari.html
  4. Informace o GW-Basicu
    https://gw-basic.com/
  5. Stránka s živým EndBASICem
    https://repl.endbasic.dev/
  6. EndBASIC: BASIC interpreter + DOS environment, reimagined
    https://www.endbasic.dev/
  7. GWBASIC User's Manual
    http://www.antonis.de/qbe­books/gwbasman/index2.html
  8. GFA-BASIC
    http://sites.google.com/si­te/gfabasic16/
  9. E-mail od tvůrce GW-Basicu
    http://www.classiccmp.org/pi­permail/cctech/2005-April/042999.html
  10. General Electric GE-400
    http://www.feb-patrimoine.com/PROJET/ge400/ge-400.htm
  11. GE-400 Time-sharing information systems:
    http://www.computerhistory­.org/collections/accession/102646147
  12. A brief history of the development of BASIC (pravděpodobně již nefunkční odkaz)
    http://www.phys.uu.nl/~ber­gmann/history.html
  13. History of BASIC (PDF)
    http://www.q7basic.org/His­tory%20of%20BASIC.pdf
  14. Dartmouth College Computation Center. 1964.-The original Dartmouth BASIC manual
    http://www.bitsavers.org/pdf/dar­tmouth/BASIC_Oct64.pdf
  15. The Original BASIC
    http://www.truebasic.com/
  16. BASIC – Beginners All-purpose Symbolic Instruction Code
    http://hopl.murdoch.edu.au­/showlanguage.prx?exp=176
  17. The History of the Mainframe Computer
    http://www.vikingwaters.com/htmlpa­ges/MFHistory.htm
  18. Dartmouth Time Sharing System
    http://en.wikipedia.org/wi­ki/Dartmouth_Time_Sharing_Sys­tem
  19. General Electric (Wikipedia)
    http://en.wikipedia.org/wi­ki/General_Electric
  20. GE 225 vs. IBM 1401
    http://ed-thelen.org/GE225-IBM1401.html
  21. A GE-225 is found
    http://ed-thelen.org/comp-hist/GE225.html
  22. G.E. 200 Series Computers
    http://www.smecc.org/g_e__200_se­ries_computers.htm
  23. DTSS – Dartmouth Time Sharing System
    http://dtss.dartmouth.edu/index.php
  24. John G. Kemeny: BASIC and DTSS: Everyone a Programmer
    http://dtss.dartmouth.edu/e­veryoneaprogrammer.php
  25. GE-200 series (Wikipedia)
    http://en.wikipedia.org/wiki/GE-200_series
  26. GE-400 series (Wikipedia)
    http://en.wikipedia.org/wiki/GE-400_series
  27. GE-600 series (Wikipedia)
    http://en.wikipedia.org/wiki/GE-600_series
  28. ZX Basic Manual
    http://www.worldofspectrum­.org/ZXBasicManual/
  29. ZX81 BASIC Programming
    http://www.worldofspectrum­.org/ZX81BasicProgramming/
  30. Sinclair BASIC History
    http://scratchpad.wikia.com/wi­ki/Sinclair_BASIC_History
  31. Sinclair BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Sinclair_BASIC
  32. Sinclair BASIC (Wikipedia EN)
    http://en.wikipedia.org/wi­ki/Sinclair_BASIC
  33. Beta BASIC (Wikipedia EN)
    http://en.wikipedia.org/wi­ki/Beta_BASIC
  34. Beta BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Beta_BASIC
  35. BETA BASIC NEWSLETTER No 8
    http://spectrum128.ru/hel­p/BetaBasicNewsletter8.pdf
  36. R. T. RUSSELL: The home of BBC BASIC
    http://www.rtrussell.co.uk/
  37. R. T. RUSSELL: A History of BBC BASIC
    http://www.cix.co.uk/~rrus­sell/bbcbasic/history.html
  38. SuperBASIC (Wikipedia EN)
    http://en.wikipedia.org/wi­ki/SuperBASIC
  39. SuperBASIC (Wikipedia CZ)
    http://en.wikipedia.org/wi­ki/SuperBASIC
  40. Laser Basic/Laser Compiler
    http://www.sincuser.f9.co­.uk/049/laser.htm
  41. Laser BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Laser_BASIC
  42. BBC BASIC
    http://www.bbcbasic.co.uk/bbcba­sic.html
  43. BBC BASIC
    http://mdfs.net/Software/BBCBasic/
  44. BBC BASIC (Z80) for the ZX Spectrum
    http://mdfs.net/Software/BBCBa­sic/Spectrum/
  45. BBC BASIC (Wikipedia CZ)
    http://en.wikipedia.org/wi­ki/BBC_BASIC
  46. BeebWiki – 8-bit Acorn Computer Wiky
    http://beebwiki.jonripley­.com/Main_Page
  47. Porovnání osmibitů
    http://porovnani8bitu.spa­ces.live.com/
  48. Rosetta Code – Main Page
    http://rosettacode.org/wiki/Main_Page
  49. Rosetta Code – Category Basic
    http://rosettacode.org/wi­ki/Category:BASIC
  50. QBasicJedi
    http://www.freewebs.com/qbasicjedi/
  51. QBasic/QuickBasic Downloads
    http://www.freewebs.com/qba­sicjedi/qbdownloads.html
  52. QuickBASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/QuickBASIC
  53. QBasic.com
    http://www.qbasic.com/
  54. QBasic (Wikipedia)
    http://cs.wikipedia.org/wiki/QBasic
  55. Dialling with QBASIC
    http://www.mysundial.ca/tsp/qba­sic.html
  56. BASIC (Wikipedia EN)
    http://en.wikipedia.org/wiki/BASIC
  57. BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wiki/BASIC
  58. Turbo BASIC (Wikipedia CZ)
    http://cs.wikipedia.org/wi­ki/Turbo_BASIC
  59. More BASIC Computer Games
    http://www.atariarchives.or­g/morebasicgames/
  60. How to build an interpreter in Java, Part 1: The BASICs
    http://www.javaworld.com/jw-05–1997/jw-05-indepth.html
  61. Apple I
    http://applemuseum.bott.or­g/sections/computers/a1.html
  62. The Apple 1 history
    http://apple2history.org/his­tory/ah02.html
  63. The Apple 2 history
    http://apple2history.org/his­tory/ah03.html
  64. INTEGER BASIC Reference
    http://www.landsnail.com/a2ref2.htm
  65. APPLESOFT Reference
    http://www.landsnail.com/a2ref.htm
  66. Apple II Programming
    http://home.swbell.net/ru­bywand/csa2pfaq.html
  67. Applesoft Lite: Applesoft BASIC for the Replica-1
    http://cowgod.org/replica1/applesoft/
  68. Simons' BASIC
    http://en.wikipedia.org/wi­ki/Simons'_BASIC
  69. Simon's Basic
    http://www.lemon64.com/?ma­inurl=http%3A//www.lemon64­.com/museum/list.php%3Fli­neoffset%3D54%26genre%3Dma­nualmisc
  70. BASIC
    http://www.c64-wiki.com/index.php/BASIC
  71. C64 Wiki: Simons Basic
    http://www.c64-wiki.de/index.php/Simons_Basic
  72. Simons' Basic (evaluation)
    http://www.atarimagazines­.com/creative/v9n11/60_Si­mons_Basic.php
  73. Bill Gates' Personal Easter Eggs in 8 Bit BASIChttp://www.pagetable.com/?p=43
  74. Kladivo na programy (je tam třeba popsán způsob nahrávání a ochran programů protí kopírování a crackování)
    http://www.grandjihlava.cz/tmp/kla­divo.pdf
  75. Didaktik Gama návod k obsluze
    http://www.grandjihlava.cz/tmp/na­vod.pdf
  76. Můj přítel Didaktik Gama
    http://www.grandjihlava.cz/tmp/pri­teldidaktik.pdf
  77. Tip & trip pro Didaktik
    http://www.grandjihlava.cz/tmp/tip­trikdidaktik.pdf
  78. Muzeum československých mikropočítačů
    http://cs-pocitace.ic.cz/
  79. Popis modulů a aplikací pro IQ-151
    http://cs.felk.cvut.cz/~bily/iq151/
  80. IQ 151
    http://osmi.tarbik.com/cssr/iq151­.html
  81. „Domácí počítače“ nedávné minulosti
    http://www.fi.muni.cz/usr/jku­cera/pv109/xkrejcir.htm
  82. ZPA: IQ-151
    http://www.homecomputer.de/pa­ges/easteurope_cz.html#iq151
  83. Zrození IQ-151
    http://www.iq151.net/index.htm
  84. Stručná historie počítače IQ150/IQ151
    http://www.iq151.net/history.htm
  85. Old Computers – IQ 151
    http://www.old-computers.com/MUSEUM/compu­ter.asp?st=1&c=1045
  86. Wikipedia EN: IQ 151
    http://en.wikipedia.org/wiki/IQ151
  87. Wikipedia CZ: IQ 151
    http://cs.wikipedia.org/wiki/IQ151
  88. JtyOne Online ZX81 Emulator
    http://www.zx81stuff.org.uk/zx81/jty­one.html
  89. OpenSE BASIC
    https://zxdesign.itch.io/opense

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.