Question débutant 6809

Cette catégorie traite de développements récents pour 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

Répondre
Avatar de l’utilisateur
z80¯\_(ツ)_/¯
Messages : 77
Inscription : 06 oct. 2020 13:15
Localisation : Bourgogne

Question débutant 6809

Message par z80¯\_(ツ)_/¯ »

Bonjour,
Je voudrais savoir s'il est possible en assembleur 6809 de sauvegarder le PC dans la pile mais en lui ajoutant un nombre de façon à reprendre légèrement plus loin après un RTS dans une sous routine après un branchement.

Je ne sais pas si je suis clair mais en gros, un truc du genre :

PSHS PC + 2
CMPD #0
BGE UPDATE_P1 * Branchement routine (et je voudrais qu'un RTS dans la sous routine me rebranche à la ligne juste en dessous)
REPRISE APRES RTS (dans la sous routine)
Zebulon
Messages : 2788
Inscription : 02 nov. 2020 14:03

Re: Question débutant 6809

Message par Zebulon »

Je pense que ce problème n'est pas spécifique au 6809. Revenir d'une sous-routine avec un RET (RTS) alors qu'elle n'a pas été appelée par un CALL mais uniquement un saut donc adresse de retour non empilée.

Je ne pense pas qu'un seul processeur 8-bit permette de faire des opérations d'addition sur une instruction PUSH. A mon avis il faut charger l'adresse de retour indiquée par un label sur l'instruction dans un registre puis faire un PUSH de ce registre avant le saut.

J'ai aussi vu des routines sur CPC où la valeur de retour était PUSHée juste avant le RET dans la sous routine...

Dès lors qu'on sait que le RET va dépiler une valeur pour la mettre dans PC et continuer l'exécution on peut bricoler ce qu'on veut tant qu'on retombe toujours sur nos pattes.

On a beaucoup décrié le Basic comme étant le langage des programmes spaghetti mais je crois qu'on fait bien pire en assembleur. :wink:

EDIT il ne faut pas sous-estimer la puissance des labels/étiquettes car c'est l'assembleur qui va faire l'énorme travail de calculer l'adresse au final et à chaque modif du programme le calcul est actualisé.
Fool-DupleX
Messages : 2284
Inscription : 06 avr. 2009 12:07

Re: Question débutant 6809

Message par Fool-DupleX »

Mais pourquoi pas juste un BLO ou BMI skip_jump suivi d'un jsr ?

Code : Tout sélectionner

CMPD #0
BLO skip_jump
jsr routine
skip_jump:
REPRISE APRES RTS 
au moment ou tu fais ton "PSHS PC+2" le PC est déjà apres le PSHS, donc le but c'est de revenir au milieu du CMPD ? Pas sur de comprendre.

le JSR n'est rien d'autre qu'un PSHS PC suivi d'un JMP, donc pour sauter ailleurs, il suffit de faire un STX #adr, PSHS X, JMP routine.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: Question débutant 6809

Message par Daniel »

On ne peut pas empiler PC augmenté de 2 avec une seule instruction.
Il faut transférer PC dans un autre registre 16 bits, par exemple X, ajouter 2 à X et empiler X.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: Question débutant 6809

Message par hlide »

Ce que tu veux faire, c'est l'équivalent en Z80 :

Code : Tout sélectionner

    OR      A
    CALL    NS, UPDATE_P1
    ...
, non ?

C'est à dire on ne saute à UPDATE_P1 que si A >= 0 ? si c'est le cas, je pense que la réponse de Fool-Duplex est la plus appropriée. Je ne crois pas qu'en passant par un PSHS, on y gagne en nombre de cycles et d'octets et de registre consommé.

Pour un cas plus général avec un PC + n, une fois de plus il peut y avoir une solution mieux adaptée. Le tout est de ne pas se laisser enfermé par cette idée de vouloir faire comme ça comme c'est très souvent le cas.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Question débutant 6809

Message par __sam__ »

Hum

Code : Tout sélectionner

PSHS PC + nnnn
Je pense que tu souhaites un truc à la Push the Effective Adresse

Code : Tout sélectionner

PEA nnnn(PC)
du 68000, grand frère du 6809. Hélas cela n'existe pas sur cette génération. Cependant il y a plein de façon de le faire quand même en trashant des registres:

Code : Tout sélectionner

LEAX LABEL_REPRISE,PCR   ; ou LDX #LABEL_REPRISE si on ne veut pas faire de code relogeable.
PSHS X   ; on peut remplacer X par D si on fait du LDr au lieu de LEAr (LEAD n'existe pas)
ou encore

Code : Tout sélectionner

PSHS PC
LDD  #N (à ajuster en fonction des instruction qui suivent pour bien empiler LABEL_REPRISE)
ADDD ,S
STD  ,S
A noter que tu peux même te passer du PSHS X/RTS dans la 1ere option en faisant un "JMP ,X" au lieu du RTS.

Mais je pense que dans ton cas la solution de fool est la mieux: retourne avec à BRA/JMP à l'adresse "PC+2" que tu voulais. C'est plus dans l'esprit 6809.
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
Avatar de l’utilisateur
z80¯\_(ツ)_/¯
Messages : 77
Inscription : 06 oct. 2020 13:15
Localisation : Bourgogne

Re: Question débutant 6809

Message par z80¯\_(ツ)_/¯ »

Merci pour toutes ces informations.
Je vais tester tout ça.
Avatar de l’utilisateur
z80¯\_(ツ)_/¯
Messages : 77
Inscription : 06 oct. 2020 13:15
Localisation : Bourgogne

Re: Question débutant 6809

Message par z80¯\_(ツ)_/¯ »

J'ai testé :

Code : Tout sélectionner

	PSHS PC					* PC dans la pile S
	LDD #10					* 10 dans D
	ADDD ,S					* ajoute S dans D
	STD ,S					* sauvegarde D dans S
	JMP DRAWXY				* JMP avec RTS dans la sous routine
	NOP					* Le RTS de la sous routine reprend bien ici
Ca fonctionne.
Pouvez-vous me confirmer que le 10 vient du fait qu'on doit passer 4 instructions (donc 8 octets) et se positionner sur la cinquième (donc 10 octets) par rapport au PSHS PC ?
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: Question débutant 6809

Message par __sam__ »

z80¯\_(ツ)_/¯ a écrit : 05 août 2021 13:18 Pouvez-vous me confirmer que le 10 vient du fait qu'on doit passer 4 instructions (donc 8 octets)
Non pas "donc". Les instructions ne sont pas de taille unique. Un LDD #nnnn prends 3 octets, un "ADD ,S" en prends 2, un NOP un seul. Fais une execution pas à pas dans l'émulateur pour voir si le calcule te donne bien l'adresse du NOP. C'est le plus simple. (sinon si on préfère le calcul théorique à l'expérimentation sous émulateur on a: "LDD #10"=3, "ADD ,S"=2, "STD ,S"=2, "JMP PLOTXY"=3. TOTAL=10)

Mais plus simple encore est d'utiliser un LABEL. L'assembleur va faire le calcul pour toi:

Code : Tout sélectionner

  PSHS PC 
  LDD  #REPRISE-* (* = La valeur de PC qui vient juste d'être empilée)
  ADDD ,S
  STD  ,S
  JMP  DRAWXY
  .. blabla ..
REPRISE
  NOP
Mais si tu te fiche de la relogeabilité, alors ceci est encore plus simple:

Code : Tout sélectionner

	LDD #REPRISE	* ou / LEAX REPRISE,PCR
	PSHS D		*    \ PSHS X
	JMP DRAWXY	* JMP avec RTS dans la sous routine
REPRISE
	NOP		* Le RTS de la sous routine reprend bien ici
Mais attends, REPRISE est juste après le JMP. Je suppose que c'est ainsi parce que le code est simplifié par rapport à ce que tu veux faire vraiment, mais dans ce cas tu peux faire directement

Code : Tout sélectionner

	JSR DRAWXY	* Empile le PC sur l'instruction (suivante) et saute (JMP) dans la sous routine
	NOP		* Le RTS de la sous routine reprend bien ici 
JSR c'est juste fait pour reprendre immédiatement après justement.
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 : 2284
Inscription : 06 avr. 2009 12:07

Re: Question débutant 6809

Message par Fool-DupleX »

Et donc, quel est l'intérêt de se compliquer ainsi la vie ?
Avatar de l’utilisateur
z80¯\_(ツ)_/¯
Messages : 77
Inscription : 06 oct. 2020 13:15
Localisation : Bourgogne

Re: Question débutant 6809

Message par z80¯\_(ツ)_/¯ »

C'est très intéressant
Répondre