Salut à Tous,
Je vous prie de m'excuser si le message est un peu long mais il m'a semblé utile de mettre un exemple
qui permette de comprendre un peu mieux la mécanique Forth et surtout parler de sa fameuse Machine Virtuelle.
On va partir d'un exemple, mais je vais être obligé de forcer le trait pour en arriver où je veux.
Nous sommes dans les années 70 et supposons que nous ayons à écrire un programme ASM pour le 6809 qui calcule la fonction f(x)=8x + 7
La technique ici est ce que les Américains appellent "Threaded code" https://en.wikipedia.org/wiki/Threaded_code
Je n'ai jamais vraiment trouvé de traduction française.
Je me souviens avoir lu une fois "Programmation filaire" et moi ça me convient.
Arrivant à la conclusion qu'il me suffit de prendre un registre et de savoir y ajouter 1, y retrancher 1 et le multiplier par deux je fais :
Code : Tout sélectionner
ORG $4550
SETDP $45
;****************
;* 8D+7
;****************
Entree_Forth
4550 8645 LDA #$45
4552 1F8B TFR A,DP
4554 CC0010 LDD #$0010 ; Calcul pour la valeur D=$0010
;**********************************************************
; Calcul de la fonction F(D) = 8*D+7 = 2*2*2(D+1)-1
; MAIN PROGRAM
Code_8Dplus7
4557 BD4566 JSR Code_plusun
455A BD456E JSR Code_deuxfois
455D BD456E JSR Code_deuxfois
4560 BD456E JSR Code_deuxfois
4563 BD456A JSR Code_moinsun
; END OF MAIN PROGRAM- Résultat dans D
;**********************************************************
; D+1
Code_plusun
4566 C30001 ADDD #$0001
4569 39 RTS
; D-1
Code_moinsun
456A 830001 SUBD #$0001
456D 39 RTS
; 2*D
Code_deuxfois
456E 58 LSLB
456F 49 ROLA
4570 39 RTS
la lumière; c'était la mémoire. Chaque Ko était fait à la main et coûtait une fortune.
Très tôt on a cherché à économiser cette mémoire ROM ou RAM et on a vite remarqué que des adresses $4557 à $4563 on répétait l'instruction BD (JSR)
Naturellement l'idée est venue très tôt de faire un "Interpréteur d'adresse" qui ne lirait que les adresses et simulerait les JSR.
En fin de routine, au lieu de faire un RST il suffisait de retourner à l'interpréteur.
OBS : l'interpréteur d'adresse a existé avant le Forth.
Je modifie mon programme et j'appelle cet interpréteur d'adresses directes PseudoNext :
Code : Tout sélectionner
ORG $4550
SETDP $45
; DEBUT
4550 7E4555 JMP Entree_Forth
Adresse_Code
4553 4564 FDB Code_8Dplus7 ; Début du programme
; (COLD)
Entree_Forth
4555 8645 LDA #$45
4557 1F8B TFR A,DP
4559 CC0010 LDD #$0010 ; Calcul de la fonction pour D = $0010
455C 108E4553 LDY #Code_8Dplus7 ; Ecriture adresse du début du programme dans le pointeur d'adresse Y
; INTERPRETEUR D ADRESSES DIRECTES
Code_PseudoNext
4560 AEA1 LDX ,Y++ ; Ecriture de l'adresse dans X et avancement du pointeur vers l'adresse suivante
4562 6E84 JMP ,X ; Saut vers l'adresse de la sous-routine
;***************************************************************
; Programme principal
; Calcul de la fonction F(D) = 8*D+1 = 2*2*2(D+1)-1
Code_8Dplus7
4564 456E FDB Code_plusun
4566 4578 FDB Code_deuxfois
4568 4578 FDB Code_deuxfois
456A 4578 FDB Code_deuxfois
456C 4573 FDB Code_moinsun
; END - Résultat dans D
;*****************************************************************
; MOTS DU VOCABULAIRE
Code_plusun
456E C30001 ADDD #$0001
4571 0E60 JMP Code_PseudoNext ; Retour à l'interpréteur d'adresse
Code_moinsun
4573 830001 SUBD #$0001
4576 0E60 JMP Code_PseudoNext ; Retour à l'interpréteur d'adresse
Code_deuxfois
4578 58 LSLB
4579 49 ROLA
457A 0E60 JMP Code_PseudoNext ; Retour à l'interpréteur d'adresse
Version Z80 de l'interpréteur d'adresse direct
Code : Tout sélectionner
0001 0000 ;tasm -80 listing2.asm –g3
0002 4550 .ORG $4550
0003 4550 ; DEBUT
0004 4550 C3 55 45 JP Entree_Forth
0005 4553 Adresse_Code:
0006 4553 62 45 .DW Code_8Dplus7 ; Début du programme (Sans utilité)
0007 4555 ; (COLD)
0008 4555 Entree_Forth:
0009 4555 11 10 00 LD DE, $0010 ; Calcul pour la valeur DE=$0010
0010 4558 01 62 45 LD BC, Code_8Dplus7 ; Ecriture adresse du début du programme dans le pointeur d'adresse Y
0011 455B
0012 455B ; INTERPRETEUR D ADRESSES DIRECTES
0013 455B Code_PseudoNext:
0014 455B 0A LD A,(BC)
0015 455C 6F LD L,A
0016 455D 03 INC BC
0017 455E 0A LD A,(BC)
0018 455F 67 LD H,A
0019 4560 03 INC BC
0020 4561 E9 JP (HL)
0021 4562
0022 4562 ;***************************************************************
0023 4562 ; Programme principal
0024 4562 ; Calcul de la fonction F(D) = 8*DE+1 = 2*2*2(DE+1)-1
0025 4562 Code_8Dplus7:
0026 4562
0027 4562 6C 45 .DW Code_plusun
0028 4564 74 45 .DW Code_deuxfois
0029 4566 74 45 .DW Code_deuxfois
0030 4568 74 45 .DW Code_deuxfois
0031 456A 70 45 .DW Code_moinsun
0032 456C
0033 456C ; END - Résultat dans DE
0034 456C ;*****************************************************************
0035 456C
0036 456C ; MOTS DU VOCABULAIRE
0037 456C
0038 456C ; DE+1
0039 456C Code_plusun:
0040 456C 13 INC DE
0041 456D C3 5B 45 JP Code_PseudoNext
0042 4570
0043 4570 ; DE-1
0044 4570 Code_moinsun:
0045 4570 1B DEC DE
0046 4571 C3 5B 45 JP Code_PseudoNext
0047 4574
0048 4574 ; 2*DE
0049 4574
0050 4574 Code_deuxfois:
0051 4574 AF XOR A
0052 4575 CB 13 RL E
0053 4577 CB 12 RL D
0054 4579 C3 5B 45 JP Code_PseudoNext
Nota : Voulant faire très vite je n'ai pas vérifié mes codes sur émulateur, merci de me signaler toutes coquilles
EDIT du 15-10: Ajouté version Z80 de l'interpréteur d'adresse direct