Dans le cadre d’un développement 6502, pour la console portable Lynx, je souhaite transformer en langage d’assemblage une partie du code C composé de boucle for. Ces boucles sont en effet très gourmandes en ressource machine ! J'imagine que le fonctionnement 6502 et x86 est à peu près le même, avec possibilité de transfert de données dans les registres du CPU et adresse mémoire.
assembleur Lynx: RA65.exe et LYXASS.exe
et un LIBR65.EXE qui doit concerner les librairies.
Ci-dessous, un exemple basique de ma conception, en asm (dans la procédure Vtest():
Code : Tout sélectionner
uchar vac=0x00; // déclaration variable testable en assembleur
uchar vac=0x01; // si j'active cette ligne, la variable vac sera donc mis à 1, ce qui provoquera avec la commande BNE une boucle infini.
void Vtest()
{
#asm
rretour:
clc ; mise à 0 de l'Accumulateur
lda _vac ; charge le contenu de la variable vac dans l'Accumulateur du 6502
bne rretour ; Si Accumulateur > 0 Alors goto rretour
#endasm
};
// et enfin l'appel de la procédure, donc à placer dans la boucle principale:
Vtest(); // si vac=0x01 alors le programme se bloque comme prévu (c’est juste pour tester voyez).
Code : Tout sélectionner
// manual clear of collision buffer
void clear_coll_buffer(void) {
#asm
pha
phx
phy
lda #0
ldy #10
loop0 ldx #0
loop1 sta $9C60,x
dex
bne loop1
dey
bne loop0
ply
plx
pla
#endasm
}
******************** LDA STA
Et voici le code en C:
Code : Tout sélectionner
// ** LDA STA ******************************************
// ** Ci-dessous le code à transformer en asm 6502 ***
// *******************************************************
// Tout d'abord, voici la déclaration des variables:
int col_x, tile_x, grpx, lecx, comptx, compty, brnbr, level, tlnb;
uchar tbr01[7][56]=
{
{0,0,0,0,0,23,24,25,26,27,0,0,0,0,0,0,0,0,0,23,24,25,26,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,7},
{0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,19,20,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
{0,0,0,0,0,15,16,17,18,0,0,0,0,15,0,0,0,0,0,0,16,17,18,0,0,0,1,7,28,28,28,1,7,0,0,0,0,0,0,0,1,7,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
{12,13,12,13,12,14,12,14,12,13,12,13,12,14,12,13,12,13,12,13,12,14,12,13,12,13,12,13,12,13,12,13,12,13,12,13,0,0,1,3,2,8,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
{10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,10,11,1,3,5,7,10,11,10,11,10,11,10,11,10,11,10,11,1,3,5,3,2,8,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
{1,3,5,7,9,9,9,9,9,9,1,3,5,3,5,3,5,3,5,7,2,4,6,8,7,9,9,9,9,9,9,1,3,5,3,5,3,5,5,5,2,8,0,0,0,0,0,0,0,0,0,0,0,0,2,8},
{2,4,6,8,3,5,3,5,3,5,2,4,6,4,6,4,6,4,6,8,2,4,6,8,8,3,5,3,5,3,5,2,4,6,4,6,4,6,6,6,2,8,3,5,3,5,3,5,3,5,3,5,3,5,2,8}
};
// Ci-dessous, vous voyez le code en C que je souhaite tranformer en asm. Ce code est situé dans la boucle principale :
col_x+=1;
if (col_x>23)
{
col_x=0;tile_x+=1;
for(grpx=0 ; grpx<6; grpx++) // de 0 à 5, ce qui fait 6 tests voyez.
{
for(lecx=(grpx*8) ; lecx<(grpx*8)+8; lecx++) // de 40 à 47, ce qui fait 8
{
if (tile_x == 2+lecx)
{
comptx = 8+lecx;brnbr = 7*(lecx-(grpx*8));
for(compty=0 ; compty<7; compty++) // de 0 à 6, ce qui fait 7
{
if (level==1)
{
tlnb=24;tlnb=tlnb+brnbr;
SCBDATA(&SCB[tlnb][0]) = dctab[tbr01[compty][comptx]%29];
SCBX(&SCB[tlnb][0]) = comptx*24;
SCBY(&SCB[tlnb][0]) = compty*24;
++brnbr;
}
}
}
}
}
}
col_x-=1;
if (col_x<1)
{
col_x=24;tile_x-=1;
for(grpx=0 ; grpx<6; grpx++) // de 0 à 5, ce qui fait 6
{
for(lecx=(grpx*8) ; lecx<(grpx*8)+8; lecx++) // de 40 à 47, ce qui fait 8
{
if (tile_x == 1+lecx)
{
comptx = lecx;brnbr = 7*(lecx-(grpx*8));
for(compty=0 ; compty<7; compty++) // de 0 à 6, ce qui fait 7
{
if (level==1)
{
tlnb=24;tlnb=tlnb+brnbr;
SCBDATA(&SCB[tlnb][0]) = dctab[tbr01[compty][comptx]%29];
SCBX(&SCB[tlnb][0]) = comptx*24;
SCBY(&SCB[tlnb][0]) = compty*24;
++brnbr;
}
}
}
}
}
}
http://www.mirari.fr/gBdW