La piaga dei cattivi programmatori Amiga

Dopo aver visto quanto siano stati (diversamente) bravi i manager e gli ingegneri Commodore nel far evolvere la nostra adorata piattaforma, è tempo di parlare anche di un’altra fonte di enormi problemi che ha causato tanti bagni di sangue: i programmatori incapaci.

Mi riferisco a quelli che, per definizione, non sono stati capaci di apprendere i rudimenti della (corretta, ovviamente) programmazione e sviluppare software in grado di girare su qualunque configurazione, sia hardware sia software, della famiglia di macchine della casa madre, nonostante quest’ultima sia stata molto prodiga nel mettere a disposizione tutta la documentazione necessaria (con l’arcinota collana di libri Amiga Kernel Manual in pompa magna).

Sia chiaro che l’Amiga non è il solo sistema dove programmatori inetti abbiano fatto danni, poiché quello della gente che è passata troppo velocemente dalla zappa alla tastiera è un problema generale, ma essendo stato il mio habitat informatico per parecchi anni (e ancora oggi continuo a interessarmene, perché ne rimango un appassionato) è quello che mi ha fatto provare di più sulla pelle e prendere atto della tragica situazione.

Essere ignoranti non ha necessariamente una connotazione negativa: indica lo stato di chi ignora, per l’appunto: di chi non abbia adeguate conoscenze in un particolare ambito (qualunque esso sia). Ma non si tratta di una condizione permanente, poiché è possibile porvi rimedio con adeguati studi.

Non è, però, né dev’essere una scusante, proprio perché è possibile “appianare le divergenze” e mettersi in condizione di poter masticare correttamente una materia. Specialmente nell’era del boom dell’informazione e, soprattutto, nel boom della rete prima (BBS) e di internet poi, l’ignoranza non è un’attenuante, ma un’aggravante quando si commettono sbagli che da essa derivino.

Tutto ciò al netto di errori che possano capitare e che in informatica hanno un nome preciso: bug. Di cui, checché ne possano dire sviluppatori molto presuntuosi e tronfi, nessun programmatore può considerarsi esente. I bug capitano, insomma (“shit happens“, dicono gli amici anglofoni), anche se ciò non deve dar la sponda a ignorare le buone pratiche che si dovrebbero mettere in atto per ridurli o eliminarli: anche qui diventa, poi, una questione di ignoranza (mancano strumenti nella propria “cassetta degli attrezzi” mentale).

Vivere entro le proprie quattro mura

Purtroppo, e come avevo anticipato, Amiga è stata una piattaforma letteralmente infestata da software sviluppato coi piedi da incompetenti, senza adeguata conoscenza e senza mettere in atto misure in grado di garantire che potesse girare su sistemi diversi dal proprio.

Una lavorazione cieca e solipsista, in cui l’unico punto di riferimento rimane il giardinetto di casa propria, ignorando tutto il resto del mondo. E’ proprio il classico caso de “funziona sul mio computer!”, davanti al quale non si può che sghignazzare impietosamente, giusto per metterla sul ridere.

Perché è proprio questo che succedeva: infilavi il dischetto di un gioco o una demo e… non dava segni di vita, non funzionava bene, oppure si presentava la classica schermata tanto “cara” nonché ben nota agli amighisti:

O ancora te ne accorgevi nel momento in cui avevi aggiornato la tua meravigliosa macchina: l’agognata espansione di memoria aggiuntiva da 512kB, oppure la ROM con la nuova versione del Kickstart (la parte più importante del s.o., che serviva all’avvio e che conteneva buona parte del codice principale), o la scheda acceleratrice che avevi sognato accanto al poster di Samantha Fox:

A volta bastava anche soltanto aggiungere un secondo lettore di dischi per scoprire che qualche applicazione non funzionasse più, a causa del leggero consumo di memoria a esso associato.

Braccia rubate all’agricoltura

Tutti scenari infausti e, purtroppo, comuni che facevano capo all’assurda leggerezza e scelleratezza con la quale si sviluppavano quei prodotti, e che purtroppo ancora oggi sono sorprendentemente di moda, come ho potuto scoprire di recente nel più grande forum amighista (EAB), che mi ha spinto a scrivere quest’articolo, di cui riporto il contenuto degli ultimi commenti rilevanti in merito:

I have a small bonus question: Is there an official mention that forbids writing 8-bit (byte) to a custom register?
Taking for example AUDxVOL, where only the 7 low bits are used, with the other bits being marked as “not used” in the doc, which means must be set to zero.
I wondered how the hardware reacted to a byte write in that scenario? (from testing at least in WinUAE, it appears to work fine.)

e la successiva risposta:

Upper byte (bits 8-15) = lower byte (might be different on some 020+, e.g 060, but in this case it doesn’t matter), because audio volume only uses bits 0-6, so it works fine. You can also have any value in bit7 (I’m doing that in my 4kb intro PT player, no problems).

Inutile dire che la risposta sarebbe dovuta esser ben diversa, considerato che sì: esiste una menzione ufficiale in merito, che si trova nel primo capitolo introduttivo dell’Amiga Hardware Reference Manual, e di cui riporto la parte rilevante:

Do not write spurious data to, or interpret undefined data from currently unused bits or addresses in the custom chip space. All undefined bits must be set to zero for writes, and ignored on reads.

Il cui significato dovrebbe essere già di per sé intelligibile, ma la lettura della descrizione del registro del volume dei canali audio contribuisce senz’altro a fugare qualunque dubbio possa ancora celarsi:

Bits 15-07Not used
Bit 06Forces volume to max (64 ones, no zeros)
Bits 05-00Sets one of 64 levels (000000=no output (111111=63 1s, one 0)
Audio Channel Volume (AUDxVOL)

Fa cascare le braccia, quindi, l’ultimo commento, dove il programmatore in erba (chissà quale) afferma candidamente, e magari orgogliosamente, di utilizzare il bit 7 nel suo player (audio) di appena 4kB di spazio…

Il museo degli orrori

Se tutto questo è roba recente, dove il tempo e l’esperienza avrebbe dovuto portar consiglio come sarebbe meglio agire (e, soprattutto, studiare), si può immaginare come fosse la situazione all’epoca, coi programmatori che si sono lasciati andati a ogni genere di porcata pur di far andare il gioco o la demo più velocemente… o semplicemente (!) per pura ignoranza.

Ci si potrebbe anche chiudere un occhio rimanendo nell’ambito delle demo: difficile pretendere professionalità da chi magari abbia letto o scopiazzato qualche spezzone di codice altrui per poi decidere di pasticciare qualcosa vedendo che, alla fine, “funzionasse” (!).

Ciò che è inaccettabile, però, è che codice di scarsa qualità sia stato realizzato per prodotti che sono stati commercializzati e finiti nelle mani degli utenti, perché in questo caso sì: la professionalità è certamente pretesa e leggere la documentazione della casa madre e applicarne le linee guida sarebbe stato il minimo indispensabile.

Purtroppo diversi delle migliaia di “slave” (una sorta di interfaccia fra gioco/demo e il framework principale) di WHDLoad (progetto nato inizialmente per poter installare i giochi su disco rigido, poi espansosi alla sistemazione di bug e all’aggiunta di nuove funzionalità come, ad esempio, il supporto a joystick/joypad con più tasti e altro ancora) riportano nella loro documentazione l’elenco delle modifiche, le quali ci fanno rendere conto di quanti giochi siano affetti da cattivissime pratiche di programmazione: un vero museo degli orrori!

Prendiamo alcuni esempi per far vedere di che razza di problemi erano affetti e che i programmatori degli slave hanno dovuto sistemare. Per Impossible Mission II:

leggiamo:

The game requires an installed A500 Kickstart 1.3 image.
The kickstart image must be located in the directory “Devs:Kickstarts” and must be named “kick34005.A500”.

Probabilmente il gioco saltava su qualche routine che si trova specificamente in qualche indirizzo della versione 1.3 del Kickstart, che quindi risulta necessario per poter funzionare. Ovviamente non soltanto non si deve fare alcuna assunzione su quale versione del s.o. sia presente nel sistema (a meno che non sia un vero e proprio requisito: ad esempio per le macchine AGA si assume la presenza di almeno la versione 3.0), ma è assolutamente proibito saltare ad alcuni indirizzi della ROM perché è facile che cambino da una versione all’altra!

Invece Fright Night:

ci mostra un paio di rogne abbastanza comuni:

  • Memory ($C00000) redirected in expmem
  • Blitwaits inserted

Il primo si potrebbe definire da manuale (in quanto non raro, purtroppo): il gioco assume che ci sia sempre la famigerata memoria “Slow” al solito indirizzo $C00000 a cui risulta normalmente mappata. Peccato che non sia sempre vero, perché questo speciale tipo di memoria risulta presente soltanto nelle primi modelli di Amiga 500 e 2000, mentre negli altri si può trovare 1MB di memoria Chip, ad esempio, oppure espansioni con memoria Fast (che ovviamente risulta mappata in tutt’altro posto!). Il gioco, quindi, non funzionerà mai in nessun’altra configurazione che non preveda la memoria Slow.

Il secondo è molto più comune (!), ma è da prendere con le pinze. Intanto e per chiarire, l’inserimento dei cosiddetti Blitwait significa che non sono presenti controlli che il Blitter abbia completato la sua ultima operazione a cui sta lavorando prima di poterlo riprogrammare per la prossima. Programmarne i registri mentre lavora può portare a dei disastri, e per questo è necessario che il processore esegua delle istruzioni per controllare che il Blitter risulti libero prima di riprogrammarlo.

Il codice può anche funzionare senza problemi perché per una serie di coincidenze tutto fila sempre liscio nella configurazione usata per testare il gioco. Ma ovviamente in un’altra può miseramente fallire, ed è il motivo per cui bisogna sempre mettere dei Blitwait. Posto che se le linee guida della casa madre affermano che bisogna controllare lo stato del Blitter prima di riprogrammarlo, lo si deve fare a prescindere!

Ora, può benissimo succedere che i programmatori si siano dimenticati di farlo. Questo è umano e, come già detto, i bug esistono per questo motivo. Nulla da dire in questo caso: Errare humanum est, dicevano gli antichi latini.

Discorso ben diverso se, invece, i programmatori abbiano appositamente evitato di mettere i Blitwait per risparmiare spazio in memoria per le istruzioni richieste, oltre a diversi cicli di clock necessari alla CPU per eseguirle. Quindi al fine di ottimizzare spazio e prestazioni. Questo succede anche perché i programmatori probabilmente avranno pensato: “tanto il Blitter avrà finito sicuramente il lavoro prima che torniamo di nuovo a programmarlo”. In ogni caso l’omissione sarebbe chiaramente dolosa e meritevole di fustigazione in pubblica piazza.

Distinguere fra bug e intenzionalità è difficile, ma chi ha realizzato lo slave avrà disassemblato il codice del gioco e visto tutti i casi in cui il Blitter viene programmato, per cui probabilmente può rendersi conto se si tratti dell’attuazione di un ben preciso schema criminale (da ergastolo) oppure qualche occasionale omissione dovuta a dimenticanza dello sviluppatore.

Un altro gioco che si presenta come un coacervo di pratiche abominevoli è, invece, Space Harrier II:

Non oso immaginare il lavoraccio che è stato necessario allo sviluppatore dello slave, il quale è stato prodigo di dettagli nella spiegazione dell’inferno che ha trovato nel codice di questo caso da studiare all’università riguardo le pratiche da cui ci si dovrebbe sempre astenersi:

  • Blitter waits added x47
  • Invalid memory accesses fixed x7
  • Screen clear routine rewritten to improve speed
  • Player avatar blit out of bounds blit fixed
  • Keyboard routine replaced to fix handshake
  • Timer subroutines fixed to avoid stack frame issues on 68010+
  • Frame delay/speed regulation added for very fast machines
  • Set CUSTOM2=0-5 to specify many frames to wait (minimum)
    (0 is off, 1 is draw every frame, 2 is every other frame, etc.)
  • Graphics fixed on fast machines due to copperlist not running in time
    (Mantis issue #4560)

Riporto anche parti del commento dell’autore dello slave:

WORDS FROM THE AUTHOR

Access faults persisted with bosses and bonus levels, that should be fixed.
There were also some blits that addressed memory above the 512k chip limit.

It also turns out there are two revisions of the game. The latter release is
the same box art and only distinguished by a different disk label, so my
guess is Grandslam did a second production run and let the developer do some
bug fixes. There is an attempt to make the keyboard handshake actually work
(using a succession of divu instructions!) but not much else different.
[…]

The game has an incredibly expensive approach to rendering – clearing the
entire screen buffer each frame and redrawing everything! I’ve rewritten
the clearing code as the blitter was used with src A activated, meaning the
blitter was reading memory for no reason. Doing this meant I could use the
CPU in parallel to clear the screen a bit faster. The game starts drawing
immediately after so it is not possible to have the blitter run while the
game gets on with something else.

Ironically, despite running at about 15fps on a stock A500, this game runs
too fast on very modern accelerators/emulators, so I’ve added a frame delay
to clamp this. I recommend a setting of 2, i.e. 25fps, which is still a bit
faster than A500, but you can vary it if you wish (up to 5, which is 10fps).

A parte l’impressionante montagna di Blitwait che è stato necessario aggiungere (per cui dubito fortemente che possa trattarsi di dimenticanza dei programmatori. Niente bug, insomma: è un problema sistemico!), c’è di tutto di più: si va da diversi accessi illegali alla memoria (oltre gli indirizzi disponibili) al disegno dei personaggio fuori dai confini dello schermo, dall’uso errato del Blitter per cancellare lo schermo (abilitando un canale DMA inutile, che non viene usato, ma che ovviamente influisce negativamente sulle prestazioni) alle Copperlist (i programmi eseguire dall’altro coprocessore, il Copper) che non vengono impostate in maniera corretta e che creano problemi coi sistemi dotati di hardware più veloce.

A tal proposito il gioco è talmente scritto male che il creatore dello slave è stato costretto ad aggiungere del codice per poter aggiustare opportunamente la velocità d’esecuzione nei sistemi più veloci, dove altrimenti diventa ingiocabile. Questa, purtroppo, è stata una piaga di diversi giochi che ovviamente sono stati scritti coi piedi da programmatori inetti che non hanno tenuto in debito conto dei sistemi più avanzati (le schede acceleratrici esistevano già fin dai tempi dell’Amiga 1000!).

Cosa che si ripercuote anche nella gestione della tastiera, la quale nell’Amiga ha bisogno di un protocollo di comunicazione che tenga conto di precise tempistiche per funzionare correttamente, ma che Space Harrier II ha sbagliato fin dalla prima versione del gioco, molto probabilmente implementando un ciclo di attesa via software, tramite l’esecuzione di un determinato numero di istruzioni. Ciclo che in sistemi più veloci è stato evidentemente eseguito molto rapidamente, anticipando notevolmente i tempi da rispettare per comunicare col controllore della tastiera e, quindi, non facendola funzionare correttamente.

Il problema è stato talmente evidente che pure la seconda versione del gioco ha cercato di porvi rimedio, ma ancora una volta con una “soluzione” completamente sbagliata, perché ha usato delle istruzioni di divisione (che sono molto lente nei primi processori 68000, ma decisamente più veloci in quelli più moderni) per cercare di allungare il tempo d’esecuzione del ciclo, quando invece la via corretta sarebbe dovuta essere quella di usare i timer presenti nel sistema per programmare l’opportuno tempo da far trascorre oppure controllare la posizione del pennello elettronico aspettando di aver superato la riga giusta (che equivale al fatto che sia passato un certo tempo sufficiente allo scopo).

Non so se ci siano giochi che abbiano fatto peggio (dovrei smazzarmi i migliaia di slave; che ovviamente non ho alcuna intenzione di fare), ma mi pare giusto che, oltre all’ergastolo, per i programmatori si sarebbero dovuti dare anche i lavori forzati e 47 frustate (una per ogni Blitwait mancante) per la sfilza di disastri che sono riusciti a causare con un solo gioco (roba da dilettanti allo sbaraglio: gente che avrebbe fatto meglio a dedicarsi a tutt’altra occupazione, standosene ben lontana dalla programmazione).

Conclusioni

Mi fermo qui, perché gli esempi che ho citato coprono i casi più importanti nonché comuni con cui abbiamo avuto a che fare con giochi (e non solo: le demo sono autentiche miniere di “perle” simili) scritti male, non seguendo le linee guida di Commodore riguardo la corretta programmazione degli Amiga.

Nel bene e nel male, la facilità di programmazione di queste macchine, unita alla maggior accessibilità (rispetto a PC et similia), ha sdoganato un’orda di programmatori improvvisati che hanno infestato i nostri amati computer con prodotti contenenti ogni sorta di trucchetti sporchi o semplicemente (!) facendo carta straccia di regole nate per garantire la fruibilità del software su ogni tipo di macchina.

Non è un caso che vi siano migliaia di slave (e altri ancora in lavorazione) per cercare di porvi rimedio, ma potete immaginare da soli la situazione dell’epoca, dove tutto ciò non era disponibile, purtroppo, portando alla disperazione tanti utenti “colpevoli” soltanto di aver avuto un computer diverso da quelli usati per sviluppare e/o testare il gioco (o la demo).

Only Amiga developers made it possible!

Press ESC to close