Oh zut, je me suis focalisé sur le mauvais lièvre. En fait la GUI du débuggeur de TEO n'affiche pas le bit C alors qu'il est présent (CC=$D9 est impair) sur la dernière capture.
Bon par contre ca veut dire que
Code:
SBCB 1,U
SBCA ,U ; A=$FF CC(teo)=$8B CC(dcmoto)=$89
BLT outTRUE
BGT outFALSE
ne fonctionne pas pareil entre DCMoto/Mess et TEO. En effet, sous TEO après le SBCA, on a CC=$8B alors que sous DCMoto CC=$89. La différence entre les deux est que TEO positionne V=1 contrairement à DCMoto et MESS.
Le code du SBCA pour TEO est celui-ci:
https://sourceforge.net/p/teoemulator/c ... 09.c#l2163Code:
value=LoadByte(address); /* value = 0 */
m1=ar; m2=-value; /* ar = 0; m1 = 0; m2 = 0; */
ar-=value+((res&0x100)>>8); /* ar = -1 */
ovfl=res=sign=ar; /* ovfl=res=sign = -1 */
ar&=0xff; /* ar = 255 */
Un truc me turlupine: pourquoi m2 = -value sans tenir compte de la retenue ? La soustraction sur ar c'est avec value+((res&0x100)>>8), donc logiquement il faudrait soustraire ((res&0x100)>>8) aussi à m2. La différence entre les émulateurs vient peut-être de là.
Si je regarde un implémentation indépendante des SBCA/B, par exemple celle-ci:
https://github.com/maly/6809js/blob/mas ... 9.js#L1319Code:
var oSBC = function (b, v) {
var temp = b - v - (CC & F_CARRY);
//temp &= 0xff;
CC &= ~(F_CARRY | F_ZERO | F_OVERFLOW | F_NEGATIVE);
CC |= flagsNZ[temp & 0xff];
if (temp & 0x100) CC |= F_CARRY;
setV8(b, v, temp);
return temp & 0xff;
};
Examinons ce qu'il se passe. On calcule temp = b - v - retenue = 0 - 0 - 1 = -1. Ok, ensuite ca calcule les flags N, Z et C dont on se fiche. Le calcul de V se fait dans setV8
Code:
setV8 = function (a, b, r) {
CC |= ((a ^ b ^ r ^ (r >> 1)) & 0x80) >> 6;
};
en l'occurrence ici on a: a=0, b=0, et r=-1 donc "a ^ b ^ r ^ (r >> 1)" = "0 ^0 ^ -1 ^ (-1>>1)" = "0^0^-1^-1" = 0. On ne devrait donc pas positionner V d'après ce simulateur 6809 en JS.
Voyons ce qu'il se passe si, dans teo, on mettais la retenue dans le calcul de m2. C'est à dire, qu'on calcule m2 = -value - ((res&0x100)>>8) = 0 - 1. Donc
Code:
V= (!((m1^m2)&0x80))&&((m1^ovfl)&0x80)
== (!((0^-1)&0x80)) && ((0^-1)&0x80)
...
== (!(0x80)) && (0x80)
== (!true) && true
== false
Humm on dirait que ce coup-ci V=0. C'est la bonne valeur !
Ca semble être un bon candidat au bug.
Ce qui m'ennuie c'est que ADCA/ADCB ont le même défaut (m2 ne tient pas compte de la retenue), et que surtout ce code est super super vieux (de Marcel-O-5 au moins) et que personne n'est tombé sur ce bug avant. Bon, après, il faut peut-être être un tordu comme moi pour faire de l'arithmétique multi-précision sur 8bits pour le découvrir...
Gilles: tu en penses quoi ?