MSX Village forum

La Place des Développeurs Mes 1ers pas sur MSX ...

Ricco59_bis Membre non connecté

Vagabond

Rang

Avatar

Inscrit le : 17/10/2020 à 17h40

Messages: 7

Le 29/12/2020 à 18h13
Hello la compagnie (je t'ai écouté aoineko ;) )

Je commence à me mettre tout doucement à la programmation sur MSX car je souhaiterai "porter'' 2 de mes jeux coleco (presque finis si je ne tiens pas compte de la musique) et je rencontre une 1ere difficulté : ma routine put_char que je souhaiterai compatible avec celle de la coleco. J'aurais donc besoin de vos lumières

Je dois faire une erreur car le caractère affiché n'est pas le bon alors que la position est correcte et comme d’habitude, ça doit être un truc tout bête mais ayant le nez dans le guidon (en plus de mon grand age), je ne vois plus :)

Voici la routine


ex : put_char(3,5,60) // x=3, y = 5, le carac a afficher se trouve à l'index 60 dans la patterntable

void put_char0(unsigned int posx, unsigned int posy, unsigned char carac)
{
posx; posy; carac;
__asm
ld l,8(ix)
ld h,#0
add hl,hl
add hl,hl
add hl,hl
push hl
ld hl,#0x0000
pop bc
add hl,bc // hl pointe sur le carac à afficher
push hl

ld hl,#0x1800
ld c,4(ix) // bc = X
ld b,5(ix)
add hl,bc // hl = 0x1800 + x
push hl

ld l,6(ix) // bc = y
ld h,7(ix)
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl

pop de
add hl,de
push hl

pop de // de = 0x1800 + y*32 + x
pop hl // hl = 0x0000 + Carac * 8
ld bc,#0x0001 // longueur = 1 carac
call 0x005c


__endasm;
}


En espérant avoir été clair.
Merci d'avance pour votre aide les zamis

Eric Edité par Ricco59_bis Le 29/12/2020 à 20h52


Voici ce que j'ai pu faire depuis... bien longtemps ;)
https://www.youtube.com/user/retro8059000
   
Sector28 Membre non connecté

Villageois

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 12/05/2018 à 23h00

Messages: 552

Le 29/12/2020 à 18h27
Code ASM :
void put_char0(unsigned int posx, unsigned int posy, unsigned char carac)
{
posx; posy; carac;
__asm
ld de,8
push ix
pop hl
add hl,de
push hl
 
ld hl,#0x1800
ld c,4(ix) // bc = X
ld b,5(ix)
add hl,bc // hl = 0x1800 + x
push hl
 
ld l,6(ix) // bc = y
ld h,7(ix)
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl
 
pop de
add hl,de // de = 0x1800 + y*32 + x
push hl
 
pop de // de = 0x1800 + y*32 + x
pop hl // hl = 0x0000 + Carac * 8
ld bc,#0x0001 // longueur = 1 carac
call 0x005c
 
 
__endasm;
}


Toute matrice carrée sur un corps K, dont le polynôme caractéristique est scindé, est semblable à une matrice de Jordan. Cette réduction est unique à l'ordre des blocs près. De plus, toute matrice carrée nilpotente sur un corps K est semblable à une matrice de Jordan dont chaque bloc est associé à la valeur 0. Évidement, cette réduction est encore unique à l'ordre des blocs près...
:)
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2693

Le 29/12/2020 à 19h42
Salut Ricco, ;)
Tu souhaites utiliser quel screen mode ?
(cf. https://www.msx.org/wiki/SCREEN)


On est toujours ignorant avant de savoir.
Github    
Ricco59_bis Membre non connecté

Vagabond

Rang

Avatar

Inscrit le : 17/10/2020 à 17h40

Messages: 7

Le 29/12/2020 à 20h39
@ quelques explications Sector28 ?

@ aoineko > screen 2

merci à vous 2


Voici ce que j'ai pu faire depuis... bien longtemps ;)
https://www.youtube.com/user/retro8059000
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2693

Le 29/12/2020 à 22h55
Je suis assez noob avec le MSX1 (je ne fais que du MSX2) mais si je devais faire une fonction put_char() je ferais :
- récupérer l'adresse de la Pattern Layout Table en VRAM (stocké par le Bios en RAM à l'adresse F3C7h, nommé GRPNAM)
- j'y ajouterai 32*y+x
- j'écrirais à cette adresse la valeur de mon caractère (directement via l'accès aux ports du processeur graphique)

Tu peux aussi passer par la fonction du Bios en 005Ch (nommé LDIRVM).
Dans ce cas, il te faut ce setup :
- BC : Block length (1 dans ton cas)
- DE : Start address of VRAM
- HL : Start address of memory

A priori, c'est ce que fait ta fonction et celle de Sector28.
J'ai du mal à lire l'assembleur que j'ai pas écris, donc je ne saurai te dire s'il y a une erreur qq part.

Je sais pas si tu as vu, mais dans le cas du Screen mode 2, il y a 3 Pattern Generator Table (font) :
- une pour le haut de l'écran (lignes 0 à 7)
- une pour le milieu (lignes 8 à 15)
- et une pour le bas (lignes 16 à 23)

Donc si tu veux les mêmes caractères partout, il te faut les copier dans ces 3 tables.


On est toujours ignorant avant de savoir.
Github    
Ricco59_bis Membre non connecté

Vagabond

Rang

Avatar

Inscrit le : 17/10/2020 à 17h40

Messages: 7

Le 29/12/2020 à 23h24
Merci Aoineko,

Oui, pour les 3 zones c'est comme sur Coleco.
Concernant les ports graphiques, je n'y ai jamais rien compris... Peut etre que ce n'est pas si compliqué mais une chose à la fois ;)

J'ai trouvé la solution, j'utilise Fillvram
hl = 0x1800 + x + y*32
bc = 1 (nb de carac à afficher)
a = le caractère à afficher

put_char1(unsigned int posx, unsigned int posy, unsigned char carac)
{
posx; posy; carac;
__asm

ld hl,#0x1800
ld c,4(ix) // bc = X
ld b,5(ix)
add hl,bc // hl = 0x1800 + x
push hl

ld l,6(ix) // bc = y
ld h,7(ix)
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl

pop de
add hl,de // position où doit etre ecrit le carac
ld bc,#0x0001 // longueur = 1 carac
ld a,8(ix)
call 0x0056 // Fill VRAM

__endasm;
}


La routine citée dans mon 1er post, n'est pas valable dans ce cas car elle attend une adresse en HL. dans ce cas, je dois faire ça :


//déclarations -----------------------------------------------------------
const unsigned char toto[] = {10,5,12,17};
unsigned char *ptoto;

// le code ----------------------------------------------------------------
void put_char0(unsigned int posx, unsigned int posy, char *carac)
{
posx; posy; carac;
__asm
ld l,8(ix)
ld h,9(ix)
push hl

ld hl,#0x1800
ld c,4(ix) // bc = X
ld b,5(ix)
add hl,bc // hl = 0x1800 + x
push hl

ld l,6(ix) // bc = y
ld h,7(ix)
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl

pop de
add hl,de
push hl

pop de // de = 0x1800 + y*32 + x
pop hl // hl = adresse table des carac à afficher
ld bc,#0x0001 // longueur = 1 carac
call 0x005c

__endasm;
}

// l'utilisation ---------------------------------------------------------------------
ptoto = (unsigned char *) &toto[0];

put_char0(3,2,ptoto); // dans ce cas n'affichera qu'un carac (10). Il suffit que je rajoute le param LENGTH par ex et je pourrai afficher de 1 à 32 caracs. Si plus il faut que je fasse des calculs pour afficher une zone de 5 caracs sur 5 lignes ou 8 carac sur 44 lignes... j'l'ai pas essayé encore car trop content d'avoir fait mon put_char ;)



Voili voilou

Bonne nuit et merci ;) Edité par Ricco59_bis Le 29/12/2020 à 23h41


Voici ce que j'ai pu faire depuis... bien longtemps ;)
https://www.youtube.com/user/retro8059000
   
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2693

Le 30/12/2020 à 00h02
Super :top

Juste un truc, si tu comptes garder le Bios (ce qui est surement le cas), je te conseil de récupérer l'adresse de la Pattern Layout Table dans la RAM plutôt que de l'écrire en dure dans ta fonction.
Si tu utilises le Bios pour initialiser le Screen Mode 2 via les routines du Bios (comme 0072h / INIGRP), tu as l'adresse VRAM de ta table à F3C7h (GRPNAM).

Du coup, normalement tu peux juste remplacer :
ld hl,#0x1800

Par :
ld hl,(#0xF3C7)



On est toujours ignorant avant de savoir.
Github    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 02/01/2021 à 12h44
Salut les zamis :)

Bon j'ai un gros soucis de connexion avec mon pseudo ricco59. Ce n'est plus le bon pseudo, dorénavant c'est ericm59 :)

@aoineko, je poste un message qui aurait etre posté il y a quelques jours


Concernant GRPNAM (F3C7h > 0x1800), je l'ai implémenté mais quel est l'intéret ? cette adresse
ne change-t-elle pas avec d'autres machines (msx2, 2+ ou turbo) ?

Voici où j'en suis :
- put_char .... ok
- sprites ..... ok
- vsync ....... ok (si on considère que HALT fait l'affaire ;) )

une tite video pour ceux qui veulent ;)
c'est ic > https://youtu.be/-rrW28Qdhbw

j'ai encore un souci pour les sprites tout fonctionne.
Lorsque je déclare mes sprites comme suit...

ZeZone[0].pattern = (13+0)*4; // sprite PRESENTS inférieur
ZeZone[0].colour = 15;
ZeZone[0].x = 13*8+0*16;
ZeZone[0].y = 16*8;
ZeZone[1].pattern = (13+1)*4; // sprite PRESENTS inférieur
ZeZone[1].colour = 15;
ZeZone[1].x = 13*8+1*16;
ZeZone[1].y = 16*8;
ZeZone[2].pattern = (13+2)*4; // sprite PRESENTS inférieur
ZeZone[2].colour = 15;
ZeZone[2].x = 13*8+2*16;
ZeZone[2].y = 16*8;
ZeZone[3].pattern = (13+3)*4; // sprite PRESENTS inférieur
ZeZone[3].colour = 15;
ZeZone[3].x = 13*8+3*16;
ZeZone[3].y = 16*8;

put_vram(0x1b00,ZeZone,128);

... mes sprites s'affichent bien mais lorsque je fais une boucle qui reprend les éléments ci-dessus

for (Ze_Boucle = 0 ; Ze_Boucle < 4 ; ++Ze_Boucle)
{
ZeZone[Ze_Boucle].pattern = (13+Ze_Boucle)*4;
ZeZone[Ze_Boucle].colour = 15;
ZeZone[Ze_Boucle].x = 13*8+Ze_Boucle*16;
ZeZone[Ze_Boucle].y = 16*8;
}
put_vram(0x1b00,ZeZone,128);

rien ne s'affiche. Bizarre non ?? un ptit éclaircissement ?

Prochaine étape : le joystick et le menu et bien sûr d'autres questions :)

A+ les zamis


Ericm59 (Ricco59) Edité par Ricco59 Le 02/01/2021 à 12h46


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 02/01/2021 à 15h19
hep hep hep ! monsieur Ericm59, y aurait pas comme un problème d'ordre dans tes attributs ?








Edité par ericb59 Le 02/01/2021 à 19h31


banniere-ericb59e
Site web    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 02/01/2021 à 16h58
Salut Eric

Pour garder ma comptabilité avec la colecovision, j'ai gardé cette structure

typedef struct
{
char y;
char x;
char pattern;
char colour;
} sprite_t;

le Y et X sont inversés sur MSX



Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 02/01/2021 à 17h49
montre un peu le code de ta fonction : put_vram


banniere-ericb59e
Site web    
aoineko Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : Shoutbox

Inscrit le : 02/01/2011 à 21h17

Messages: 2693

Le 02/01/2021 à 17h57
Salut Ricco,

Si tu veux, je peux renommer ton nouveau compte en ricco59 (et l'ancien en ricco59_bis par ex.).

Pour GRPNAM, c'est justement le meilleur moyen d'assurer la compatibilité avec tous les MSX et surtout, ça permet que ta fonction marche, même si tu déplaces les données des sprites en VRAM.
Je sais pas pour la Colleco, mais sur MSX, tu peux organiser les données en VRAM comme ça t'arrange (ce qui est très pratique pour certains jeux).

Pour la structure des attribues de sprites en VRAM, tu as raisons. C'est bien le Y en premier.
Par contre, je comprends pas pourquoi ta boucle fonctionne pas alors que la version déroulé fonctionne.
Il faudrait voir le reste du code pour te dire.


On est toujours ignorant avant de savoir.
Github    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 02/01/2021 à 19h08
Salut Aoineko,

oui, tu peux transformer ericm59 en ricco59, no soucaille ;)

@Eric, voici mon put_vram
void put_vram(int vramaddr, void* block, int size)
{
vramaddr; block; size;
__asm
ld l,6(ix)
ld h,7(ix)
ld e,4(ix)
ld d,5(ix)
ld c,8(ix)
ld b,9(ix)
call LDIRVM
__endasm;
}


Voili, voilou

Pendant 1h, je me suis battu avec gtstck et gttrig et bien... je me suis pris une raclée hihihi
Je ne m'avoue pas vaincu ;)

Bonne soirée les zamis


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
ericb59 Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 17/04/2012 à 10h25

Messages: 5481

Le 02/01/2021 à 19h33
Par Ła barbe du grand cornu ! Oui je me suis trompais, c'est bien la coordonnée Y en premier, dire que j'ai écrit l'inverse dans ma DOC ! J'ai corrigé ! Ouf ! J'espère que je ne serai pas damné pour ça !

Pour ta routine, ne faudrait il pas écrire ceci ?

Code C :
 
void put_vram(int vramaddr, void* block, int size)
{
vramaddr; block; size;
_asm
    push ix
 
    ld ix,#0
    add ix,sp
    ld l,6(ix)
    ld h,7(ix)
    ld e,4(ix)
    ld d,5(ix)
    ld c,8(ix)
    ld b,9(ix)
    call LDIRVM
    pop ix
    ret
__endasm;
}
 




Pour la routine de lecture de joystick :

Code C :
 
char Joystick(char JoyNumber) __naked
  {
      JoyNumber;
      __asm
              push ix
 
            ld ix,#0
            add ix,sp
            ld a,4(ix)
 
            call #0xD5 ; GTSTCK
            ld l,a
            pop ix
            ret
      __endasm;
  }
 



ou bien comme ça :

Code C :
 
 
char Joystick(char JoyNumber) __z88dk_fastcall __naked
  {
      JoyNumber;
      __asm
            ld a,l
            call #0xD5 ; GTSTCK
            ld l,a
 
            ret
      __endasm;
 
  }
 
 


JoyNumber :
0 = clavier
1 = port A
2 = port B Edité par ericb59 Le 02/01/2021 à 20h05


banniere-ericb59e
Site web    
Ricco59 Membre non connecté

Villageois

Rang

Avatar

Inscrit le : 02/01/2021 à 11h22

Messages: 248

Le 02/01/2021 à 20h59
hello,

@Guillaume, merci pour la modif ;)

@Eric
>> n'oublie pas de mofier le ab02 pattern number par 1b02

il me semble que sdcc ajoute automatiquement

au debut de ta fonction asm
push ix
ld ix,#0
add ix,sp

et à la fin
pop ix

sauf si tu lui mets __naked

pour gtstck,
voila ce que je fais
unsigned char get_stick(unsigned char choix)
{
choix;
__asm
ld a,4(ix)
call 0x005d
ld hl,#_Direction // direction = variable globale dans laquelle est stockée l'une des 8 directions
ld (hl),a
__endasm;
}


Si je comprends ta 2e routine,
ld a,l est equivalent à ld a,4(ix)
et pour
ld l,a le registre 'l' récupère directement la 'direction' ??

je pourrais donc écrire : direction = Joystick(0); par exemple pour le clavier
et faire
switch (direction) ou directement switch ( Joystick(0))
case 0 : blabla; break;
case 1 : blabla; break;
case 2 : blabla; break;
..
..
case 8 : blabla; break;

?

j'ai encore bcp à apprendre ;)

Merci en tout cas

Bonne soirée

Eric Edité par Ricco59 Le 02/01/2021 à 21h04


Tous mes travaux sont centralisés sur mon piti blog : https://ricco59.blogspot.com/
E-mail    
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie