A Commodore BASIC vagy PET BASIC a BASIC programozási nyelvnek a Commodore International 8 bites személyi számítógépeiben használt dialektusa, az 1977-es PET-től az 1985-ös C128-asig. A nyelv alapját a 6502-es mikroprocesszoron futó Microsoft BASIC képezte, ezért sok közös vonása volt a kor más 6502-es BASIC-jeivel, mint amilyen az Applesoft BASIC is volt. A Commodore részéről Jack Tramiel egyszeri fizetéssel vásárolta meg a Microsofttól a BASIC korlátlan licenceit, azzal utasítva el Bill Gates 3 dolláros gépenkénti ajánlatát, hogy „már házas vagyok”, így összesen dollárt költöttek az öröklicencre.Stated by Jack Tramiel at the Commodore 64 25th Anniversary Celebration at the Computer History Museum December 10, 2007 .
Története A Commodore a megvásárolt BASIC forráskódot fejlesztette tovább a többi 8 bites személyi számítógépükre. Csak a Commodore 128 megjelenésével (a V7.0-nál) kezdték a Microsoft szerzői jogát megjeleníteni. A kód eredeti, a Commodore PET-en futó 2.0 verziójában lévő, a Microsoft által elrejtett üzenet (Easter egg) a WAIT 6502, 1 beírása után a Microsoft! feliratot jelenítette meg a képernyőn. A kód jól el volt rejtve – az üzenetet nem látszott a parancsértelmező kódjában.Bill Gates' Personal Easter Eggs
A népszerű Commodore 64 a ROM-ba épített BASIC v2.0-val jelent meg, annak ellenére, hogy addigra a PET/CBM-sorozatban már a 4.0 változat is megjelent. Ennek oka az volt, hogy a 64-est otthoni számítógépnek szánták, míg a PET/CBM sorozatot üzleti és oktatási célra, ahol feltették, hogy a beépített programozási nyelv nagyobb használatnak lesz kitéve. Ez csökkentette a gyártási költségeket, mivel a V2-es kisebb ROM modulokban is elfért.
Technikai részletek
A Commodore memóriarezidens (ROM-ban tárolt) BASIC parancsértelmezőjének és KERNAL-jának kényelmes funkciója volt a teljes képernyős, szöveges szerkesztőfelület. Bár a Commodore-ok billentyűzete csak két nyílbillentyűvel rendelkezett, melyek mozgatási irányát a shift lenyomásával lehetett megfordítani, a teljes képernyős szerkesztővel a képernyő bármely területén ki lehetett adni közvetlen parancsokat vagy szerkeszteni lehetett a programsorokat. Ha a képernyő egy sora számmal kezdődött, azt sorszámként értelmezte, és tokenizálás után a programmemóriában tárolta. A nem számmal kezdődő sorokat a RETURN gomb megnyomása után végrehajtotta, amennyiben a kurzor éppen azon a soron tartózkodott. Ez jelentős előrelépés volt a korábbi otthoni számítógépek BASIC-jeinek beviteli felületéhez képest, melyek általában külön EDIT paranccsal aktiválható sorszerkesztőt használtak vagy „copy cursort”, ami a kurzor pozíciójának megfelelő helyen egyetlen karaktert engedett módosítani.
Képes volt továbbá névvel ellátott fájlként elmenteni a programot bármilyen eszközre, köztük magnókazettára – ami népszerű tárolóeszköz volt a PET idejében, és a 8 bites Commodore gépek életciklusa alatt végig olcsó tömeges tárolóeszköznek számított. Analóg hangfelvételi médiaként széles körben elterjedtek voltak. A legtöbb rendszer csak mágneslemezen tette lehetővé fájlnevek használatát, ami a többi tárolóeszközön nehézkessé tette egynél több fájl lementését. A felhasználó annyit tehetett, hogy feljegyezte a magnó számlálójának a fájl kezdetekori állását, de ez pontatlan és bizonytalan megoldás volt. A PET (és a BASIC 2.0) megjelenésével lehetett a fájlokat név szerint bekérni a kazettáról. Az eszköz ilyenkor is szekvenciálisan olvasta a kazetta tartalmát, átlépve a megadottól eltérő fájlneveken. A kazettás tároláshoz hatékony rekordstruktúra is tartozott. A Commodore kazettákon digitálisan tárolták az adatokat, szemben az akkoriban gyakori, kevésbé megbízható (bár olcsóbb) analóg megoldásokkal. Ezért specializált kazettás egységet, a Commodore Datasette-et kellett használni. Léteztek a szokásos szalagos egység használatát lehetővé tevő analóg-digitális átalakítók, de ezek alig voltak olcsóbbak a Datasette-nél.
Mivel a Commodore ugyanazt a BASIC nyelvet használta különböző hardverarchitektúrákon, ezért a LOAD parancs egy paraméterével befolyásolni lehetett, hogy a program milyen memóriacímre töltődjön be. A parancs a programot a BASIC memóriaterület elejére tölti be, míg a parancs arra a területre, ahonnan elmentésre került. BASIC programoknál általában az első változatot alkalmazták, mivel a BASIC memóriaterülete az egyes modelleknél más-más volt. Egyes Commodore BASIC-változatok ismerték a BLOAD és BSAVE parancsokat, melyek – az Applesoft BASIC-beli megfelelőjükhöz hasonlóan – a megadott memóriaterületekről bittérképeket mentettek ki vagy töltöttek be oda.
A kiindulásul szolgáló Microsoft BASIC értelmezőhöz hasonlóan a Commodore BASIC is jóval lassabb a natív gépi kódnál. Tesztek szerint 16 kilobájtnyi adat ROM-ból RAM-ba történő másolása gépi kódban kevesebb mint egy másodpercet vesz igénybe, BASIC-ben pedig egy percnél is többet. A BASIC programok felgyorsítására a programozók különböző technikákat alkalmaztak. Az egyik az volt, hogy a gyakran használt lebegőpontos értékeket változókban tárolták, mert a változónevet gyorsabban dolgozta fel a parancsértelmező a konstans értékeknél. Mivel a lebegőpontos volt az alapértelmezett számformátum, gyorsabb volt az egész számok helyett ezeket használni. Egyes programozók a valóban sebességkritikus programhelyeket 6502-es vagy 6510-es assembly nyelvre konvertálták, a BASIC program végén található DATA kulcsszavakból a memóriába POKE-olták vagy külön fájlból betöltötték, és a SYS BASIC paranccsal elindították (BASIC loader). Amikor pedig az assembly kód futási sebessége túl nagy, például egy számítógépes játékban, vagy amikor a program felhasználói adatbevitelre várakozik, programozott lekérést (polling) hajtanak végre a végrehajtás késleltetésére vagy felfüggesztésére, méghozzá a megfelelő memóriaterületek PEEK-elésével (ez pl. $A6 a C-64-en vagy $D0 a C-128-on, ami a billentyűzet-várakozási sor méretére utal).
A Commodore BASIC kulcsszavai általában rövidíthetők az első karakter shift nélküli, majd a következő shifttel történő lenyomásával. Ez a karakter legfelső bitjét 1-re állítja, amire a parancsértelmező abbahagyja az olvasást és egy keresőtábla alapján próbálja értelmezni a kifejezést. Tehát a teljes parancs beírása helyett az első néhány karakter beírása elegendő. Mivel azonban az összes BASIC parancsszó a memóriában egybájtos tokenekként tárolódik, ezért ez csak a bevitelt teszi kényelmesebbé, a program tárolását nem optimalizálja.
Az alapértelmezett, csupa nagybetűs karakterkészletben a shiftelt karakterek grafikus szimbólumokként jelennek meg; például a GOTO parancs G{Shift-O}-ként rövidíthető (ami a képernyőn így mutatkozik: GΓ). A legtöbb ilyen parancs kétbetűs, egyes esetekben hosszabb. Kétértelműség esetén több shifteletlen karaktert kellett beütni, például a GO{Shift-S} (GO♥) a GOSUB parancsnál. Egyes parancsokat nem lehetett rövidíteni, rövidségük vagy más parancsokkal való összetéveszthetőségük miatt. Például az INPUT-nak nem volt rövidítése, mert a parancsszó alakja ütközött az INPUT# paranccsal, ami közelebb helyezkedett el a kulcsszó-keresőtábla elejéhez. A gyakran használt PRINT parancsnak a többi BASIC dialektushoz hasonlóan a ? volt a rövid alakja. A parancsok shiftelt alakkal való rövidítése a Commodore BASIC egyedi sajátossága.
A kulcsszavak rövidítésével valamivel több kód fért el egy programsorban (a program egy sora 2 vagy 4 képernyősor hosszúságú lehetett, modelltől függően). Ez jelentett némi megtakarítást, mivel minden új sorhoz tartozott némi memória-overhead, de nem túl sokat. Minden BASIC parancs token formájában tárolódott és csak egyetlen bájtot foglalt a memóriából (illetve a BASIC 7 és 10 esetében több parancs két bájtot) a beírás módjától függetlenül. Ráadásul az ilyen hosszú sorokat utólag elég nehéz volt szerkeszteni. A LIST parancs mindig a teljes kulcsszavakkal listázta a programot – akkor is, ha így a sorok túlterjeszkedtek a 2 vagy 4 képernyősor hosszúságon, ami még lehetővé tette a bevitelüket.
További optimalizálást tett lehetővé,Commodore Retro Heaven: C64 Basic Optimizations hogy a BASIC programok nem igényelnek szóközöket (bár a LIST parancs a sorszám és a parancs közé automatikusan beszúr egyet), pl. a egy érvényes programsor. Gyakori is volt a szóközök nélküli programozás, mivel a kulcsszavak közötti szóközöket a tokenizált programban extra 0x20 bájtokként tárolták, amiken a parancsértelmező futtatás során átlépett. A sorok okozta overhead megtakarítására szokás volt továbbá minél több kódot egyetlen sorba írni, az egyes parancsokat kettősponttal elválasztva.
Az elágazás nélküli programvégrehajtás során a végrehajtás sorrendjét nem a sorszámozás határozza meg. A BASIC program ugyanis egyszeresen láncolt lista: minden sor a következő sor elejére mutató kétbájtos mutatóval kezdődik (ahol a 0 pointer a program végét jelzi), a következő két bájt a sor száma, majd a nullbájttal lezárt tokenizált parancssor következik.Pagetable.com: LOAD"$",8 Mivel a GOTO és GOSUB parancsok fix programsorszámokra hivatkoznak, a konstansok kódolása miatt a GOTO 10000 parancs három bájttal többet foglal a memóriából a GOTO 10 parancsnál; emiatt a programok átsorszámozása 1,2,3... sorszámokra a lehetséges optimalizációk közé tartozott (az egymást követő sorok összevonása, szóközök kihagyása stb. mellett), melyek utólagos elvégzésére külön segédprogramok léteztek. A program sorról sorra történő beírásakor a BASIC azonnal átrendezi a memóriában a programsorokat, hogy a sorszámok és a mutatók emelkedő sorrendben legyenek. Ha már a program a memóriában van, PEEK és POKE utasításokkal a sorszámok átírhatók, vagy akár minden sor száma megegyezhet. Azokban az időkben, amikor BASIC nyelven kereskedelmi programokat írtak, ezt a megoldást használták is a programok módosítása elleni védelmi technikaként.
A változónevek csak két karakter erejéig voltak megkülönböztetve, így a VARIABLE1, VARIABLE2 és VA mind ugyanarra a változóra utalt.
Az eredeti MS BASIC-kel megegyezően a Commodore BASIC natív számformátuma is lebegőpontos. A legtöbb kortárs BASIC-implementáció három bájtot használt az értékes számjegyekre (mantissza) és egy bájtot a kitevőre (karakterisztika). A három bájtos mantisszával a lebegőpontos számok pontossága kb. 6,5 decimális jegy, a kerekítési hibák gyakoriak. A Commodore azonban az MS BASIC négy bájtos mantisszáját vette át, ami a Commodore BASIC-et sokkal használhatóbbá tette az üzleti alkalmazások számára.
Bár a Commodore BASIC támogatja a (százalékjellel jelölt) előjeles egész szám változótípust, melynek értéke −32768 és 32767 közé eshet, a gyakorlatban ennek előnyei kizárólag tömbváltozóként jelennek meg: memóriát spórol, mivel így a tömb tagjai egyenként csak két bájtot foglalnak. Az egyszerű skalár változót egész számnak jelölve a BASIC mindig visszakonvertálja azt lebegőpontossá, ami lelassítja a program futását, és még pazarló is, hiszen a százalékjel egy bájtot elfogyaszt a memóriából. Az előjeles egész változókkal nem is lehet megcímezni a memória 32767 fölötti részeit a POKE vagy PEEK utasításokkal.
A karakterlánc típus jelölése a változónév után írt dollárjellel történik. Tehát az AA$, AA és AA% változókat a Commodore BASIC mind különbözőnek tekinti.
A gyári BASIC 2.0 hiányosságai miatt a Commodore 64-hez számos BASIC-kiterjesztést dobtak piacra. Az egyik legnépszerűbb kiterjesztés a Commodore 1541 Test/Demo Disken megtalálható DOS Wedge volt. Ez az 1 KB-os kiterjesztés főleg lemezkezelési parancsokkal bővítette az eredeti utasításkészletet, például lehetővé tette a lemez tartalomjegyzékének listázását a memóriában lévő program törlése nélkül. Ezeket a képességeket később több BASIC-kiterjesztés örökölte, köztük a népszerű Epyx FastLoad cartridge is. Más BASIC-kiterjesztések például a sprite-ok, hangok és a nagy felbontású grafikus mód kezelését tették lehetővé, ilyen volt például a Simons' BASIC.