Lampeggio LED

Progetti Arduino
Avatar utente
pgv
Messaggi: 484
Iscritto il: gio 17 set 2020, 13:16
Località: Ginevra

Re: Lampeggio LED

Messaggio da pgv »

Il FORTH (ah, beati ricordi di quando avevo i capelli!) e' un "Threaded Interpreted Language" in gergo informatico. Fondamentalmente, il linguaggio (che e' interpretato ma con uno zinzino di pre-compilazione, poi spiego) e' basato su un "dizionario" di "parole" che corrispondono piu' o meno a funzioni e subroutine ma non proprio. Inoltre, utilizza pesantemente lo stack, ed esegue le operazioni matematice in RPN (Reverse Polish Notation, come nelle calcolatrici HP), per cui per fare uno piu' uno si scriveva

Codice: Seleziona tutto

1 1 +
che "letto" dall'interprete andava piu' o meno "spingi il numero 1 sulla cima dello stack. Spingi il numero 1 sulla cima dello stack (a questo punto lo stack ha in cima due volte il valore 1), somma i due valori in cima allo stack e spingi il risultato sulla cima dello stack". Le "parole" non hanno una lsta formale di parametri ma vanno a cercarseli sullo stack (per cui i programmatori coscienziosi aggiungevano un commento con la lista delle cose prelevate dallo stack) e lasciano i risultati sullo stack (idem per i programmatori). Ovviamente, prelevare un oggetto in piu' o in meno, o lasciarne uno in piu' o in meno di quello che si aspetta l'utilizzatore ha rapidamente effetti disastrosi. Ogni programmatore FORTH inoltre si costruiva rapidamente un "dizionario" personale con le "parole" che utilizzava spesso. Passarsi programmi, quindi, diventava un'impresa. Leggere un programma in FORTH scritto da un programmatore, magari con uno stile personale diverso, ha causato piu' di un mal di pancia. Per esempio, vi calcolo il volume di una sfera:

Codice: Seleziona tutto

/* Calcola il volume di una sfera. Si aspetta di trovare il raggio in cima allo stack, lascia il volume sulla cima dello stack
/* Esempio : 4 volumeSfera . produce la seguente stampa: 201.06 */
: volumeSfera ( raggio -- volume )
dup dup * * pi * ;
/
Ora lo spiego. Il ":" vuol dire "Inizia la definizione di una parola", poi segue il nome della nuova parola (volumeSfera), e un commentuccio con le operazioni sullo stack, in particolare e nella mia personale notazione vuol dire che "preleva" il raggio dalla cima e lo rimpiazza con il volume.
Ora segue il codice vero e proprio. La parola "dup" copia il valore sulla cima dello stack e ce lo spinge, quindi dopo le due "dup" sullo stack abbiamo [raggio, raggio, raggio] (non e' una lista Python!). La parola "*" moltiplica tra di loro i DUE valori sulla cima dello stack, per cui dopo l'esecuzione della prima "*" lo stack contiene [raggio*raggio, raggio), e dopo la seconda contiene [raggioAlCubo]. La parola "pi" (che spesso nelle implementazioni SENZA virgola mobile, perche' la virgola mobile era considerata come un lusso e i conti si facevano tutti in interi, nascondeva giochini di rapporti tra numeri interi tipo 355/113) lascia il valore di pi greco (o un rapporto tra numeri interi...) sullo stack, per cui avremo [piGreco, raggioAlCubo] sullo stack, e l'ultima "*" moltiplica il cubo del raggio per pi greco, lasciando il volume sulla cima dello stack.

Tanto per ruzzare, una possibile implementazione di pi poteva essere la seguente:

Codice: Seleziona tutto

: pi 355 113 */ ;
dove tra l'altro troviamo "*/" che esegue una moltiplicazione mantenendo un risultato temporaneo a 32 bit (eh si', i numeri erano a 16 bit) seguita da una divisione. In questo modo non si perde precisione a causa di overflow.

Ovviamente c'erano ulteriori istruzioni di manipolazione dello stack come "swap" (che scambia tra loro i due vaolri in cima allo stack) e "drop" (che butta via il valor in cima allo stack), e cosucce simpatiche tipo "." che stampa il vaolre in cima allo stack (e lo consuma, per cui se uno voleva una stampa senza perdere il valore doveva scrivere "dup .", ovviamente).

Ma chi ce lo faceva fare??? Era l'inizio degli anni 70, quando
  • I "personal computer" non esistevano, o se esistevano erano cosucce ridicole con meno capacita' di un ATTINY85. Non scherzo. C'erano computer con BEN 256 BYTE di RAM. E che eseguivano 100,000 operazioni al secondo se andava bene. Piu' tardi, sistemi commerciali avevano 32 o 64 KILObyte di RAM ed erano considerati lussuosi
  • I linguaggi macchina, e quindi i linguaggi assembler (distinguo i codici numerici interpretati internamente dalle CPU dai codici mnemonici che sono piu' facili da leggere per un umano - ma che richiedono l'utilizzo di un programma assemblatore per essere tradotti in qualcosa capito da una CPU) erano molto diversi tra una architattura di CPU e un'altra. Oggi abbiamo poche famiglie affermate di CPU, ma gli anni 70 hanno visto nascere, evolvere e scomparire famiglie intere di CPU, tutte con architetture e istruzioni diverse ovviamente.
  • I computer dell'epoca caricavano i programmi da una pannellata di interruttori (non scherzo), cassette magnetiche (o nastroni magnetici), striscioline di carat perforate schede perforate, se andava bene flopponi da 8 pollici... Il mio primo disco rigido fu un Winchester da 5 MEGABYTE. Ed era lusso, rispetto ai floppy da 360 kbyte. Quindi, i linguaggi di programmazione, o andavano in ROM (BASIC, qualcuno si ricorda?) ed erano limitatissimi nella taglia, o caricavano da floppy e comunque erano limitati perche' dovevano convivere in memoria con il codice del programmatore...
In tutto questo, il FORTH era facile da "portare" da una architettura all'altra (perche' pochissime parole base sono scritte in assembler, e vanno riscritte, ma da un certo punto in poi le parole si scrivono in FORTH), occupava poco spazio in memoria (il Cantab Jupiter Ace era una specie di Sinclair ZX80 con 3 kbyte di RAM schermo incluso e FORTH in 8 kbyte di ROM), e grazie alla sua natura semi-interpretata (definendo una "parola" nuova, tutte le chiamate a parole esistenti sono "pre-compilate" con un link direttamente al codice eseguibile della parola) e' abbastanza veloce (molto piu' del BASIC per esempio). E le alternative si chiamavano COBOL (ick!), FORTRAN, BASIC, dopo qualche anno PASCAL e LISP...

Bene, abbiamo fatto una breve escursione nella storia della programmazione. E per restare in tema col Forum, sappiate che ci sono numerosi interpreti FORTH disponibili per Arduino.
Guido
Messaggi: 1443
Iscritto il: dom 18 mar 2018, 20:21

Re: Lampeggio LED

Messaggio da Guido »

Va bene, ho capito che l'argomento ti appassiona :D
Io ho imparato un bel po' di Assembly su C64 e ti diro' che lo trovavo molto facile, piu' facile del basic. Ci ho fatto cose da pazzi, tipo un engine per la gestione dei database sui floppy da 5 pollici e 1/4, ed era un database velocissimo. Ci ho scritto un nuovo firmware del lettore floppy sempre del C64, rendendolo piu' veloce, piu ho fatto programmi vari. Ma facevo un altro lavoro ed ad un certo punto ho dovuto fare una scelta. Una cosa che non ho capito e' come mai i programmatori hanno preferito i linguaggi tipo il C ed altri linguaggi ad alto livello, perdendo cosi' il controllo sulla macchina, ma lasciando che il produttore del linguaggio decidesse cosa fare e come farlo. E da li' il passo verso necessita' hardware sempre piu' spinte e' stato breve.
Avatar utente
pgv
Messaggi: 484
Iscritto il: gio 17 set 2020, 13:16
Località: Ginevra

Re: Lampeggio LED

Messaggio da pgv »

Il motivo e' semplicemente praticita'. Io posso compilare la mia coppia di Server e Client su Socket TCP/IP scritto in C (o interpretare quelli scritti in Python, non cambia niente) su un micro con una CPU ARM, Intel, Motorola, ESP32 al limite, senza dover applicare alcun cambiamento (non del tutto vero per l'ESP32 perche' non gira Python ma microPython, ma quasi) senza cambiare una linea di codice (tanto uso GCC o Python 3 in ogni caso, ESP32 escluso). Perfino la IDE Arduino e' in grado di compilare lo stesso sketch per CPU molto diverse, a partire dagli ATMEGA328P (8 bit) di un Arduino Uno passando per ESP8266 (8 bit), STM8 (con moderazione, non tutte le librerie sono disponibili, sempre 8 bit), ESP32 (32 bit), STM32 (32 bit) e chi piu' ne ha piu' ne metta. Tutto semplicemente aggiungendo un file JSON nelle Preferenze. Perche'? Perche' C, C++, Python sono linguaggi di programmazione definiti da uno standard, e quindi le implementazioni, per potersi chiamare C (o C++, o Python) devono implementare esattamente le stesse funzionalita' (non a caso PiccoloeMoscio ha inventato C# a propria immagine e somiglianza). Allego due listati in Assembly (e da notare che differenti programmi assemblatori utilizza(va)no sintassi differenti anche per la stessa CPU!):

1. "Hello World" in Commodore 64

Codice: Seleziona tutto

; 64TASS
; hello.asm

KERNAL_CLEAR_SCREEN = $e544 ; KERNAL ROM routine.
VICSCN = $0400              ; VIC-II Screen Video Matrix, 1024 (int).


; BASIC loader.
*=$0801             ; The two byte load address at the start of the .PRG file.
    .byte $0b, $08  ; Linked list pointer to next line of BASIC.
    .byte $d9, $07  ; 2009 (int) line number (LO, HI).
    .byte $9e       ; BASIC SYS token.
    .text "2064"    ; Memory address (int) to start of ASM: $0810


; ASM code.
*=$0810 ; The start of ASM execution.

      jsr KERNAL_CLEAR_SCREEN

      ; Enter HELLO WORLD into screen memory ($0400-$07e7) (1024-2023).
      lda #8         ; 'H' Screen Code
      sta VICSCN + 0 ; 'H' in $0400 screen memory
            
      lda #5         ; 'E' Screen Code
      sta VICSCN + 1 ; 'E' in $0400+1 screen memory

      lda #12         ; 'L' Screen Code
      sta VICSCN + 2 ; 'L' in $0400+2 screen memory
      
      lda #12         ; 'L' Screen Code
      sta VICSCN + 3 ; 'L' in $0400+3 screen memory

      lda #15         ; 'O' Screen Code
      sta VICSCN + 4 ; 'O' in $0400+4 screen memory

      lda #32        ; ' ' Screen Code
      sta VICSCN + 5 ; ' ' in $0400+5 screen memory

      lda #23         ; 'W' Screen Code
      sta VICSCN + 6 ; 'W' in $0400+6 screen memory
      
      lda #15         ; 'O' Screen Code
      sta VICSCN + 7 ; 'O' in $0400+7 screen memory
      
      lda #18         ; 'R' Screen Code
      sta VICSCN + 8 ; 'R' in $0400+8 screen memory
      
      lda #12         ; 'L' Screen Code
      sta VICSCN + 9 ; 'L' in $0400+9 screen memory
      
      lda #4         ; 'D' Screen Code
      sta VICSCN + 10; 'D' in $0400+10 screen memory
      
      rts            ; All programs must end with Return To Subroutine (RTS).
2. "Hello World" in ZX Spectrum:

Codice: Seleziona tutto

; hello-world.z80
CHAN_OPEN   equ  5633
PRINT       equ  8252

            org  32512

            ld   a, 2                ; 3E 02
            call CHAN_OPEN           ; CD 01 16
            ld   de, text            ; 11 0E 7F
            ld   bc, textend-text    ; 01 0E 00
            jp   PRINT               ; C3 3C 20

text        defb 'Hello, World!'     ; 48 65 6C 6C 6F 2C 20 57
                                     ; 6F 72 6C 64 21
            defb 13                  ; 0D

textend     equ  $
Guido
Messaggi: 1443
Iscritto il: dom 18 mar 2018, 20:21

Re: Lampeggio LED

Messaggio da Guido »

Il motivo e' semplicemente praticita'. Io posso compilare la mia coppia di Server e Client su Socket TCP/IP scritto in C (o interpretare quelli scritti in Python, non cambia niente) su un micro con una CPU ARM, Intel, Motorola, ESP32 al limite, senza dover applicare alcun cambiamento
Non mi mostrare listati assembly del C64 che mi fai venire la nostalgia e potrebbe tornarmi la pazzia di programmare questa roba !

Hai ragione perfettamente per quanto riguarda la praticita', ma se il prezzo da pagare e' stato quello di necessitare di hardware sempre piu' potenti per fare le stesse cose che si facevano con qualche centinaio di kbytes di ram, e magari con prestazioni inferiori, forse sarebbe stato il caso di insistere sulla strada dei linguaggi di basso livello ed una soluzione si sarebbe trovata.
Io per es nel mio lavoro mi ero scritto un programma in dos con il linguaggio Clipper che girava tranquillamente in 2 Mbyte di Ram e cpu 386 e faceva le stesse stesse cose (anzi meglio) che facevano i miei colleghi sotto Windows con programmi commerciali e computer monster. Ma ad un certo punto ho dovuto gettare la spugna: ero un lupo solitario e non avevo nessuno che mi aiutasse nella programmazione e per seguire le pazze direttive ministeriali ad un certo punto mi sono comprato il programma commerciale piu' in voga e di maggior successo e sono iniziate le imprecazioni nel vedere che questo programma non aveva gli automatismi che alleggerivano di molto il mio lavoro e che invece avevo implementato nel mio programma. Ed io ero un dilettante nella programmazione. Cosi' va il mondo.
Avatar utente
pgv
Messaggi: 484
Iscritto il: gio 17 set 2020, 13:16
Località: Ginevra

Re: Lampeggio LED

Messaggio da pgv »

Non confondere i sistemi operativi con pseudo-feature che consumano Gigabyte di RAM senza che l'utente abbia ancora lanciato un programma con i linguaggi di programmazione. Ricorda che C e C++ producono programmi che eseguono perfino su ATTINY o PIC10.
Io per lavoro e per piacere utilizzo spesso "macchinette" con varie (per)versioni di Linux e sto benissimo dentro 256 Mbyte di RAM quando si tratta di Linux vero e proprio, e 32 o 64 quando si tratta di Embedded Linux. Intendo dire editando e compilando i programmi a bordo delle macchinette stesse, non su un PC per poi trasferire. Ho provato anche il (dubbio) piacere del Raspberry Pizza, ma mi sembra piu' un "vorrei essere un desktop" che un sistema piu' o meno embedded o embeddable, e il fatto di dover diventare matto per farlo bootare senza monitor, tastiera, mouse e connessione Ethernet non me lo rende gradito. Come RetroStazione di emulazione gia' meglio.
P.S.: io il mio C64 ce l'ho ancora, in cantina... E sto facendo gli occhi dolci alla consorte per comprarmi un C64 Maxi.
Guido
Messaggi: 1443
Iscritto il: dom 18 mar 2018, 20:21

Re: Lampeggio LED

Messaggio da Guido »

Si, ma se il programma commerciale che si vuole usare gira solo sotto Windows e magari si rifiuta di girare su versioni di Windows inferiori al 2000 c'e' poco da fare .
Complimenti per la tua voglia di programmare, io ultimamenente non avrei molta voglia di riprendere in mano vecchi linguaggi . Ho in cantiere un programma in Visual Basic (essendo un programma intensamente grafico VB facilita la programmazione), ma chissa' quando prendera' la luce.
Rispondi