Obligement - L'Amiga au maximum

Samedi 31 mai 2025 - 06:40  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : AMOS - AMOStel, un émulateur Minitel en AMOS (1re partie : les jeux de caractères)
(Article écrit par François Lionet et extrait d'Amiga News Tech - mars 1992)


Chose promise, chose due : Daisy et moi nous sommes réconciliés ! Main dans la patte, nous allons vous proposer dans cette rubrique, de réaliser un émulateur Minitel complet en AMOS.

 Il s'agit d'un travail de longue haleine, dont la publication sera étalée sur plusieurs articles. Nous n'allons pas trop nous étendre sur l'émulation elle-même, ce qui prendrait tout le magazine pendant plusieurs mois, mais plutôt sur l'implémentation en AMOS. Ainsi aujourd'hui, vous trouverez un truc permettant de changer le jeu de caractères dans toute fenêtre ouverte.

À propos de la documentation : le Minitel est un domaine assez professionnel, à cheval sur les réseaux de communication et la telématique. Les documentations que l'on trouve sont en général assez ardues. Nous avons cependant trouvé quelques livres assez abordables, comme Guide Pratique Du Vidéotex aux éditions Eyrolles.

Les jeux de caractères

Première chose à faire pour émuler le Minitel, reproduire ses jeux de caractères. Le Minitel ne contient pas moins de quatre jeux de cent vingt-huit caractères différents chacun.
  • Jeu G0 : les caractères ASCII presque standard. Les lettres de l'alphabet, les chiffres et ponctuations. Neuf caractères sont spécifiques, de $5b à $5e, et de $7b à $7f.

  • Jeu G1 : les mosaïques contiguës. C'est grâce à ces caractères semi-graphiques que les serveurs peuvent afficher des images. Chaque caractère est divisé en six (deux par trois), et toutes les combinaisons sont explorées.

  • Jeu G2 : les mosaïques séparées, semblables aux précédentes avec un trait noir entre chaque pavé. Ces mosaïques sont souvent utilisées par les serveurs. L'annuaire électronique affiche le cadran de téléphone en haut à gauche de l'image avec les caractères du jeu G2.

  • Jeu G3 : les caractères spéciaux, à savoir les accents et trémas.
Comment implémenter ceci en AMOS ? Il est en effet impossible (théoriquement) de changer le jeu de caractères courant d'un écran. Impossible, jusqu'à maintenant ! La fonction "=SCREEN BASE" retourne l'adresse de base de la structure interne de définition d'un écran AMOS. En position 170 de cette structure, se trouve l'adresse de la structure de la fenêtre courante, dans laquelle l'adresse du jeu de caractères se trouve en position 8.

La petite procédure suivante fait pointer le jeu de caractères courant sur une adresse quelconque.

Procedure _SET WINDOW_FONT[A]
   AFONT=Leek(Screen Base+170)+8
   Loke AFONT,A
End Proc

Pour aller plus rapidement lors de l'affichage, les caractères sont codés très simplement : l'un après l'autre, se trouvent les huit octets de définition de chaque caractère. Le jeu de caractères comprend les trente-deux premiers caractères, même si ceux-ci ne sont pas accessibles.

Quelques applications :
  • Notre programme d'émulation, bien sûr. Nous allons fabriquer une banque mémoire contenant les quatre jeux à la suite.
  • Définir de nouveaux symboles graphiques.
  • Coder un listing, en faisant pointer les caractères sur n'importe quoi. Il n'y a aucun risque. Le nec plus ultra étant de faire pointer sur des données modifiées, par exemple "_SET_WINDOW_FONT[Log Base(0)]".




Le programme ouvre un écran deux couleurs dans lequel il travaille. Il crée les quatre jeux à la suite l'un de l'autre. La plupart des caractères sont définis dans le jeu par défaut de l'AMOS. Il suffit de les afficher avec un "PRINT" normal, ce que fait la procédure "_CPRINT[]". On imprime d'abord les caractères ASCII normaux, puis les caractères spécifiques, en les prenant dans les codes supérieurs à 128.

La procédure "_GET_FONT[]" se charge de transférer la police de l'écran dans la banque. Les jeux graphiques sont quant à eux fabriqués à partir des données (datas), en explorant toutes les différentes possibilités.

L'émulateur

Vous devez vous procurer un câble Minitel-Amiga et relier les deux machines. Pour le moment, toutes les manipulations doivent se faire sur le Minitel.

L'interface série fonctionne correctement à partir d'AMOS 1.3. Attention cependant, il se peut que le programme ne fonctionne qu'une fois, puis bloque la deuxième fois. Ce problème ne vient pas de l'AMOS, mais de Commodore : une version du serial.device contient un bogue. Solution : copier le fichier Devs/serial.device de votre disquette Workbench originale sur votre disquette AMOS.

Le programme est composé de deux procédures principales :
  • "_DISPLAY_INIT" : initialise l'écran et lit toutes les données des codes de contrôle.
  • "_DISPLAY[A]" : réceptionne un caractère, et émule l'écran du Minitel. Le caractère peut provenir de l'interface série, ou d'une banque mémoire dans laquelle vous aurez enregistré des données.
Ces deux procédures peuvent facilement être récupérées dans d'autres programmes. Vous devez pour cela :
  • Copier les deux procédures et la définition des variables globales.
  • Ouvrir un écran 16 couleurs basse résolution, d'au minimum 320x200 pixels.
  • Appeler la procédure "_DISPLAY_INIT".
Ce qui est émulé

Bien que l'Amiga soit infiniment supérieur au niveau graphique au Minitel, l'émulation de l'affichage est assez complexe à réaliser, du fait de la présence de codes de contrôles de couleur, appelés attributs graphiques.

Qu'est-ce donc qu'un attribut graphique ? Il s'agit d'un caractère affiché par le Minitel comme un espace, et définissant les caractéristiques de ce qui vient à sa droite sur l'écran. Peuvent ainsi être définies la couleur de fond et le soulignement.

Lorsque l'on affiche un caractère à l'écran, il faut donc pour connaître sa couleur de fond, explorer la ligne de la gauche vers la droite. Une émulation parfaite n'est donc possible qu'en langage machine.

En AMOS, il faut ruser. Nous gardons en mémoire (dans la banque 11) une grille représentant l'écran. Cette grille contiendra les attributs graphiques. Nous avons aussi volontairement simplifié l'émulation. Tout fonctionne, sauf le soulignement, utilisé extrêmement finement par les serveurs, et par conséquent très difficile à reproduire, et le défilement. Pour les initiés, le niveau de l'émulation se situe entre Amigatel et Flammitel.

Fonctionnement du programme

AMOS permet d'adresser des labels contenus dans des chaînes de caractères. C'est extrêmement pratique et surtout, rapide. Notre émulateur doit en effet fonctionner assez rapidement et ne pas aller moins vite que le débit de la prise série !

Nous usons (et abusons) de cette facilité dans le programme :
  • "CMODE$" contient la fonction actuelle. La première instruction de la procédure "_DISPLAY" branche directement à la routine, sans perdre de temps en tests. Les routines de traitements spécifiques peuvent, par une simple égalité, modifier le branchement lors du prochain appel de la procédure.

  • Les labels des routines de gestion des codes de contrôle se trouvent dans les tableaux "CMODE$()" et "ESC$()". Le numéro du code pointe directement dans le tableau. En un coup de cuillère à pot, on connaît la routine à appeler. Nous utilisons une méthode toute simple pour afficher les caractères en double largeur (ou hauteur) : on affiche le caractère en taille normale, puis on le zoome à même l'écran.
'***************************** 
' Émulateur Minitel en AMOS
' Par Daisy & François Lionet
' Partie 1 : l'affichage 
'***************************** 
'
' Tableaux des codes de controle 
Dim CMODE$(32),ESC$(128)
'
' Variables globales 
Global CMODE$,CMODE$(),ESC$(),OCMODE$
Global GMODE,FLSH,G2$,GOPAP,CPAP,CPEN,CINV,PRNT$,ALAST
Global XCU,YCU,OXCU,OYCU
Global PAR1,PAR2,PAR3
Global AATR
'
' Faire fonctionner Minitel_Fonte.AMOS 
' puis ce programme. Vous pouvez ensuite 
' enlever la ligne suivante... 
'Load "ram:minitel_fonte.abk",15 
'
' Ouverture de l'écran d'exemple 
Screen Open 0,320,200,16,0 : Flash Off : Cls 0
_DISPLAY_INIT
'
' Ouvre l'interface série
Serial Open 0,1
'
' Boucle d'exemple 
Repeat 
  '
  _SERIAL_GET
  A=Param : If A>=0 : _DISPLAY[A,1] : End If 
  '
Until A<0
'
' Fermeture de la série
Serial Close 
'
Procedure _DISPLAY_INIT
  '
  ' Préparation de l'ecran 
  Paper 0 : Cls 
  Wind Open 1,0,8,40,24
  '
  ' La palette du minitel ne comprend que des couleurs 
  ' extrèmement vives! 
  Palette 0,$F00,$F0,$FF0,$F,$F0F,$FF,$FFF
  ' Fait clignoter les couleurs 8-15 
  For C=0 To 7
    V=Colour(C)
    Flash C+8,"("+Mid$(Hex$(V,3),2)+",20)(000,20)"
  Next 
  '
  ' Initilisalisation des fenetres 
  Window 1 : Paper 0 : Pen 7 : Clw 
  Scroll Off : Curs Off 
  '
  Window 0 : Paper 0 : Pen 7 : Clw 
  Scroll Off : Curs On : _SET_FONT[0]
  '
  ' Initialisation des attributs 
  CMODE$="_G0"
  GMODE=0 : FLSH=0 : PRNT$="_NNPRINT"
  GOPAP=-1 : CPAP=0 : CPEN=7 : CINV=0
  '
  ' Lis les codes de controle
  For C=0 To 31 : Read CMODE$(C) : Next 
  '
  ' Lis les code d'échappement 
  Repeat : Read C : Read ESC$(C) : Until ESC$(C)=""
  '
  ' Chaine de définition des caracteres spéciaux 
  G2$=Chr$($41)+"eèaàuù"+Chr$($42)
  G2$=G2$+"eé"+Chr$($43)+"eêaâiîuûoô"
  G2$=G2$+Chr$($48)+"eëiïaä"
  G2$=G2$+Chr$($4B)+"cç"
  '
  ' Initialise la carte de couleurs
  Erase 11 : Reserve As Work 11,40*26 : AATR=Start(11)
  Fill AATR To AATR+25*40,0
  '
  ' Jeu de commandes du mode C0
  Data "_Nul","_Nul","_Nul","_Nul"
  Data "_Nul","_Nul","_Nul","_Nul"
  Data "_ARR","_AVT","_BAS","_HAU"
  Data "_CLS","_DLI","_GG1","_GG0"
  Data "_Nul","_CON","_RPT","_CLA"
  Data "_COF","_Nul","_GG2","_Nul"
  Data "_CAN","_GG2","_SKP","_ESC"
  Data "_Nul","_Nul","_HOM","_LOC"
  '
  ' Jeu de commandes ESCAPE
  Data $39,"_dld",$3A,"_lkk",$3B,"_dlk"
  Data $40,"_PEN",$41,"_PEN",$42,"_PEN",$43,"_PEN"
  Data $44,"_PEN",$45,"_PEN",$46,"_PEN",$47,"_PEN"
  Data $48,"_GFL",$49,"_NFL",$4A,"_Nul",$4B,"_Nul"
  Data $4C,"_GNN",$4D,"_GDY",$4E,"_GDX",$4F,"_GDD"
  Data $50,"_PAP",$51,"_PAP",$52,"_PAP",$53,"_PAP"
  Data $54,"_PAP",$55,"_PAP",$56,"_PAP",$57,"_PAP"
  Data $58,"_Nul",$59,"_G1N",$5A,"_G1L",$5B,"_CSI"
  Data $5C,"_NOR",$5D,"_INV",$5E,"_Nul",$5F,"_Nul"
  Data 0,""
  '
End Proc
'
Procedure _DISPLAY[A,F]
  '
  Goto CMODE$
  '
  ' Entree impression normale
  _G0:
  If A<32 Then OCMODE$=CMODE$ : Goto CMODE$(A)
  ALAST=A : Gosub PRNT$ : Pop Proc
  '
  ' Impression normale 
  _NNPRINT:
  If GMODE=0
    If A<>$20
      Gosub _ATTRIB
      Print At(XCU,YCU)+Chr$(A);
      Gosub _CRIGHT
    Else 
      Gosub _ATTRIB : Gosub _LATCH : Print At(XCU,YCU)+" ";
      Gosub _DELIM : Gosub _CRIGHT
    End If 
  Else 
    Gosub _DELIM
    Print At(XCU,YCU)+Chr$(A);
    Gosub _CRIGHT
  End If 
  Return 
  '
  ' Impression double largeur
  _DXPRINT:
  If XCU>38 Then Goto _NNPRINT
  Gosub _CRIGHT : Gosub _NNPRINT
  X=X Graphic(XCU-1) : Y=Y Graphic(YCU)
  Zoom 0,X,Y,X+8,Y+8 To 0,X-8,Y,X+8,Y+8
  Return 
  '
  ' Impression double hauteur
  _DYPRINT:
  If YCU<2 Then Goto _NNPRINT
  X=X Graphic(XCU) : Y=Y Graphic(YCU)
  Gosub _NNPRINT
  Zoom 0,X,Y,X+8,Y+8 To 0,X,Y-8,X+8,Y+8
  If XCU=0 : Gosub _CDOWN : End If 
  Return 
  '
  ' Impression double  
  _DDPRINT:
  If XCU>38 Then Goto _DXPRINT
  If YCU<1 Then Goto _DYPRINT
  X=X Graphic(XCU+1) : Y=Y Graphic(YCU)
  Gosub _CRIGHT : Gosub _NNPRINT
  Zoom 0,X,Y,X+8,Y+8 To 0,X-8,Y-8,X+8,Y+8
  If XCU<=1 : Gosub _CDOWN : End If 
  Return 
  '
  ' Trouve la couleur de papier
  _ATTRIB:
  AA=Peek(AATR+YCU*40+XCU) : P=AA and $7
  If P<>CPAP : Paper P : CPAP=P : Gosub _SINV : End If 
  Return 
  '
  ' Met un délimiteur dans les couleurs
  _DELIM:
  Gosub _LATCH : AA=CPAP+$80
  If XCU<39
    For XA=XCU To 39
      O=Peek(AATR+YCU*40+XA) : Poke AATR+YCU*40+XA,AA
      Exit If AA=O or Btst(7,O)
      Bclr 7,AA
    Next 
  End If 
  Return 
  '
  ' Faut-il changer la couleur de papier 
  _LATCH:
  If GOPAP>=0
    CPAP=GOPAP : GOPAP=-1 : Paper CPAP : Gosub _SINV
  End If 
  Return 
  '
  ' Passe en inverse s'il faut 
  _SINV: If CINV : Inverse On Else Inverse Off : End If 
  Return 
  '
  ' Vers la droite 
  _CRIGHT: Inc XCU
  If XCU>=40
    XCU=0 : If YCU>0 : Gosub _CDOWN : End If 
  End If 
  Locate XCU,YCU
  Return 
  '
  ' Vers la gauche 
  _CLEFT: Dec XCU
  If XCU<0
    XCU=39 : If YCU>0 : Gosub _CUP : End If 
  End If 
  Locate XCU,YCU
  Return 
  '
  ' Vers le bas
  _CDOWN:
  If YCU=0
    XCU=OXCU : YCU=OYCU : Gosub _NLINE
  Else 
    Inc YCU : Gosub _NLINE
    If YCU=25 : YCU=1 : End If 
  End If 
  Locate XCU,YCU
  Return 
  '
  ' Vers le haut 
  _CUP:
  If YCU
    Dec YCU : Gosub _NLINE
    If YCU=0 : YCU=24 : End If 
  End If 
  Locate XCU,YCU
  Return 
  '
  ' Code non utilisé 
  _NUL: Pop Proc
  '
  ' Codes de mouvement du curseur  
  _ARR: Gosub _CLEFT : Pop Proc
  _AVT: Gosub _CRIGHT : Pop Proc
  _HAU: Gosub _CUP : Pop Proc
  _BAS: Gosub _CDOWN : Pop Proc
  _DLI: XCU=0 : Locate XCU,YCU
  Gosub _NLINE : Gosub _DELIM : Pop Proc
  '
  ' Efface jusqu'à la fin de la ligne
  _CAN: Paper CPAP : Gosub _SINV
  ACAN=CPAP+$80
  If XCU<40
    Locate XCU,YCU
    For X=XCU To 39
      Print " ";
      Poke AATR+YCU*40+X,ACAN : Bclr 7,ACAN
    Next 
    Locate XCU,YCU
  End If 
  Pop Proc
  '
  ' Curseur  
  _CON: Curs On : Pop Proc
  _COF: Curs Off : Pop Proc
  '
  ' Home / Clear   
  _HOM: XCU=0 : YCU=1
  Locate XCU,YCU : Gosub _DEF : Pop Proc
  _CLS: Gosub _DEF
  Window 1 : Clw : Window 0 : XCU=0 : YCU=1
  Fill AATR+40 To AATR+25*40,0 : Pop Proc
  '
  ' Mode mosaique
  _GG1: _SET_FONT[1] : GMODE=1
  CINV=0 : Gosub _SINV : Gosub _DEF2 : Pop Proc
  _GG0: _SET_FONT[0] : GMODE=0 : Gosub _DEF2 : Pop Proc
  '
  ' Caracteres spéciaux du jeu G2
  _GG2: CMODE$="_G22" : Pop Proc
  _G22: PAR1=Instr(G2$,Chr$(A))
  If PAR1 : CMODE$="_G23" : Pop Proc : End If 
  _SET_FONT[3] : Gosub PRNT$ : _SET_FONT[GMODE]
  CMODE$=OCMODE$ : Pop Proc
  _G23: B=Instr(G2$,Chr$(A),PAR1)
  If B : A=Asc(Mid$(G2$,B+1,1)) : Gosub PRNT$ : End If 
  CMODE$=OCMODE$ : Pop Proc
  '
  ' Locate 
  _LOC: CMODE$="_LO2" : Pop Proc
  _LO2:
  If A>=$40
    ' Locate direct, en Y
    Y=A-$40
    If Y=0 and YCU<>0 : OYCU=YCU : OXCU=XCU : End If 
    If Y>=0 and Y<25 : YCU=Y : End If 
  Else 
    ' En début de ligne, dizaines
    PAR1=A-$30
  End If 
  CMODE$="_LO3" : Pop Proc
  _LO3:
  If A>=$40
    ' Direct, en X 
    X=A-$41 : If X>=0 and X<40 : XCU=X : End If 
  Else 
    ' En début de ligne, unités
    Y=PAR1*10+A-$30
    If Y>=0 and Y<25 : YCU=Y : XCU=0 : End If 
  End If 
  CMODE$=OCMODE$ : Gosub _DEF : Locate XCU,YCU
  Pop Proc
  '
  ' Repetition 
  _RPT: CMODE$="_RP2" : Pop Proc
  _RP2: PAR1=A-$40 : A=ALAST : CMODE$=OCMODE$
  For REP=1 To PAR1 : Gosub PRNT$ : Next : Pop Proc
  '
  ' Saute le prochain code 
  ' (par exemple, appui sur une touche du minitel) 
  _SKP:
  _CLA: CMODE$="_CL2" : Pop Proc
  _SK2:
  _CL2: CMODE$=OCMODE$ : Pop Proc
  '
  '
  ' Passage en mode ESCape 
  _ESC: CMODE$="_ES2" : Pop Proc
  _ES2: CMODE$=OCMODE$
  If(A>=$40) and A<=$60 Then Goto ESC$(A)
  If A>=$30 Then CMODE$="_SK2" : Pop Proc
  If A>=$20 Then CMODE$="_SKP" : Pop Proc
  Pop Proc
  '
  ' Codes ESC : Paper / Pen  
  _PAP: If GMODE=0 : GOPAP=A-$50 : Pop Proc : End If 
  CPAP=A-$50 : Paper CPAP : Gosub _SINV : GOPAP=-1
  Pop Proc
  _PEN: Pen A-$40+FLSH : CPEN=A-$40 : Gosub _SINV
  Pop Proc
  ' Codes ESC : Mosaiques séparées ou non
  _G1N: If GMODE=2 : _SET_FONT[1] : GMODE=1 : End If 
  Pop Proc
  _G1L: If GMODE=1 : _SET_FONT[2] : GMODE=2 : End If 
  Pop Proc
  ' Codes ESC : Inverse on / off 
  _INV: CINV=-1 : Inverse On : Pop Proc
  _NOR: CINV=0 : Inverse Off : Pop Proc
  ' Codes ESC : Taille des caracteres
  _GNN: PRNT$="_NNPRINT" : Pop Proc
  _GDX: If GMODE=0 : PRNT$="_DXPRINT" : End If : Pop Proc
  _GDY: If GMODE=0 : PRNT$="_DYPRINT" : End If : Pop Proc
  _GDD: If GMODE=0 : PRNT$="_DDPRINT" : End If : Pop Proc
  ' Codes ESC : Flash On / Off 
  _GFL: FLSH=8 : Pen CPEN+FLSH : Pop Proc
  _NFL: FLSH=0 : Pen CPEN : Pop Proc
  '
  ' Reinitialisations lors de LOCATE 
  _DEF: GMODE=0 : _SET_FONT[GMODE]
  Pen 7 : CPEN=7 : FLSH=0 : Paper 0 : CPAP=0 : GOPAP=-1
  CINV=0 : Gosub _SINV
  _DEF2: PRNT$="_NNPRINT"
  Return 
  '
  _NLINE:
  If GMODE=0
    Paper 0 : CPAP=0 : GOPAP=-1 : Gosub _SINV
  End If 
  PRNT$="_NNPRINT" : Return 
  '
End Proc
'
Procedure _SERIAL_GET
  '
  ' Attend un caractere de la série  
  ' ou du clavier
  Repeat 
    '
    A=Serial Get(0)
    '
    A$=Inkey$
    If A$<>"" : A=-Asc(A$) : Exit : End If 
    '
  Until A>=0
  '
End Proc[A]
'
Procedure _SET_FONT[N]
  '
  ' Adresse du jeu de caractere dans la banque 
  F=Start(15)+128*8*N+Sgn(N)*128*8
  ' Adresse dans la structure fenetre
  A=Leek(Screen Base+170)+8
  '
  Loke A,F
  '
End Proc


[Retour en haut] / [Retour aux articles]