[MZ-700] Fichier WAV étonnamment complexe

Placez ici vos trucs et astuces, étalez sans retenue votre savoir-faire et votre science qui va nous permettre de redonner une apparence neuve et fonctionnelle à nos bouzes.

Modérateurs : Papy.G, fneck, Carl

Avatar de l’utilisateur
hlide
Messages : 3495
Inscription : 29 nov. 2017 10:23

[MZ-700] Fichier WAV étonnamment complexe

Message par hlide »

Un gars qui a conçu un jeu m'a passé l'enregistrement WAV du seul exemplaire de son jeu sur cassette pour l'aider à le récupérer. Je ne fournirais aucun fichier ici puisque je n'arrive pas à comprendre ce qu'il veut en faire et ne me répond plus.

Néanmoins j'ai trouvé le sujet très intéressant techniquement car le plus étonnant c'est que ce WAV contenait plusieurs blocs de données qui est assez rare dans la logithèque du MZ-700 car on a généralement un bloc d'entête de 128 octets décrivant le seul bloc de données qui suit (99%). Occasionnellement un ou deux blocs qui suivent.

Là il y avait un bloc d'entête et 8 blocs de données ! dans le détail, il y a :
- bloc 1 : entête pour le bloc 2, contient également deux entêtes partiels pour le bloc 3 et 4.
- bloc 2 : donnée, affiche directement à l'écran des caractères. A 1200 baud, ça fait très minitel.
- bloc 3 : donnée, affiche directement à l'écran des couleurs. Pareil, très minitel.
- bloc 4 : donnée, code "loader" pour chargement des autre blocs à suivre (partie 1 jusqu'à partie 5). Il contient dans son code les autres entêtes partielles des blocs à suivre et le message à afficher entre chaque chargement de bloc.
- bloc 5 : donnée, partie 1
- bloc 6 : donnée, partie 2
- bloc 7 : donnée, partie 3
- bloc 8 : donnée, partie 4
- bloc 9 : donnée, partie 5

Deux de ces parties sont déplacées dans une autre zone de mémoire vive via un changement de banque : la mémoire vive instantanée n'est que de 48 Ko sur un total de 64 Ko via le bank-switching mais là il n'y a pas loin de 58 Ko de chargement si on exclut les blocs 2 et 3.

Comment ça charge ? il y a une zone de mémoire de 128 octets (à partir de $10F0) qui sert à contenir la dernière entête lue. Une bonne partie est un champ de commentaire or le bloc 1 y stocke deux entêtes et leur code pour les lire sans leur commentaire. le code consiste à copier l'entête partiel dans cette zone de mémoire et à faire un appel à une routine de lecture de bloc de donnée (call $04F8) qui se sert de cette zone de mémoire pour déterminer la taille et l'adresse de chargement. Et enfin, le code fait un JP sur le code suivant de chargement.

On retrouve ce même motif sur le code du loader (bloc 4) sauf que entre deux chargements il affiche un message indiquant quelle partie est en cours de chargement.

Le problème, c'est que je n'ai pas découvert tout ça sans devoir me confectionner des outils. En effet, la qualité du WAV était trop mauvaise pour le seul émulateur (EmuZ-700) en mesure de lire des multiples blocs. Il me fallait donc extraire tous ces blocs. Je dois aussi passer par Audacity pour "resampler" et "amplifier" les signaux.

Dans un premier temps j'ai pensé à créer un fichier MZT qui est la concaténation de tous ces blocs. Idée qui sera vouée à l'échec car on perd l'information de la taille des blocs 3 à 9 que l'émulateur ne peut pas deviner.

Néanmoins, j'essaie. J'ai besoin d'extraire les blocs du fichier WAV. Je connais cet outil donc je pars sur cette base. Sauf que ça ne fonctionnera pas si je laisse tel quel donc je dois l'adapter pour qu'il sache leur taille et leur adresse. Il reste deux blocs qui ne sont pas extraits : je vois une séquence répétée de 9 bit à 0 (pulsions courtes) alors que le neuvième bit à encoder un octet devrait être à 1 (pulsion longue) - je retire ce test et j'obtiens enfin les deux blocs manquants. Le checksum pour chaque bloc est bien vérifié. Pour chaque bloc l'outil crée un fichier MZF (bloc entête de 128 octets et un bloc de données). J'en profite pour créer un MZT qui sera la concaténation de tous ces blocs.

C'est un demi-échec avec l'émulateur, je vois bien qu'il lit tous les blocs mais la machine interprète mal les autres blocs.

J'ajoute à l'outil la création d'un fichier WAV artificiel mais propre avec au passage pas mal d'optimisation (suppression des silences, raccourcissement des gaps et la partie basse d'une pulsation exprimant le bit 1 - avant j'avais 21 tics haut et 21 tics bas puis j'ai passé à 11 tics bas car seuls le nombre contigu de tics servent à déterminer le bit 0 ou 1 - est réduite). Après avoir corrigé une bourde sur la longueur des échantillons dans l'entête RIFF, je parviens à lancer ce programme sous l'émulateur !

Voici avec le logiciel Audacity le chemin parcouru :
Beyond-new-WAV.jpg
Beyond-new-WAV.jpg (477.61 Kio) Consulté 2299 fois
Vous noterez que j'aurais réduit le temps de chargement à la moitié - ce qui m'a surpris pour tout vous dire.

Cette réduction m'a donné une idée : et si je pouvais compresser chaque bloc avec l'outil mz7c (ZX7 appliqué sur du MZF) ?

Avec mzfdisas, je peux consulter le contenu de chaque MZF et désassembler/dumper une partie du contenu. J'ai donc pu analyser la faisabilité et je me suis dit qu'il y avait des chances pour que ce soit réalisable.

J'ai compressé les fichiers MZF en fichier MZ7 et apporté des modifications dans le bloc 1 et 4 pour prendre en compte les nouvelles tailles, les nouveaux adresses de chargement et d'exécution (du travail itératif voire récursif). La compression utilise un décompresseur qui est copié dans le tampon clavier pour y exécuter la décompression puis il saute à l'adresse d'exécution d'origine.

Evidemment je dois faire un outil qui extrait les blocs des fichiers MZ7 et MZF (seuls les blocs 1 à 3 - écran d'introduction - ne sont pas compressés donc MZF pour ceux-là) et me crée un fichier WAV artificiel optimisé et propre. Et là miracle, l'émulateur est trop content de me lancer le jeu !

Voici ce que ça donne sous Audacity :
Beyond-new-WAV-compressed.jpg
Beyond-new-WAV-compressed.jpg (390.92 Kio) Consulté 2299 fois
La compression est saisissante n'est-ce pas ? je vous avoue que je m'attendais pas à de telles compressions sur certain blocs :
- bloc 4 (loader): 520 -> 275 octets
- bloc 5 (part 1): 4081 -> 1561 octets
- bloc 6 (part 2): 12057 -> 1578 octets
- bloc 7 (part 3): 12288 -> 4464 octets
- bloc 8 (part 4): 6609 -> 1982 octets
- bloc 9 (part 5): 22841 -> 9596 octets

Passer de 12 à 6 puis moins de 3 minutes.

Je ne vous cache pas que les blocs 2 (1 Ko) et 3 (1 Ko) et 4 (520 o) peuvent être fusionnés et compressés en 1 seul bloc qui fasse à peine plus que 500 octets (testé grossièrement en les concaténant). Mais bon il faudrait modifier le loader pour qu'il prennent les copies d'introduction à l'écran et je ne pense pas que ça change la donne dans le temps total.

Si vous avez d'autres idées à me soumettre, n'hésitez pas !
Dernière modification par hlide le 14 avr. 2020 20:09, modifié 6 fois.
Avatar de l’utilisateur
hlide
Messages : 3495
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Fichier WAV étonnamment complexe

Message par hlide »

Et voici le résultat sous EmuZ-700 :
https://youtu.be/nMO03gvq4E8
__sam__
Messages : 7964
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [MZ-700] Fichier WAV étonnamment complexe

Message par __sam__ »

En plus, il n'a pas l'air très facile ce jeu au final. C'est donc excellent d'avoir réduit le temps de chargement par 4 car patienter 12mins pour perdre au jeu au bout de 2mins est très frustrant :mrgreen:
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
hlide
Messages : 3495
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Fichier WAV étonnamment complexe

Message par hlide »

hé hé hé, oui je te confirme qu'il n'est pas facile mais c'est aussi lié au fait que je suis sous émulateur avec une capture vidéo qui provoque des micro temps de réaction assez aléatoires que je ne vois pas vraiment dans le vidéo. Je reconnais que les ascenseurs sont casse-gueule. Enfin bref, l'approche choisi pour charger tout ce bousin m'aura bien occupé. Le jeu, je m'en fiche un peu - surtout qu'il n'a été jamais publié - et que je ne sais toujours pas ce que l'auteur projette d'en faire.
Avatar de l’utilisateur
Papy.G
Modérateur
Messages : 3051
Inscription : 10 juin 2014 13:40
Localisation : Haute-Garonne/Gers

Re: [MZ-700] Fichier WAV étonnamment complexe

Message par Papy.G »

Peut-être cela a été codé avec un assembleur sur cassette, et il n'était pas possible d'enregistrer le logiciel d'un seul coup (vu la taille du jeu, ou le code et les données sont gérés comme "modules"?
Soyez exigeants, ne vous contentez pas de ce que l'on vous vend.
Demandez-en plus, ou faites-le vous-même.
Avatar de l’utilisateur
hlide
Messages : 3495
Inscription : 29 nov. 2017 10:23

Re: [MZ-700] Fichier WAV étonnamment complexe

Message par hlide »

Les deux mon capitaine !

En temps normal, tu as la zone 1 sous forme d'une ROM monitor de $0000-$0FFF et à partir de $D000 la zone 3 où tu as la zone video et I/O, des ROM externes. La zone 2 de $1000 à $CFFF est de la DRAM donc tu as au max 48 Ko pour sauver en un seul bloc or ce jeu en utilise plus. Les zones 1 et 3 peuvent basculer en DRAM (au total il y a bien 64 Ko de DRAM) et on a plus que 48 Ko de jeu.

La découpe en bloc (module pour reprendre ton mot) vient fort à propos :
- afficher un écran de chargement (à la minitel) pour faire patienter le joueur tout en lui indiquant la progression (part 1 à 5)
- pour les parties 1 à 4 on a une alternance entre les adresses de chargement $A000 et $1200.
- la partie 2 se recopie en zone 3 avant que la partie 4 l'écrase. Ce sont des données - y mettre du code alors que l'on voudra faire de l'affichage ou de l'I/O n'est pas une bonne idée.
- la partie 5 comble le trou laissé entre les blocs précédemment chargés en $1200 et $A000.

Je croyais que l'un des blocs se chargeait en zone 1 pour remplacer la ROM monitor. Du coup, le jeux a perdu un peu de mon estime mais en même temps ça me permet d'envisager le possibilité de réduire encore le temps de chargement : rajouter dans le loader (bloc 3) un petit code qui va recopier la ROM monitor dans la zone 1 (même adresse que la ROM mais en RAM), "patcher" la temporisation de lecture pour passer 1200 baud au double voire au triple. Les blocs 4 à 9 pourront être lus deux ou trois fois plus rapidement.

EDIT: Ah non c'est rappé !!! j'ai oublié d'examiner la partie 1 - elle se copie en zone 1 à la place du ROM monitor. Du code ? cette zone ne peut pas être en permanence si elle ne remplace pas le monitor avantageusement. Néanmoins, on revient en ROM après la copie car logiquement on a besoin du Monitor pour charger le reste des parties.
Dernière modification par hlide le 15 avr. 2020 21:21, modifié 2 fois.
Avatar de l’utilisateur
Totor le Butor
Messages : 2235
Inscription : 07 sept. 2011 16:14
Localisation : Paris - Mezels

Re: [MZ-700] Fichier WAV étonnamment complexe

Message par Totor le Butor »

:shock: pour moi c'est de la sorcellerie...
Born to bricole
[Rch] Vieux composants électroniques et circuits intégrés toute époque et vieilles cartes .
Répondre