Dans le CEO-Mag 368, Didier se faisait l’écho des tests de Rax sur le mode LORES 1, très rarement utilisé. Au passage, il apportait l’explication sur la différence entre les caractères semi-graphiques sur Oric-1, et sur Atmos: sur Oric-1, ils sont définis sur une matrice de 8×8 pixels, alors que l’Oric n’en affiche que 6×8. Ils ont donc un aspect bizarre, décentré, et Didier en concluait “on oubliera vite ce jeu de caractère dans le cadre d’une utilisation sur Oric-1”.
Bien qu’ayant globalement été oublié tout court, j’ai eu à coeur de remettre le mode LORES 1 à égalité entre l’Oric-1 et l’Atmos ! Voici donc un modeste programme bricolé rapidement, 38 octets ayant pour but de corriger, après le boot de l’Oric-1, les caractères LORES pour les rendre identiques à ceux de l’Atmos.
Cette routine redéfinit simplement les caractères LORES en les décalant d’un bit vers la gauche. Elle est relogeable où l’on veut en RAM. Elle ne modifiera qu’une fois les caractères: s’il ont déjà été corrigés, la lancer ne produira plus d’effet. Elle peut donc sans risque être lancée au début d’un programme.
La redéfinition de caractères résistera à HIRES/TEXT, mais pas à un reset à chaud: il faudra alors lancer à nouveau la routine.
Voici le code:
AD 08 B9 LDA $B908 Let's control if we already seem to have the right values
C9 38 CMP #$38 by testing one
F0 1E BEQ exit If so, exit!
A2 00 LDX #$00 else get ready to change a whole page
loopB9:
BD 00 B9 LDA $B900,X Load a byte from page $B9
F0 06 BEQ nextB9 If $00, nothing to do, skip to next
6A ROR else shift once to the right
29 3F AND #$3F then set the two left bytes to 0 ($3F=00111111)
9D 00 B9 STA B900,X and replace the value in RAM
nextB9:
CA DEX Next byte
D0 F2 BNE loopB9 As long as X is not zeroed again, loop
loopBA:
BD 00 BA LDA $BA00,X X already at 0 here. Load a byte from page $BA
F0 06 BEQ nextBA If $00, nothing to do, skip to next
6A ROR else shift once to the right
29 3F AND #$3F then set the two left bytes to 0 ($3F=00111111)
9D 00 BA STA BA00,X and replace the value in RAM
nextBA:
CA DEX Next byte
D0 F2 BNE loopBA As long as X is not zeroed again, loop
exit:
60 RTS
(merci à ISS qui a relu mon code et supprimé deux octets inutiles !)
J’ai redécouvert après coup que Mike Brown donnait déjà exactement cette solution, dans une discussion que nous avions eue en 2019 alors que je m’étonnais de la différence d’aspect du mode LORES 1 entre l’Oric-1 et l’Atmos. Cf. https://forum.defence-force.org/viewtopic.php?t=1981
Vous trouverez ci-joint le fichier TAP de LoresFix 1.0, implémenté au bas de la page 1 et qui se lance automatiquement.
In English:
The goal of Lores Fix is to correct the alternate LORES characters definition, which is wrong on ROM 1.0.
What’s wrong? Well, ROM 1.0 sets those chars on a 8×8 pixels matrix, while Orics actually only display 6×8 pixels on screen. So the chars are not correctly centered.
This was corrected in ROM 1.1.
So, Lores Fix simply shifts in RAM the default LORES characters by 1 bit to the right, having them centered again. You can run it as much as you want, the chars won’t shift again if they are at the right value 😉
Mise à jour 05/09/2024 :
Grâce aux remarques et idées d’ISS et Sodiumlightbaby sur Defence-Force, nous sommes arrivés à une version bien plus compacte du code, que voici (seulement 16 octets !) :
AE 18 B9 LDX $B918 Test if we have a ROM 1.0: value FF in $B918 (3F on ROM 1.1, 7F once shifted on ROM 1.0)
E8 INX increment by 1 to get 00 if we had FF, thus get ready to change a whole page
D0 09 BNE exit if result was different from 00, it's not a ROM 1.0 or it was already fixed, so exit!
loop:
5E 00 B9 LSR $B900,X shift bytes from page $B9
5E 00 BA LSR $BA00,X shift bytes from page $BA
CA DEX Next byte
D0 F7 BNE loop As long as X is not zeroed again, loop
exit:
60 RTS
Cependant, je me suis rendu compte que lancer ce code sur Oric-1 provoque de gros problèmes quand on essaie de rentrer un programme Basic ensuite. Diantre, que se passe-t-il ? Est-ce que cela pourrait avoir un lien avec le HIMEM qui n’est pas placé au boot de l’Oric-1 ? Qu’est-ce qui pourrait donc gêner le système, de voir modifiées les octets de B900 à BAFF ?
En réalité, deux choses se cumulaient:
– sur ROM 1.0, le chargement d’un bloc mémoire plante le pointeur “fin de basic” en page 0, octets 9C-9D. Ce pointeur de fin prend la valeur de la fin du bloc mémoire !
– d’autre part, j’avais stocké la routine en $100 (pile), ce qui semble être une mauvaise idée quand on reste sur l’interpréteur et qu’on joue avec le basic: la routine est écrasée. BFE0-BFFF semble plus indiqué !
Le mieux pour une utilisation sur Oric-1 dans un programme Basic, semble donc être une implémentation à l’intérieur du Basic, par exemple (en appelant la routine par CALL#BFE0):
65 FORI=1TO16
70 READA$:A=VAL("#"+A$):POKE#BFDF+I,A
75 NEXTI
80 DATAAE,18,B9,E8,D0,09,5E,00,B9,5E,00,BA,CA,D0,F7,60
Désolé pour la mise en page du code, je ne sais pas pourquoi il supprime systématiquement tous les espaces en double !
J’ai redécouvert une ancienne discussion de 2019 avec Mike Brown, qui donnait déjà la solution… https://forum.defence-force.org/viewtopic.php?t=1981
Intéressant sujet.
Et très jolie seconde solution !
De mémoire, j’utilise la zone BFE0-BFFF pour stocker le message d’invite sous Basix…
Nous avons eu la même idée de récupérer ces quelques octets inutilisés…
Merci !
L’avantage de la petite routine est qu’on la place où on veut.
En cas d’utilisation Basic, l’optimal pour moins perdre en RAM est de charger un premier programme basic qui implémente la routine à un endroit qui résiste à un RESET, puis de charger le programme basic principal et d’appeler une fois la routine au début avec un CALL. Ainsi ça libère la RAM des quatre lignes utilisées pour l’implémentation.
Bon après, qui se sert de LORES 😉
Le bas de la pile est utilisé par un certain nombre d’instructions du BASIC comme zone temporaire.
Par exemple, HEX$() y place la chaîne de caractères générée, la conversion chaîne -> valeur numérique se sert également de cette zone.
Concernant la zone de $BFE0 à $BFFF, elle est en partie utilisée par le FTDOS ($BFE0-$BFED) donc attention il risque de ne pas apprécier qu’elle soit modifiée.
Je n’ai pas vérifié pour Sedoric.
Oui, d’après l’Oric à Nu sur le bas de la page 1: “Lors des conversions flottant/décimal ou flottant/hexadécimal, il fallait une zone pour stocker les résultats. Cette zone se situe au début de la page 1, de #100 à #10F ou de #0FF à #10E pour l’instruction STR$.”
La zone à cibler serait alors plutôt à partir de $0110, en espérant que la pile ne descende pas trop bas.
Pour $BFE0, il y a des instructions Sedoric qui s’en servent (de mémoire LINE et BOX, à vérifier si ça existe vraiment car je n’ai pas regardé, mais André dans Sedoric à Nu en parlait je crois).
Il n’y a de toute façon, dans l’absolu, aucune zone totalement réservée, sauf à faire un HIMEM et à stocker la routine au-dessus. L’avantage, c’est qu’elle peut être logée n’importe où sans modif.
Reste une dernière question, histoire de rire: pour les jeu sortis sur Oric-1 utilisant Lores 1, donc avec les graphismes “mal fichus”, est-ce qu’il faudrait “corriger” l’Atmos dans l’autre sens ? :-p
Tout dépend de ce qu’on entend par réservé,
Tant qu’on ne fait pas un GRAB, la mémoire de $9800 à $B3FF n’est pas utilisable par le basic.
Sinon, il y a les plages $B400-$B4FF et $B800-$B8FF.
Ces deux zones correspondent aux caractères 0 à 31 du jeu normal et du jeu LORES 1 mais elles ne sont pas du tout utilisées puisque l’ULA n’affiche pas ces caractères.
La plage $BB00-$BB7F est aussi utilisable et non initialisée par la rom mais elle correspond aux caractères 96 à 111 du jeu LORES 1 qui peuvent être affichés par l’ULA, ce qui permet de définir d’autres caractères LORES 1
Ces zones mémoire sont déplacées lors d’un passage TEXT => HIRES et remises à leur place au retour en mode TEXT.
On pourrait d’ailleurs récupérer les plages $9800-$98FF et $B400-$B4FF pour le basic moyennant la modification d’une poignée d’octets dans la rom (une instruction et une table) et remonter la limte maximale à $9900 au lieu de $9800 au démarrage ($B4FF au lieu de $B3FF en cas de GRAB) soit 256 octets de plus.
Pour les jeux Oric-1 en LORES 1 sur un Atmos, on peut effectivement se poser la question 🙂