Tutoriel GCC 6809 pour MO/TO

Cette catégorie traite de développements récents destinés à nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
Orion_
Messages : 176
Inscription : 07 août 2014 16:29
Localisation : Perpignan
Contact :

Tutoriel GCC 6809 pour MO/TO

Message par Orion_ »

Comme j'ai pas mal galéré pour réussir à faire fonctionner GCC6809 pour MO5, je fait un petit tutoriel ici "presque" étape par étape.
Un grand merci à Pulkomandy pour sont SVN qui m'a permis d'avoir pas mal d'exemple afin de démarrer.
Je vous le conseil y'a plein de chose sympa: http://pulkomandy.tk/projects/thomson/b ... ls/gfx2mo5

Premièrement, ce tutorial est pour Windows (testé sous Windows 7 64bits)

Installer Cygwin: https://www.cygwin.com/ de préférence la version 32bits "setup-x86.exe"
Pendant l'installation, installer les packages "make" et "dos2unix".

Télécharger GCC6809 (personnellement j'ai utilisé la version du projet FreeWPC)
http://sourceforge.net/projects/freewpc/files/GCC-6809/
Fichier: gcc6809-win32-4.3.4-2.tar.gz
Décompressez ce fichier à la racine du répertoire C:\cygwin


Allez dans le repertoire C:\cygwin\home\NomDutilisateur
Editez le fichier ".bashrc" avec WordPad (ou un outil qui reconnais les fichiers texte au format Unix)
Ajouter la ligne: export PATH=/usr/local/gcc6809/bin:$PATH
Enregistrer et fermer le fichier.
Si vous éditer ce fichier avec WordPad, il sera enregistré sous le format Windows, et Bash n'aimera pas ça.
Lancez donc la console Cygwin avec le fichier C:\cygwin\Cygwin.bat
Ignorez les erreurs et taper: dos2unix .bashrc
Puis: source .bashrc
Normalement le fichier .bashrc devrait être correct maintenant.
(Tapez la commande: "aslink" pour voir si le programme ce lance)

Télécharger ce petit outil: http://onorisoft.free.fr/mo5/gcchex2bin.zip
Copier le fichier "gcchex2bin.exe" dans C:\cygwin\usr\local\gcc6809\bin


Ensuite vous pouvez avoir vos fichiers/projets dans le repertoire C:\cygwin\home\NomDutilisateur
L'avantage c'est que lorsque vous lancerez la console Cygwin, vous serez d'office dans ce répertoire.
Sinon si vous avez un répertoire du style: C:\mo5\exemple
Sous Cygwin vous serez obliger d'utiliser la commande: cd /cygdrive/c/mo5/exemple pour vous y rendre.


Allez donc dans le répertoire de votre choix, puis créer les fichiers suivant:

Un fichier start.s (il sera ajouté au début du binaire pour faire un JMP directement a la fonction main du fichier .c)

Code : Tout sélectionner

	.area .text
	jmp	_main
	rts
Le Makefile, générique, il suffit juste de changer les paramètres au débuts suivant ce que vous avez. (ici l'adresse de démarrage est $3000 pour MO5)

Code : Tout sélectionner

OUTPUT=exemple
BASEADRS=0x3000
OBJECTS=start.o main.o
CFLAGS=-Os

PREFIX=m6809-unknown-none
CC=$(PREFIX)-gcc
AS=$(PREFIX)-as
LIBPATH=/usr/local/gcc6809/lib/gcc/m6809-unknown-none/4.3.4/libgcc-cache
LIBOBJ=

all:	$(OBJECTS)
	aslink -mnwxso -b .text=$(BASEADRS) $(OUTPUT).s19 $(OBJECTS) $(LIBOBJ)
	gcchex2bin -i$(OUTPUT).s19 -o$(OUTPUT).bin
	rm -f $(OUTPUT).s19

clean:
	rm -f $(OUTPUT).bin $(OUTPUT).map $(OBJECTS)

%.o: %.c
	$(CC) $(CFLAGS) -c $< -o $@

%.o: %.s
	$(AS) $< -o $@

Et votre fichier main.c

Code : Tout sélectionner

#define mon_putc(car) { \
	asm(" swi \n"\
		" .fcb 2"\
		::"B" ((unsigned char) (car))\
	); \
}

void	myputs(char *str)
{
	while (*str)
		mon_putc(*str++);
}

void	main(void)	// Should NOT return INT ! (else gcc will include strange code affecting U register, don't bother the Warning from GCC about this)
{
	myputs("Hello, World !\r\n");
}
Note: La remarque sur le "main" qui ne retourne pas "int" s'explique par le fait que, si on met "int" à la place de "void", gcc ajoutera du code qui va modifier U et des valeurs dans la page direct (suivant DP), je ne sais pas pourquoi mais pour éviter ça, le seul moyen que j'ai trouvé c'est de mettre "void" à la place de "int" en valeur de retour du "main". Vous aurez un petit warning a la compilation mais ce n'est rien de grave.

Dans la console cygwin, taper "make" et voila votre fichier exemple.bin est disponible !
Il suffit de le charger dans DCMOTO à l'adresse $3000 et de faire un exec &h3000 !

Le fichier de sortie ".bin" est brut, sans aucun header.
EDIT: le format CoCo (aslink -t) qui semble avoir un header proche du thomson, n'est pas correct, en effet il intercale ce header tout les 32 octets


Attention, dans le Makefile que je vous donne çi dessus, aucune librairie n'est incluse.
Donc si vous faite des multiplications sur 16/32bits par exemple il faudrat rajouter les libraires de GCC pour ça.
Ajoutez donc à la ligne LIBOBJ=$(LIBPATH)/_muldi3.o $(LIBPATH)/_mulhi3.o
Si vous utilisez des divisions, c'est plus complexe, vous pouvez ajouter les libraries GCC mais elle pèsent plus de 2ko !!
(voici la ligne si vous voulez #$(LIBPATH)/_divdi3.o $(LIBPATH)/_divhi3.o $(LIBPATH)/_modhi3.o $(LIBPATH)/_umodhi3.o $(LIBPATH)/_euclid.o $(LIBPATH)/_seuclid.o $(LIBPATH)/_udivhi3.o $(LIBPATH)/_ashlhi3.o $(LIBPATH)/_lshrhi3.o $(LIBPATH)/_clzsi2.o $(LIBPATH)/_clz.o)

Il y a une autre méthode, utilisez la fonction div32 fourni par l'équipe de GCC6809, elle est dispo dans le fichier div32.s ici: https://code.google.com/p/gcc6809/downloads/list
Par contre, ce fichier ne compile pas d'office avec GCC, j'ai donc du le modifier pour qu'il fonctionne, il est dispo sur mon site ici: http://onorisoft.free.fr/mo5/div32.s

Pour l'utilisez, mettez ce fichier dans votre répertoire projet et rajouter "div32.o" à la fin de la ligne OBJECTS= de votre Makefile
Dans votre fichier C ou vous utilisez des divisions, ajoutez la ligne de déclaration de la fonction:
void divide32(unsigned long *dividend, unsigned long *divisor, unsigned long *quot_remainder);

Puis pour faire votre division procédez comme suit:
Au lieux de faire: A = B / C;
Faites:
unsigned long A, B, C, result[2];

divide32(&B, &C, result);
A = result[0];
Dernière modification par Orion_ le 18 août 2014 12:05, modifié 1 fois.
Programmation rétro ! Orion_'s website
__sam__
Messages : 7964
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Tutoriel GCC 6809 pour MO/TO

Message par __sam__ »

Orion_ a écrit :Le fichier de sortie ".bin" est brut, sans aucun header, si vous souhaitez avoir un fichier avec header (pour le charger avec LOADM) vous pouvez essayer le format "CoCo", changez la ligne dans le Makefile: aslink -mnwxso par aslink -mnwxst et supprimez la ligne gcchex2bin
Dans ce cas il ajoute le header: $00, Taille sur 16bits, Adresse de chargement sur 16bits
et le tailer: $FF $00 $00 $00 $00
Mais je ne sais pas si ça correspond exactement au format du basic sur thomson.
Si si ca colle au format binaire thomson.

Sinon une petite optim en asm: "<INSTR> 0,x" est plus lent que "<INSTR> ,x". Parfois les assembleurs optimisent, mais pas tous. Typiquement, je ne suis pas certain que l'assembleur utilisé par gcc optimise les "0,x" en ",x".
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Fool-DupleX
Messages : 2339
Inscription : 06 avr. 2009 12:07

Re: Tutoriel GCC 6809 pour MO/TO

Message par Fool-DupleX »

Juste pour info, Eric Botcazou avait fait sa propre version de gcc pour thomson. Elle est obsolete, mais la partie libc et surtout le lieur final au format binaire thomson seraient a mon avis interessants a reprendre et completer. Tout est sur http://nostalgies.thomsonistes.org
Avatar de l’utilisateur
Orion_
Messages : 176
Inscription : 07 août 2014 16:29
Localisation : Perpignan
Contact :

Re: Tutoriel GCC 6809 pour MO/TO

Message par Orion_ »

Fool-DupleX > Les binaires sur cette page ne marche que sous DOS, ce qui ne fonctionne plus sous Windows 7, a moins de passer par DosBox :/ Après pour bidouiller les sources du linker etc.. c'est une autre histoire.

__sam__ > je viens de m'apercevoir que le format CoCo intercale ce header tout les 32 octets ! ce ne sera donc pas compatible avec le thomson du coup :/
Programmation rétro ! Orion_'s website
__sam__
Messages : 7964
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Tutoriel GCC 6809 pour MO/TO

Message par __sam__ »

Orion_ a écrit :__sam__ > je viens de m'apercevoir que le format CoCo intercale ce header tout les 32 octets ! ce ne sera donc pas compatible avec le thomson du coup :/
C'est étrange ca de perdre 4 octets tous les 32 octets. Ca le fait tout du long du binaire ou certaines zones font 32 octets, d'autres 100 ou 200 ? Si ca varie, cela peut venir du linker qui "link" chacun des fichier .o dans son propre header. Ca lui facilite le boulot.

Sur thomson le binaire peut contenir plusieurs blocks logiques comme sur coco. Ils correspondent typiquement à des adresses de chargement non contiguës. Donc si ca se trouve le binaire coco, quoique non optimal irait parfaitement bien sur thomson. Il faut faire l'essai.

Vu que tu as perl d'installé depuis l'autre jour, voici un petit programme qui décode les binaires thomson. Tu devrais l'essayer sur les binaires CoCo pour voir si ca donne quelque chose de censé:

Code : Tout sélectionner

#!/bin/perl
#
# decode un fichier binaire thomson
#
# Samuel DEVULDER, Novembre 2012.
#

for(my $c=&getb; $c>=0; $c=&getb) {
        my($len) = &getw; last if $len<0;
        if($c==255) {
                printf "TYPE: FIN\nEXEC: 0x%04x\n\n", &getw;
        } elsif($c==0) {
                print "TYPE: DATA\nSIZE: $len\n";
                my($adr) = &getw;

                my($l) = "";
                for(my $i=0; $i<$len; ++$i, ++$adr) {
                        printf "%04x:", $adr if ($i&15)==0;
                        my($b) = &getb; last if $b<0;
                        printf " %02x", $b;
                        $l .= $b>=32 && $b<=126 ? chr($b) : ".";
                        if(($i&15) == 15) {print " $l\n"; $l = "";}
                }
                print " $l", " " x (15-($len&15)), "\n" if $len & 15;
                print "\n";
        } else {
                print "TYPE: $c\nSIZE: $len\n";
                for(my $i=0; $i<$len; ++$i) {
                        my($b) = &getb; last if $b<0;
                        printf " %02x", $b;
                        print "\n" if ($i&15) == 15;
                }
                print "\n" if $len & 15;
        }
}

# lit un word
sub getw {
        my($b1) = &getb; return $b1 if $b1<0;
        my($b2) = &getb; return $b2 if $b2<0;
        return $b1*256 + $b2;
}

# lit un octet
sub getb {
        $glb_line = <> unless length($glb_line)>0;
        return defined $glb_line?ord(substr($glb_line, 0,1, "")):-1;
}
[EDIT] utilisation d'un var fantôme dans le code corrigée.
Dernière modification par __sam__ le 18 août 2014 15:34, modifié 1 fois.
Samuel.
A500 Vampire V2+ ^8^, A1200 (030@50mhz/fpu/64mb/cf 8go),
A500 GVP530(MMU/FPU) h.s., R-Pi, TO9, TO8D, TO8.Démos
Fool-DupleX
Messages : 2339
Inscription : 06 avr. 2009 12:07

Re: Tutoriel GCC 6809 pour MO/TO

Message par Fool-DupleX »

Je ne parlais pas d'utiliser le binaire mais de reprendre le source et de l'adapter pour l'ajouter dans ta suite de developpement ... le packager n'est pas tres gros, il devrait être facile a mettre a jour. la libc thomson ne necessite en principe aucune modification, juste d'être completee ...
Linzino
Messages : 69
Inscription : 26 août 2017 02:40

Re: Tutoriel GCC 6809 pour MO/TO

Message par Linzino »

Hi everyone!

Some of the links are broken.

What is the most recent version of GCC6809 that can be used to compile C programs for the Mo5/To7?

Fabrizio
Répondre