exl100

Émulateur Exelvision EXL 100 (1984) dans le navigateur : dsp-cpp en WebAssembly, cartouches et cassettes BASIC
git clone https://git.schurger.org/exl100.git
Log | Files | Refs | README

commit e4e47b5faf95b0ea96c41fec60f0e9c3513ac23f
parent 5f6e1572ab1cbb291378090c44d2dc83422ea7da
Author: Jean Schurger <jean@schurger.org>
Date:   Thu,  5 Nov 2026 14:55:18 -0500

Exeldisk : l'Exelmémoire reste branchée au lancement d'une disquette (EXEC de Jester y charge)

Depuis l'EXELTEL ou après débranchement dans la page, rechargement EXL 100 puis relance (sessionStorage
exl100.exec). Test library-disk.mjs : EXELMEM/AFTER pour répondre aux questions du programme.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QyJB9yqUAYm3wRQi4uytj9

Diffstat:
Mtest/library-disk.mjs | 5+++++
Mweb/shell.html.in | 17++++++++++++++---
2 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/test/library-disk.mjs b/test/library-disk.mjs @@ -8,6 +8,7 @@ const cmd = process.argv[3] ?? 'DIR'; const base = process.argv[4] ?? 'http://127.0.0.1:8196'; const prefix = process.argv[5] ?? '/tmp/lib-disk'; const page = await open(base + '/', { width: 900, height: 1100 }); +if (process.env.EXELMEM) await page.evaluate("localStorage.setItem('exl100.exelmem', '1')"); // EXEC (Jester) charge dans la CRAM await page.evaluate('location.reload()'); await sleep(7000); const hit = await page.evaluate(`(() => { @@ -29,6 +30,10 @@ for (const ch of cmd) { } await key('Enter', 'Enter', 13); await sleep(6000); +if (process.env.AFTER) { // réponse à une question du programme (ex. « Écraser exelmémoire ? » d'EXEC), puis attente + for (const ch of process.env.AFTER) await key(ch.toLowerCase(), 'Key' + ch.toUpperCase(), ch.toUpperCase().charCodeAt(0)); + await sleep(Number(process.env.AFTER_MS ?? 12000)); +} await page.screenshot(prefix + '-cmd.png'); console.log('statut :', await page.evaluate("document.getElementById('status').textContent")); console.log('Captures :', prefix + '-boot.png', prefix + '-cmd.png'); diff --git a/web/shell.html.in b/web/shell.html.in @@ -323,6 +323,7 @@ return path; } + let keepCram = false; // lancement de disquette : l'Exelmémoire reste branchée (EXEC y charge les programmes) function launch(args) { $('help').hidden = true; outputEl.textContent = ''; @@ -331,9 +332,10 @@ // Exelmémoire de l'EXL 100 : le driver la branche si /roms/cros64_exl100.rom existe dans le // MEMFS ; débranchée, on retire le fichier avant de démarrer (une cartouche formatée // démarrerait CROS64 à la place du logo). L'EXELTEL l'a toujours (menu Périphériques). - if (!onExeltel && !exelmemEnabled()) { + if (!onExeltel && !exelmemEnabled() && !keepCram) { try { fs().unlink('/roms/cros64_exl100.rom'); } catch (e) {} } + keepCram = false; try { Module.ccall('dsp_web_start', 'number', ['string'], [args.join('\n')]); } catch (e) { @@ -462,8 +464,17 @@ args.push('--tape', '/roms/cartridges/exelbasic.bin', '--tape', '/roms/tapes/' + value.slice(5)); cassette = true; } else if (value.startsWith('disk:')) { - // Disquette de la bibliothèque : l'Exeldisk est monté avec l'image (le pilote reconnaît .fd) et - // l'EXL 100 amorce dessus (BOOT V1.5 puis EXELDOS). Pas de persistance des écritures ici. + // Disquette de la bibliothèque (EXL 100 seulement) : l'Exeldisk est monté avec l'image (le pilote + // reconnaît .fd) et la machine amorce dessus (BOOT V1.5 puis EXELDOS). L'Exelmémoire reste branchée, + // EXEC (chargeur Jester) y charge les programmes ; si elle a déjà été débranchée dans cette page, ou + // depuis l'EXELTEL, on recharge la page EXL 100 et on relance. Pas de persistance des écritures. + if (onExeltel || !exists('/roms/cros64_exl100.rom')) { + try { sessionStorage.setItem('exl100.exec', value); } catch (e) {} + location.href = onExeltel ? location.pathname : location.href.split('#')[0]; + if (!onExeltel) location.reload(); + return; + } + keepCram = true; args.push('--tape', '/roms/disks/' + value.slice(5)); } else if (value.startsWith('cram:')) { // Volume Exelmémoire de la bibliothèque. Programmes EXL 100 (ceux de webmo : code machine qui