Interpréteur compatible GFA Basic 3.5 pour Atari ST, écrit en C ANSI (C89).
Analyse, compile et exécute des programmes .bas GFA Basic 3.5. Émule les appels TOS (GEMDOS, BIOS, XBIOS, AES, VDI) et fournit un environnement console avec primitives graphiques SDL2.
make # compiler l'émulateur
./build/gfabasic demo_cplt.bas # exécuter la démo
./build/gfabasic # mode interactif (REPL)make test-all # 369+ tests, 100%
./build/gfabasic tests/test_if.bas # 31 tests IF/THEN/ELSELe projet est en C89 strict avec une couche d'abstraction OS (os_layer.c)
qui cible aussi bien Windows que l'Atari ST (via gcc-mintelf).
- MSYS2 (installé automatiquement par
build_atari.batsi absent) - Toolchain m68k-atari-mintelf (gcc 68000 + binutils + mintlib + fdlibm)
build_atari.batCe script installe MSYS2 + la toolchain (via setup_msys2_toolchain.sh),
puis compile :
build\atari\GFABASIC.PRG (~288 Ko, BSS ~400 Ko → tient en 1 Mo)
Résultat : un exécutable TOS Atari ST M68K à copier sur disquette/CF ou à lancer dans Hatari/Steem.
run_atari.batCe script crée une image disquette build\atari\GFABASIC.ST
(via make_floppy.py, motif FAT12 720 Ko) puis lance Hatari :
hatari.exe --tos tos.img --disk-a build\atari\GFABASIC.ST --auto A:\GFABASIC.PRG --machine st --memsize 4
--disk-a GFABASIC.ST: insère l'image disquette dans le lecteur A: (méthode universelle — n'exige pas le support GEMDOS HD, absent de certains compilages Hatari)--auto A:\GFABASIC.PRG: démarre automatiquement le programme depuis la disquette--machine st: Atari ST 68000--memsize 4: 4 Mo de RAM- Mode interactif : tapez
QUITpour sortir - La fenêtre Hatari ferme quand le programme se termine
run_atari_test.batExécute automatiquement tests\test_atari.bas dans Hatari et affiche le
résultat (console Atari + erreurs Hatari).
Principe :
- Compile
tools\runner.cenRUNNER.PRG(make -f Makefile.atari runner) — un mini-launcher TOS qui utilisePexec()pour lancerGFABASIC.PRGavecA:\TEST.BASen argument (sans lui, les arguments ne peuvent pas être passés automatiquement à un PRG autostarté par Hatari). - Construit une disquette multi-fichiers
GFABASIC.STcontenant GFABASIC.PRG, RUNNER.PRG et TEST.BAS (make_floppy.py --multi). - Lance Hatari avec :
--auto A:\RUNNER.PRG: démarre le launcher (qui lance GFA Basic)--conout 2: redirige la console VT52 verssimulation_console.txt--benchmark: mode le plus rapide (vitesse CPU maximale) — indispensable, car le runtime GFA en C compilé est trop lent en mode cycle-exact du 68000--run-vbls 4000: arrêt automatique après 4000 VBL
- Affiche la console Atari et les diagnostics (Bus Errors, panics).
Points d'attention corrigés durant les tests :
argv[argc-1]: sous MiNT/Pexec, la cmdline GEMDOS inclut le nom du programme en premier token (argv[1]), le fichier.baspasse donc en dernier argument.RUNNER.PRGne doit PAS être strippé : le strip des PRG contiguself32-atariprgcassait le crt0 (Bus Error au démarrage).- Framebuffer graphique statique (BSS) 320×200 sous
GFA_TARGET_MINT: lemalloc(256 Ko)de la mintlib bouclait avec le gros BSS du programme. load_file()en lecture progressive (sansfseek/ftell) pour être fiable sous GEMDOS.
Installation manuelle des outils (le script guide aussi) :
- Hatari (émulateur Windows ≥ 2.6) : https://framagit.org/hatari/hatari/-/releases
→ décompressez
hatari.exedanstools\hatari\ - ROM TOS : une ROM
tos.imgest fournie avec Hatari (ou EmuTOS libre : https://emutos.sourceforge.io/) → placeztos.imgdanstools\hatari\
pacman -S --needed --noconfirm make mingw-w64-x86_64-gcc
bash setup_msys2_toolchain.sh # une seule fois
make -f Makefile.atari clean
make -f Makefile.atari| Option | Rôle |
|---|---|
-m68000 |
68000 nu (ST/STE compatibles) |
-mnoshort |
int = 32 bits (le code suppose int 32 bits partout) |
-DGFA_TARGET_MINT |
Active la branche osbind.h/_DTA/_base de os_layer.c |
-Os |
Optimise la taille (RAM Atari limitée) |
Note : l'ABI historique TOS (
-mshort,int= 16 bits) casserait le code (buffers 4 096 lignes, tailles > 32767). Un audit complet serait nécessaire pour cibler l'ABI Pure C 1.1.
Deux modes : édition (prompt n]) et commande (prompt >). Une ligne vide bascule.
| Commande | Description |
|---|---|
LIST |
Liste le programme avec indentation automatique |
EDIT n |
Édite la ligne n (curseur ← → Home End Bksp Del) |
DELETE n ou n-m |
Supprime une ligne ou une plage |
INSERT n |
Insère une ligne avant la position n |
RUN ["fichier"] |
Exécute le programme (ou charge + exécute) |
LOAD "fichier" |
Charge un fichier .bas |
SAVE [A,] "fichier" |
Sauvegarde le programme |
NEW |
Efface le programme |
CLS / QUIT |
Efface l'écran / quitte |
Les mots-clés sont automatiquement mis en majuscules à la saisie.
| Catégorie | Détail |
|---|---|
| Contrôle de flux | IF/THEN/ELSE/ENDIF, FOR/NEXT/STEP/DOWNTO, WHILE/WEND, REPEAT/UNTIL, SELECT/CASE/ENDSELECT, GOTO/GOSUB/RETURN/@, DO/LOOP, EXIT IF, ON x GOTO/GOSUB, STOP, END, QUIT |
| Procédures/Fonctions | PROCEDURE, FUNCTION, RETURN expr, ENDFUNC, LOCAL, VAR (by-ref), DEFFN/FN, récursion, appels sans parenthèses (maProc 3, 7) |
| Tableaux 1D | DIM, ERASE, ARRAYFILL, DIM?, OPTION BASE |
| Opérateurs | + - * / ^ = <> < > <= >= AND OR XOR NOT EQV IMP MOD DIV, & (concat) |
| Mathématiques | 35 fonctions : SIN/COS/TAN/ATN/ASIN/ACOS/SINQ/COSQ/SINH/COSH/TANH, EXP/LOG/LOG10/SQR, ABS/SGN/INT/FRAC/FIX/ROUND/CEIL/TRUNC, MIN/MAX/EVEN/ODD/PRED/SUCC, FACT/COMBIN/VARIAT, RND, DEG/RAD, CFLOAT/CINT |
| Chaînes | 28 fonctions : LEN, ASC, CHR$, VAL, VAL?, LEFT$/RIGHT$/MID$, INSTR, RINSTR, UPPER$/LCASE$/LOWER$, TRIM$, STR$, BIN$, HEX$, OCT$, SPACE$, STRING$, MKI$/MKL$/MKS$/MKF$/MKD$, CVI/CVL/CVS/CVF/CVD |
| Opérateurs bits | BTST, BSET, BCLR, BCHG, SHL, SHR, ROL, ROR |
| PRINT, PRINT #, PRINT AT(x,y), PRINT USING (format #, ##.##, **, $$, +, -, ^^^^, virgules), INPUT, INPUT #, LINE INPUT, INKEY$, CLS, LOCATE, HTAB, VTAB | |
| Fichiers | OPEN/CLOSE (I/O/R/A/U), OPENW/CLOSEW, PRINT#/INPUT# |
| Mémoire | PEEK/POKE/DPEEK/DPOKE/LPEEK/LPOKE, DATA/READ/RESTORE, MALLOC/MFREE, BLOAD/BSAVE/BGET/BPUT |
| Graphismes SDL2 | COLOR (palette 16 couleurs), LINE, BOX, PBOX, CIRCLE, PCIRCLE |
| Son | BEEP, SOUND ch, freq, dur, vol, env |
| Événements | EVERY, AFTER, ON ERROR, ON BREAK, ERROR, ERR |
| Debug | TRON, TROFF |
| Édition | LIST avec indentation, EDIT en place (← → Home End Bksp Del), INSERT, DELETE, LOAD/SAVE |
main.c ──┬── lexer/ (490 keywords, tokens, EOL)
├── parser/ (LL(1), AST, labels 2-pass)
├── codegen/ (AST → bytecode)
└── runtime/ (VM pile, call stack, builtins)
├── memory/ (symboles, tableaux)
├── builtins/ (maths 35/35, chaînes 28/28, bits 8/8)
├── io/ (fichiers, BLOAD/BSAVE/BGET/BPUT)
├── events/ (EVERY, AFTER, ON ERROR)
├── sound/ (BEEP, SOUND)
├── tos/ (GEMDOS, BIOS, XBIOS, AES)
└── graphics/ (SDL2, COLOR, LINE, BOX, CIRCLE)
utils/os_layer (abstraction fichiers, console, temps)
Voir PLAN.md pour l'inventaire complet des fonctionnalités manquantes
et le plan de travail priorisé.
Résumé :
| Priorité | Nb items | Effort | Description |
|---|---|---|---|
| ✅ Implémenté | ~130 | — | Flux, procédures, maths, chaînes, bits, print AT/USING, conversion binaire, fichiers, graphismes SDL2, TOS partiel |
| 🔜 Priorité A | 22 | ~2-3 jours | Runtime cases uniquement : VAL?, INPUT$, PAUSE, MOUSE, TIMER, DATE$/TIME$, == (bug fix), etc. |
| 🔜 Priorité B | 40 | ~5-7 jours | Parser + codegen + runtime : SPOKE, graphismes avancés (PLOT, DRAW, TEXT, POLYLINE, FILL, BITBLT…), SETTIME, SWAP, QSORT |
| ⏳ Priorité C | 10 | ~4-8 semaines | Nouveaux sous-systèmes : GEM AES, VDI, MAT, FIELD, SHEL, CHAIN |
| Limitation | Détail |
|---|---|
| Mots-clés comme noms | Certains mots (add, val, double, inc) sont réservés car le lexer n'est pas contextuel |
| Format flottant | IEEE-754 (double précision), pas le format GFA propriétaire 8 octets |
| GEM AES | APPL_INIT/EXIT ok. FORM_ALERT, MENU_BAR, WIND_, EVNT_ sont des stubs (retournent 0). Voir PLAN.md |
| RESTORE label | Parse OK mais la restauration est globale (le label est ignoré au runtime) |
: séparateur |
Non supporté — une ligne = une instruction (conforme au vrai GFA Basic 3.5) |