OPL2LPT : une carte son AdLib sur port parallèle
Vincent Bernat
La carte son AdLib était la première carte son en vogue pour les IBM PC (avant cela, nous étions choyés par le son du haut-parleur interne). Connectée à un slot ISA 8 bits, elle est équipée d’une puce Yamaha YM3812, aussi connue sous le nom d’OPL2. Cette puce peut piloter 9 canaux sonores dont les caractéristiques sont affinées grâce à 244 registres.
J’en avais une mais je l’ai égarée. Les modèles disponibles sur eBay sont assez rares et chers. Il est possible d’en fabriquer une soi-même (soit celle de Sergey, soit cette reproduction fidèle). Cependant, un port ISA est toujours nécessaire. L’imagination débordante de certains passionnés peut encore aider ici. Par exemple, vous pouvez combiner la carte processeur Xi 8088 de Sergey avec son fond de panier ISA 8 bits, sa carte Super VGA et sa carte XT-CF-Lite pour obtenir votre propre PC compatible IBM vaguement moderne. Vous pouvez également jeter un œil sur la carte son AdLib sur un port parallèle de Raphaël Assénat.
La carte son OPL2LPT#
Récemment, David Murray a publié une vidéo sur une carte son AdLib pour port parallèle, l’OPL2LPT. Bien que les cartes mères actuelles n’aient plus de port parallèle, il est facile d’en ajouter un au format PCI-Express. J’ai donc acheté une OPL2LPT pré-assemblée et quelques jours plus tard, elle était dans ma boîte à lait :
Mise à jour (03.2018)
Vous pouvez également acheter un
boîtier pour l’OPL2LPT. Après avoir écrit cet article, on m’en
a offert un:
Mise à jour (07.2018)
L’OPL3LPT est également disponible avec une conception similaire mais utilisant une puce OPL3.
Tel que conçu, ce périphérique se branche sur un port parallèle ISA (accessible à l’adresse 0x378). Il faut ensuite charger un pilote pour DOS (qui va intercepter les appels vers l’adresse de la carte AdLib) puis exécuter un jeu compatible avec l’AdLib. Bien qu’il soit correctement pris en charge par Linux, le port parallèle PCI-Express ne fonctionne pas comme son équivalent ISA. QEMU est livré avec une émulation du port parallèle mais, en raison de problèmes de synchronisation, ne peut pas piloter correctement l’OPL2LPT. Par contre, l’émulation de VirtualBox est suffisante1.
Sous Linux, l’OPL2LPT se programme presque comme une véritable AdLib. Le bout de code ci-dessous permet d’écrire une valeur dans un des registres :
static void lpt_write(uint8_t data, uint8_t ctrl) { ieee1284_write_data(port, data); ieee1284_write_control(port, (ctrl | C1284_NINIT) ^ C1284_INVERTED); ieee1284_write_control(port, ctrl ^ C1284_INVERTED); ieee1284_write_control(port, (ctrl | C1284_NINIT) ^ C1284_INVERTED); } void opl_write(uint8_t reg, uint8_t value) { lpt_write(reg, C1284_NSELECTIN | C1284_NSTROBE); usleep(4); // 3.3 microseconds lpt_write(value, C1284_NSELECTIN); usleep(23); }
Pour utiliser « nativement » l’OPL2LPT, j’ai modifié les programmes suivants :
- ScummVM, un émulateur pour d’anciens jeux d’aventure, notamment ceux de LucasArts — rustine2
- QEMU, un émulateur générique et rapide — rustine avec une émulation minimaliste des minuteries et les temporisations codées en dur 🙄
- DOSBox, un émulateur x86 intégrant DOS — rustine avec une émulation complète des minuteries et un fil d’exécution dédié3
Vous pouvez comparer les résultats sur l’introduction du jeu Indiana Jones et la dernière croisade dans la vidéo suivante4 :
- 0:00, DOSBox avec une émulation du haut-parleur interne
- 0:58, DOSBox avec une émulation de l’AdLib
- 1:51, VirtualBox avec l’OPL2LPT (sur un port parallèle émulé)
- 2:42, ScummVM modifié avec l’OPL2LPT
- 3:33, QEMU modifié avec l’OPL2LPT
- 4:24, DOSBox modifié avec l’OPL2LPT
- 5:17, DOSBox modifié avec une version améliorée de l’émulateur OPL3 (Nuked OPL3)
- 6:10, ScummVM avec la piste CD (version FM Towns)
Je vous laisse juger de la qualité de chaque option ! Vous pouvez vous
procurer l’OPL2LPT l’OPL3LPT depuis l’Europe via
Serdashop ou depuis l’Amérique du Nord via The 8-Bit
Guy.
Annexes#
Indiana Jones et le mystère de l’Atlantide#
Voici une autre vidéo avec l’introduction de Indiana Jones et le mystère de l’Atlantide, publié en 1992, tournant dans DOSBox avec l’OPL2LPT. C’est le second jeu utilisant le système de son iMUSE : la musique est synchronisée avec l’action et les transitions se font en toute transparence. Particulièrement novateur pour l’époque !
Monkey Island 2#
Le premier jeu utilisant iMuse est Monkey Island 2, publié en 1991. La vidéo ci-dessous montre les premières minutes du jeu tournant dans DOSBox avec l’OPL2LPT.
Notamment, à 5:33, quand Guybrush se trouve à Woodtick, une sympathique ville de Scabb Island, la musique joue autour d’un thème principal et d’une variation avec un instrument différent pour chaque endroit, sans jamais s’interrompre.
Enregistrement des vidéos#
Avec une carte vidéo VGA, de nombreux jeux utilisent le Mode 13h, un mode 256 couleurs avec une résolution de 320×200. Sur un écran 4:3, ce mode n’affiche pas de pixels carrés: ils sont étirés verticalement par un facteur de 1,2.
Les vidéos précédentes ont été enregistrées avec FFmpeg (puis éditées avec Blender). Il propose de très nombreux filtres permettant d’automatiser la capture et une partie du montage. Voici un exemple :
FONT="font=Monkey Island 1991 refined: fontcolor=OrangeRed: fontsize=16: x=w-text_w-10" ffmpeg -y \ -thread_queue_size 64 \ -f x11grab -draw_mouse 0 -r 30 -s 640x400 -i :0+844,102 \ -thread_queue_size 64 \ -f pulse -ac 1 -i default \ -filter_complex "[0:v]pad=854:400:0:0, drawtext=${FONT}:y= 10:text=Indiana Jones 3, drawtext=${FONT}:y= 34:text=Intro, drawtext=${FONT}:y=100:text=DOSBox, drawtext=${FONT}:y=124:text=VGA, drawtext=${FONT}:y=148:text=PC speaker, scale=854:480:flags=neighbor[game]; [1:a]volumedetect; [1:a]showwaves=s=214x100:colors=OrangeRed:scale=lin[waves]; [1:a]showcqt=s=214x100[spectrum]; [waves][spectrum]vstack[vis]; [game][vis]overlay=x=640:y=280" \ -pix_fmt yuv420p -c:v libx264 -qp 0 -preset ultrafast \ indy3-dosbox-pcspkr.mkv
La partie intéressante est l’argument filter_complex
. La vidéo
capturée passe du format 640×400 au format 854×400 sans étirement
comme première étape d’adaptation au format 16:95. En utilisant
la fonte The Secret Font of Monkey Island, du texte est
ajouté sur la droite de la vidéo. Le résultat est ensuite étiré vers
du 854×480 pour obtenir le format final. Le flux vidéo correspondant
est nommé game
. Dans un deuxième temps, la piste audio est utilisée
pour construire deux visualisations : une vue d’oscilloscope et un
spectrogramme. Elles sont placées verticalement et le résultat est
nommé vis
. La dernière étape est de superposer les deux flux
précédents.
-
Il n’y a pas d’interface graphique pour configurer le port parallèle. Cela doit se faire via la ligne de commande :
↩︎$ VBoxManage modifyvm "FreeDOS (games)" --lptmode1 /dev/parport0 $ VBoxManage modifyvm "FreeDOS (games)" --lpt1 0x378 7
-
La rustine pour ScummVM a été accepté. La prise en charge de l’OPL2LPT apparaîtra avec la version 2.1. À la compilation, l’option
--enable-opl2lpt
doit être spécifiée. ↩︎ -
Avec QEMU et DOSBox, le respect des délais nécessaires au bon fonctionnement de l’OPL2 devrait être la responsabilité du jeu qui s’exécute. Toutefois, QEMU n’émule pas les délais dus aux entrées/sorties et DOSBox
semble ne pas être assez précistravaille sur des intervalles de 1 milliseconde. Sur ce dernier, l’OPL2LPT est gérée depuis un fil d’exécution dédié qui reçoit les écritures et s’assure que les délais minimaux sont respectés. ↩︎ -
Indiana Jones et la dernière croisade a été le premier jeu que j’ai essayé après avoir branché la carte son AdLib que j’ai forcé mes parents à acheter lors d’un voyage au Canada en 1992. À l’époque, aucun magasin traditionnel ne vendait cette carte dans ma ville française et les achats en ligne (via le Minitel) étaient limités aux biens de grande consommation (comme un magnétoscope). La grande époque. 😏
La vidéo illustre la version VGA (320×200, 256 couleurs) publiée en 1990. Toutefois, à l’époque, je jouais avec la version CGA/EGA (320×200, 4 couleurs fixes ou 640×350, 16 couleurs issues d’une palette de 64). ↩︎
-
Une méthode courante pour étendre une vidéo de 4:3 à 16:9 sans barres noires est d’ajouter en fond la vidéo étirée et floutée. C’est aussi possible avec FFmpeg ! ↩︎