Tout une évolution par rapport au Bull Micral un dinosaure de 1972 La puissance des ordinateurs actuel est phénoménale J'attends la suite avec impatience!
Bonjour Bertrand, merci pour cette série de vidéos très intéressantes ! Je suis content d'avoir découvert le site ASM80 grâce à toi. C'est une merveille pour écrire en assembleur, compiler et débuguer puis exporter le fichier BIN sur une EEPROM pour faire des tests avec un Z80 et également un 8080 ou 6502. TOP 👍
super comme y avait rien à la tv comme dab , j'ai regardé la série z80 , mais des fois pour prolonger les séries on ravive les morts non 😅 . Pour l'enregistrement et la relecture à l'époque y en a qui ajustait la tête de lecture du magnéto avec un tournevis 🤪 . En tous cas merci c'est pationant pour la génération 80 .
Que de souvenirs, c’est très exactement à partir de ces expériences que j’ai décidé de faire carrière dans la radio analogique même si aujourd’hui l’informatique m’a rattrapé puisque je travaille dans la 4G et que je ne tourne plus un noyau depuis 20 ans au profit de commandes Linux :) super video
Dans le temps (1978) j'avais réalisé en assembleur 8080 , un moniteur qui pouvait écrire et lire des cassettes standards . le codage était, de mémoire, à base de deux fréquences et le format des datas était celui d'un dump format intel hex . :10010000214601360121470136007EFE09D2190140 :100110002146017EB7C20001FF5F16002148011988 :10012000194E79234623965778239EDA3F01B2CAA7 je pouvais sauver et recharger à n'importe quelle adresse , ou ajouter un offset pour des cas spéciaux . Le bon temps, vraiment !
Chouette ça va continuer !. Petite précision : la fonction call va sauvegarder le compteur ordinal aux deux adresses situées avant le pointeur de pile. Donc si le pointeur est à 0000 ce seront donc les adresses FFFF et FFFE qui seront visées. A moins d'un décodage partiel des adresses de la ROM et de la RAM, il y a peu de chance que ce soit celles-ci qui répondent.
Merci pour la mise au point du début et pour cette vidéo très intéressante. Personnellement je n'ai pas trouvé les bons niveaux sonores à l'époque des sauvegardes sur K7. :(
Ce sera marrant d'avoir une application qui produirait un fichier audio à partir des codes hexa. Il n'y aurait alors plus qu'à faire "lire ce fichier" par la plateforme pour charger le programme 😄 Encore un très bon épisode 👍
Bonjour, Ce système est déjà utilisé sur l'émulateur ZX Spectrum qui utilise des fichiers WAV pour remplacer l'interface cassette dans l'émulateur. Je ne serais pas étonné que ces fichiers joués simule la sortie son d'une cassette audio sur l'ordinateur d'origine.
Le bon vieux son de l'enregistrement sur K7. Pendant longtemps, c'était le seul moyen abordable pour enregistrer et recharger ses programmes. Standard Kansas City il me semble, comme sur mon vieux Tatav...
Super vidéo, merci ! Est-ce que tu pourrais faire un épisode sur la partie électronique qui s'occupe du codage et surtout du décodage audio utilisé pour la sauvegarde sur K7 ? La documentation est assez succincte sur ce sujet (ils listent les UC utilisées, mais le scan du schéma n'est pas suffisamment lisible pour se faire une idée de comment ça fonctionne). A propos de l'interface K7, il devrait être assez simple d'écrire une petite application sur PC pour générer un fichier sonore à partir de la sortie de ton assembleur (ou d'un compilateur C) afin de t'éviter d'avoir à entrer de longues séries d'octets au clavier.
2 роки тому
Je suis au même point que vous. Pas possible de faire mieux que le schéma du manuel. Honnêtement, je ne veux pas m'attarder outre mesure sur cette plateforme...la prochaine vidéo sera d'ailleurs la dernière.
Bonjour Bertrand, Pourquoi ne pas définir les variables comme locales, ainsi le compilateur utilisera soit les registres du Z80, soit la pile plutôt que ces horribles variables globales affectées à une adresse fixe. Cela permet de gagner en lisibilité et en portabilité.
Bertrand, Finalement, sur ton site ce n'est pas la version finale que tu avais publie. En cette partie 4 05:30, tu lis les cases mémoire 0x0000 à 0x0002 (prog. moniteur en EPROM) qui sont respectivement les opcodes 0x31, 0x6A, 0x13 ce qui correspond au mnémonique Z80 suivant LD SP,0x136A soit charger le haut de la pile en 0x136A NB: le codage en 16 bit est little Endian soit poids faible suivi du poids fort Cette 1ere instruction n'est pas un hasard et qui donne une pile maximale de 874 octets En tout cas c'est dans le premier Ko de RAM car le second Ko était optionnel. La RAM au delà de cette adresse était peut-être utilisé pour y mettre du code ou des variables. Petite modif. de ton code pour avoir une pile valide et utiliser les variables locales, le passage d'arguments et même les interruptions logicielles et matérielles avec un petit effort supplémentaire. Testé avec SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pc08/s08/stm8 3.6.0 v9615 (MINGW32) published under GNU General Public License (GPL) /* _===_ _ _ ______ _ _ _ _ _ | ___| | | | | ___ (_) | | (_) | | | |__ | | ___ ___| |_ _ __ ___ ______| |_/ /_ __| | ___ _ _ _| | | ___ _ _ _ __ | __|| |/ _ \/ __| __| '__/ _ \______| ___ \ |/ _` |/ _ \| | | | | | |/ _ \ | | | '__| | |___| | __/ (__| |_| | | (_) | | |_/ / | (_| | (_) | |_| | | | | __/ |_| | | \____/|_|\___|\___|\__|_| \___/ \____/|_|\__,_|\___/ \__,_|_|_|_|\___|\__,_|_| Essai de Basculement de la broche PIO-B0 sur plateforme Z80 PRO-83 Code source développé et compilé sur SDCC électro-Bidouilleur, V1, Juillet 2022. Licence de droits: Attribution 4.0 International (CC BY 4.0) */ void pause(unsigned int arg1); void boucleprinc(void) ; __sfr __at 0x41 pio_b_d; __sfr __at 0x43 pio_b_c; // Le signe DIESE est substitué par $$$ sans quoi le message est rejeté par la messagerie yt // a remplacer toutes les occurences avant de compiler $$$define RAMTOP 0x17FF // 3 lignes qui changent tout et aussi la possibilité de mixer ASM et C // 8 octets maxi pour cette section (RST 0 du Z80) void main(void) { // pointeur de pile sur la fin de la RAM __asm DI LD SP,$$$RAMTOP IM 1 __endasm; // le Z80 a sa pile sur le haut de la RAM et l'interruption INT est masquée // (confirmation car elle l'est au RESET) // le mode 1 n'a pas besoin de vecteur pour les chips Z80 PIO-SIO-DART // et un front descendant sur la broche INT* saute à l'adresse 0x38 // les variables locales et les retours de routine suite a un CALL sont gerees boucleprinc(); } // code en attente (inutile) pour gestion future et détournée // des vecteurs RST 8 a RST 38h et interruptions matérielles void remplissage(void) { __asm LD IX,$$$0x1234 LD IY,$$$0x5678 LD IX,$$$0xAABB LD IY,$$$0xDEF0 NOP NOP __endasm; // en option completer le remplissage pour que la fonction suivante soit en 0x100 } void boucleprinc(void) { unsigned char sortie=1; pio_b_c = 0x0F; // port PIO-B en mode sortie (mode 0) do { sortie++; pio_b_d = pio_b_d ^ 0x01; // inverser le bit B0 du port B pause(10); } while(--sortie); // le compilateur est bizarre dans son optimisation, // il ne genere pas le RET final si while(1) car un RET Z est généré dans la boucle // cette pirouette ne sert qu'a l'obliger a travailler proprement // les efforts doivent aussi venir du codeur } void pause(unsigned int arg1) { unsigned int cnt; for (cnt = arg1; cnt > 0; cnt--) { __asm NOP; __endasm; } } // Fin
2 роки тому
Si vous viviez plus près, je vous donnerais la plateforme juste pour l'effort! Dans l'exemple du basculement de B0, je n'ai pas défini la pile parce que l'on ne s'en sert pas. Tout cela a été testé avant que j'ajoute le paramètre définissant la pile dans la commande SDCC. Le but était de faire le code le plus compact possible.
Merci Bertrand, J'ai pris l'exemple toggle B0 car très compact pour illustrer l'absence de pointeur de pile, vu qu'on part de l'adresse 0. Cet exemple n'a pas besoin de pile, c'est exact, mais les autres oui, dès qu'une instruction CALL est invoquée. Par contre ils doivent fonctionner à la perfection sous le moniteur car celui-ci initialise une pile et décharge l'utilisateur de le faire. Mais en stand-alone, aucune erreur, ni oubli ne passe. Je ne sais pas ce que fait SDCC avec cet argument, mais c'est sûr aucun code n'est généré à ce sujet. Contrairement au MC68000 qui exige un pointeur de pile inclus dans le vecteur de reset, le Z80 définit tous ses registres à 0 au reset et rien d'autres n'est prédéfini si le programmeur ne le fait point.
Tout une évolution par rapport au Bull Micral un dinosaure de 1972
La puissance des ordinateurs actuel est phénoménale
J'attends la suite avec impatience!
Bonjour Bertrand, merci pour cette série de vidéos très intéressantes ! Je suis content d'avoir découvert le site ASM80 grâce à toi. C'est une merveille pour écrire en assembleur, compiler et débuguer puis exporter le fichier BIN sur une EEPROM pour faire des tests avec un Z80 et également un 8080 ou 6502. TOP 👍
Merci Bertrand 👌
très bon travail, hâte de voir la suite, que de bon souvenir.
super comme y avait rien à la tv comme dab , j'ai regardé la série z80 , mais des fois pour prolonger les séries on ravive les morts non 😅 .
Pour l'enregistrement et la relecture à l'époque y en a qui ajustait la tête de lecture du magnéto avec un tournevis 🤪 .
En tous cas merci c'est pationant pour la génération 80 .
Que de souvenirs, c’est très exactement à partir de ces expériences que j’ai décidé de faire carrière dans la radio analogique même si aujourd’hui l’informatique m’a rattrapé puisque je travaille dans la 4G et que je ne tourne plus un noyau depuis 20 ans au profit de commandes Linux :) super video
C'est bien, j'aime beaucoup cette vidéo.
Quelle série passionnante ! j'attends la suite avec impatience ! bon weekend Bertrand ;-)
merci
Dans le temps (1978) j'avais réalisé en assembleur 8080 , un moniteur qui pouvait écrire et lire des cassettes standards . le codage était, de mémoire, à base de deux fréquences et le format des datas était celui d'un dump format intel hex .
:10010000214601360121470136007EFE09D2190140
:100110002146017EB7C20001FF5F16002148011988
:10012000194E79234623965778239EDA3F01B2CAA7
je pouvais sauver et recharger à n'importe quelle adresse , ou ajouter un offset pour des cas spéciaux . Le bon temps, vraiment !
Chouette ça va continuer !. Petite précision : la fonction call va sauvegarder le compteur ordinal aux deux adresses situées avant le pointeur de pile. Donc si le pointeur est à 0000 ce seront donc les adresses FFFF et FFFE qui seront visées. A moins d'un décodage partiel des adresses de la ROM et de la RAM, il y a peu de chance que ce soit celles-ci qui répondent.
super intéressant! merci!
Merci pour la mise au point du début et pour cette vidéo très intéressante. Personnellement je n'ai pas trouvé les bons niveaux sonores à l'époque des sauvegardes sur K7. :(
Ce sera marrant d'avoir une application qui produirait un fichier audio à partir des codes hexa. Il n'y aurait alors plus qu'à faire "lire ce fichier" par la plateforme pour charger le programme 😄 Encore un très bon épisode 👍
Bonjour,
Ce système est déjà utilisé sur l'émulateur ZX Spectrum qui utilise des fichiers WAV pour remplacer l'interface cassette dans l'émulateur.
Je ne serais pas étonné que ces fichiers joués simule la sortie son d'une cassette audio sur l'ordinateur d'origine.
Bien hâte de voir la compilation du code en C. J'adore cette série. Ça me donne vraiment le goût de fabriquer une plaquette de ce genre, mais en 6502.
La série tire à sa fin, croyez-moi!
@ c'est bien dommage 😭
Le bon vieux son de l'enregistrement sur K7. Pendant longtemps, c'était le seul moyen abordable pour enregistrer et recharger ses programmes. Standard Kansas City il me semble, comme sur mon vieux Tatav...
C'est bien cela, 1200 et 2400 Hz.
Z80 for ever ! SuperZ Bertrand
Attention le Z est Russe désormais !! LOL
Il surgit hors de la nuit (informatique), et signe son nom d'un Z80 qui veut dire Bertrand. 🙂
@@freddyzinkiewicz660 Attention ! Bertrand est stricte Pas de politique :-))
@@gerardzi7930 merci je savais pas !
@@freddyzinkiewicz660 c'est juste un N qui a mal tourné.
Le bon vieux temps (Commodore C64.🤔😋
🌟🌹🌟
Super vidéo, merci !
Est-ce que tu pourrais faire un épisode sur la partie électronique qui s'occupe du codage et surtout du décodage audio utilisé pour la sauvegarde sur K7 ? La documentation est assez succincte sur ce sujet (ils listent les UC utilisées, mais le scan du schéma n'est pas suffisamment lisible pour se faire une idée de comment ça fonctionne).
A propos de l'interface K7, il devrait être assez simple d'écrire une petite application sur PC pour générer un fichier sonore à partir de la sortie de ton assembleur (ou d'un compilateur C) afin de t'éviter d'avoir à entrer de longues séries d'octets au clavier.
Je suis au même point que vous. Pas possible de faire mieux que le schéma du manuel. Honnêtement, je ne veux pas m'attarder outre mesure sur cette plateforme...la prochaine vidéo sera d'ailleurs la dernière.
@ Pas de problème, merci pour les vidéos de la série et pour la documentation.
Je vais essayer de me débrouiller avec le code source du moniteur.
Bonjour Bertrand,
Pourquoi ne pas définir les variables comme locales, ainsi le compilateur utilisera soit les registres du Z80, soit la pile plutôt que ces horribles variables globales affectées à une adresse fixe.
Cela permet de gagner en lisibilité et en portabilité.
Il me semble l'avoir essayé sans succès...
Bonjour, en base 16, 14, OK, mais cela fait 20 octets en base 10, non ?
C'est bien ce que j'ai écrit en commentaire de correction, non?
@ Oui ! Je ne l'avais pas vu 👀👍🏻
Bertrand,
Finalement, sur ton site ce n'est pas la version finale que tu avais publie.
En cette partie 4 05:30, tu lis les cases mémoire 0x0000 à 0x0002 (prog. moniteur en EPROM)
qui sont respectivement les opcodes 0x31, 0x6A, 0x13
ce qui correspond au mnémonique Z80 suivant
LD SP,0x136A
soit charger le haut de la pile en 0x136A
NB: le codage en 16 bit est little Endian soit poids faible suivi du poids fort
Cette 1ere instruction n'est pas un hasard et qui donne une pile maximale de 874 octets
En tout cas c'est dans le premier Ko de RAM car le second Ko était optionnel.
La RAM au delà de cette adresse était peut-être utilisé pour y mettre du code ou des variables.
Petite modif. de ton code pour avoir une pile valide et utiliser les variables locales, le passage
d'arguments et même les interruptions logicielles et matérielles avec un petit effort supplémentaire.
Testé avec SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pc08/s08/stm8 3.6.0 v9615 (MINGW32)
published under GNU General Public License (GPL)
/*
_===_ _ _ ______ _ _ _ _ _
| ___| | | | | ___ (_) | | (_) | |
| |__ | | ___ ___| |_ _ __ ___ ______| |_/ /_ __| | ___ _ _ _| | | ___ _ _ _ __
| __|| |/ _ \/ __| __| '__/ _ \______| ___ \ |/ _` |/ _ \| | | | | | |/ _ \ | | | '__|
| |___| | __/ (__| |_| | | (_) | | |_/ / | (_| | (_) | |_| | | | | __/ |_| | |
\____/|_|\___|\___|\__|_| \___/ \____/|_|\__,_|\___/ \__,_|_|_|_|\___|\__,_|_|
Essai de Basculement de la broche PIO-B0 sur plateforme Z80 PRO-83
Code source développé et compilé sur SDCC
électro-Bidouilleur, V1, Juillet 2022.
Licence de droits: Attribution 4.0 International (CC BY 4.0)
*/
void pause(unsigned int arg1);
void boucleprinc(void) ;
__sfr __at 0x41 pio_b_d;
__sfr __at 0x43 pio_b_c;
// Le signe DIESE est substitué par $$$ sans quoi le message est rejeté par la messagerie yt
// a remplacer toutes les occurences avant de compiler
$$$define RAMTOP 0x17FF
// 3 lignes qui changent tout et aussi la possibilité de mixer ASM et C
// 8 octets maxi pour cette section (RST 0 du Z80)
void main(void)
{
// pointeur de pile sur la fin de la RAM
__asm
DI
LD SP,$$$RAMTOP
IM 1
__endasm;
// le Z80 a sa pile sur le haut de la RAM et l'interruption INT est masquée
// (confirmation car elle l'est au RESET)
// le mode 1 n'a pas besoin de vecteur pour les chips Z80 PIO-SIO-DART
// et un front descendant sur la broche INT* saute à l'adresse 0x38
// les variables locales et les retours de routine suite a un CALL sont gerees
boucleprinc();
}
// code en attente (inutile) pour gestion future et détournée
// des vecteurs RST 8 a RST 38h et interruptions matérielles
void remplissage(void)
{ __asm
LD IX,$$$0x1234
LD IY,$$$0x5678
LD IX,$$$0xAABB
LD IY,$$$0xDEF0
NOP
NOP
__endasm;
// en option completer le remplissage pour que la fonction suivante soit en 0x100
}
void boucleprinc(void)
{ unsigned char sortie=1;
pio_b_c = 0x0F; // port PIO-B en mode sortie (mode 0)
do
{ sortie++;
pio_b_d = pio_b_d ^ 0x01; // inverser le bit B0 du port B
pause(10);
} while(--sortie);
// le compilateur est bizarre dans son optimisation,
// il ne genere pas le RET final si while(1) car un RET Z est généré dans la boucle
// cette pirouette ne sert qu'a l'obliger a travailler proprement
// les efforts doivent aussi venir du codeur
}
void pause(unsigned int arg1)
{ unsigned int cnt;
for (cnt = arg1; cnt > 0; cnt--)
{ __asm NOP;
__endasm;
}
}
// Fin
Si vous viviez plus près, je vous donnerais la plateforme juste pour l'effort! Dans l'exemple du basculement de B0, je n'ai pas défini la pile parce que l'on ne s'en sert pas. Tout cela a été testé avant que j'ajoute le paramètre définissant la pile dans la commande SDCC. Le but était de faire le code le plus compact possible.
Merci Bertrand,
J'ai pris l'exemple toggle B0 car très compact pour illustrer l'absence de pointeur de pile, vu qu'on part de l'adresse 0.
Cet exemple n'a pas besoin de pile, c'est exact, mais les autres oui, dès qu'une instruction CALL est invoquée.
Par contre ils doivent fonctionner à la perfection sous le moniteur car celui-ci initialise une pile et décharge l'utilisateur de le faire.
Mais en stand-alone, aucune erreur, ni oubli ne passe.
Je ne sais pas ce que fait SDCC avec cet argument, mais c'est sûr aucun code n'est généré à ce sujet.
Contrairement au MC68000 qui exige un pointeur de pile inclus dans le vecteur de reset, le Z80 définit tous ses registres à 0 au reset et rien d'autres n'est prédéfini si le programmeur ne le fait point.