[Thomson] SUDOKU, nouveau jeu pour MO et TO

Cette catégorie traite de développements récents pour nos vieilles machines, applications, jeux ou démos... Amis programmeurs, c'est ici que vous pourrez enfin devenir célèbres!

Modérateurs : Papy.G, fneck, Carl

Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

[Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par Daniel »

SUDOKU est un nouveau jeu pour tous les MO et TO, développé en juillet 2021.

Il vient tout juste d'être terminé, je propose dans le forum cette version beta avant de la diffuser officiellement via le site dcmoto.
Dans l'état actuel il n'y a que 16 grilles différentes intégrées au programme, mais il est prévu dans une prochaine version de stocker les grilles dans des fichiers annexes pouvant contenir un nombre de grilles non limité.
sudoku_moto.zip
(25.12 Kio) Téléchargé 82 fois

03.png
03.png (2.56 Kio) Consulté 3187 fois

04.png
04.png (3.37 Kio) Consulté 3187 fois
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par __sam__ »

Arg... je n'arrivais pas à le faire marcher jusqu'à ce que je réalise que le nom contienne "moto" et que je me dise que c'est un fichier SD pour l'interface SDMoto et pas SDDrive. Et effectivement j'étais sous SDDrive. Je suis passé sur SDMoto sur émulateur et là ca fonctionne.

J'ai lancé mon outil d'analyse dessus. Je constate que c'est de l'ASM. Bravo! (je pensais plus à du basic) Les fontes sont très lisibles. C'est cool 8) Bon par contre je ne suis pas très bon sur ce genre de puzzles. Je serais plus du genre à écrire un programme qui le résout pour moi :)

Une question: pourquoi CMPB #0 et pas TSTB en $91E2 ?
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
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par Daniel »

J'ai du faire une bêtise car le fichier .sd devrait fonctionner avec tous les contrôleurs de cartes SD, en particulier avec SDDRIVE.
C'est une version beta, j'ai déjà fait deux nouvelles versions depuis hier soir, avec les grilles dans un fichier séparé. Dès que possible je posterai un nouveau fichier .sd. Pour ceux qui n'ont pas de contrôleur de carte SD il est possible de le convertir au format .fd.

Dans mon jargon moto.fd ou moto.sd signifie que le programme fonctionne aussi bien avec un MO qu'avec un TO. Sinon c'est mo5.sd, ou to7.sd, ou to8.sd, etc. C'est sans rapport avec le contrôleur utilisé.

Toutes les images de disquettes Thomson au format .sd doivent fonctionner avec tous les contrôleurs : CS91280, CS91282, SDDISK et SDDRIVE.
Par contre les démonstrations de streaming audio ou vidéo utilisent des fonctions de lecture de la carte SD dépendantes du contrôleur, elles sont donc spécifiques CS9128x, SDDISK, SDDRIVE ou SDSTREAM.

SUDOKU est en assembleur car je ne supporte plus la lenteur du BASIC. A l'époque on s'en contentait mais aujourd'hui on a pris de mauvaises habitudes avec les PC modernes. C'est aussi pourquoi je ne supporte plus la lenteur des cassettes ou de SDLEP-TFT.

Le sudoku n'étant pas un jeu d'action il n'est pas très utile d'optimiser le programme, je n'ai rien fait dans ce sens. Par contre je vais remplacer le CMPB par un TST. Au départ je testais la valeur maxi, c'est pourquoi j'avais mis le CMPB. Ensuite j'ai fait la boucle à l'envers (c'est toujours plus élégant), avec arrêt à zéro, et j'ai laissé le CMPB. Ce n'est pas bien grave.

Quand la vitesse n'est pas importante je privilégie la lisibilité du programme. Il serait très facile de trouver plein d'autres optimisations mais c'est sans intérêt.

Code : Tout sélectionner

 PRAGMA 6809,operandsizewarning
 OPT c
;**************************************************;
;               D C S U D O K U                    ; 
;           (c) 2021 - Daniel Coulom               ;  
;           http://dcmoto.free.fr/                 ;
;           http://forum.system-cfg.com/           ;
;--------------------------------------------------;
; Ce code est distribue gratuitement dans l'espoir ;
; qu'il sera utile, mais sans aucune  garantie  et ;
; sans  engager  la  responsabilité  de  l'auteur. ;
; Vous  pouvez  l' utiliser,  le  modifier  et  le ;
; diffuser librement, en conservant cette  licence ;
; et les références de l'auteur dans   toutes  les ;
; copies. L'exploitation commerciale est interdite.;
;**************************************************;

    
;**************************************************;
;                Version 2021.07.10                ;
;**************************************************;
; Historique
; 2021.07.10 Controle validite grille
; 2021.07.09 Affichage des grilles
; 2021.07.09 Affichage des chiffres
; 2021.07.08 Simplification deplacement curseur
; 2021.07.07 Ajout du curseur
; 2021.07.06 Affichage quadrillage et titre

;------------------------------------------------------
; INITIALISATION DU TYPE D'ORDINATEUR (0=MO,1=TO)
;------------------------------------------------------
  ORG   $9000 
  PSHS  U,Y,X,DP,B,A,CC
  ORCC  #$50           ; desactive les interruptions 
  CLR   MOTO           ; 0 = MO
  LDB   >$FFF2         ; poids fort du vecteur SWI3
  BMI   INITMO         ; initialisation MO
  INC   MOTO           ; 1 = TO
  LDA   #$60           ; valeur initialisation DP pour TO
  BPL   INITTO         ; positif --> TO 

;------------------------------------------------------
; Initialisations speciales pour MO
;------------------------------------------------------
INITMO
  LDD   #$3F82         ; affichage caractere MO = SWI #$82
  STD   WCHAR          ; modification routine affichage
  LDB   #$8A           ; lecture clavier MO = SWI #$8A
  STD   RCHAR          ; modification routine lecture
  LDB   #$7B           ; code inversion video pour MO
  STB   INVER1+1       ; modification code inversion video
  LDA   #$20           ; valeur initialisation DP pour MO
  CLR   VRAM0          ; raz adresse debut memoire video
  LDU   #$1717         ; couleur rouge/blanc
  STU   ROUGE          ; stockage couleur
  LDU   #$0707         ; couleur noir/blanc
  STU   NOIR           ; stockage couleur
  LDA   #$A7           ; valeur pour registre dp
  TFR   A,DP           ; initialisation registre dp 
  BRA   INIT1          ; initialisation de l'ecran 

;------------------------------------------------------
; Initialisations speciales pour TO
;------------------------------------------------------
INITTO
  LDA   #$E7           ; valeur pour registre dp
  TFR   A,DP           ; initialisation registre dp 
  LDB   #$38           ; caractere 8
  CMPB  >$0009         ; test du 8 de BASIC 128
  BNE   INIT1          ; ce n'est pas le BASIC 128 

;------------------------------------------------------
; Initialisation banque memoire TO7/70 en BASIC 128
;------------------------------------------------------
  LDB   <$CB           ; charger DDRB
  ANDB  #$FB           ; RAZ bit 2
  STB   <$CB           ; modifier DDRB
  LDB   #$0F           ; valeur pour premiere banque RAM
  STB   <$C9           ; stocker dans PORTB 
  LDB   <$CB           ; charger DDRB
  ORB   #$04           ; positionner bit 2
  STB   <$CB           ; modifier DDRB
  
;------------------------------------------------------
; Initialisation de l'ecran
;------------------------------------------------------
INIT1
  LDY   #ECRAN         ; adresse chaine initialisation ecran
  LBSR  WSTR           ; affichage d'une chaine 
  
;------------------------------------------------------
; AFFICHAGE DU TITRE
;------------------------------------------------------
TITR1  
  LBSR  VIDEOC         ; selection video couleur
  LDU   ROUGE          ; couleur rouge/blanc
  LDY   VRAM0          ; adresse ecran
  LEAY  $05B8,Y        ; debut derniere ligne image
  LDA   #$24           ; pour 36 lignes
TITR2
  LDB   #$08           ; pour 8 boucles
TITR3
  STU   ,Y++           ; affichage de 2 octets  
  DECB                 ; decrementation n° segment
  BNE   TITR3          ; nouveau segment
  LEAY  -$38,Y         ; ligne au-dessus
  DECA                 ; decrementation n° ligne
  BNE   TITR2          ; ligne suivante
TITR4  
  LBSR  VIDEOF         ; selection video forme
  LDX   #TITRE         ; adresse image
  LDY   VRAM0          ; adresse ecran
  LEAY  $0838,Y        ; debut derniere ligne image
  LDA   #$34           ; pour 36 lignes
TITR5
  LDB   #$08           ; pour 8 boucles
TITR6
  LDU   ,X++           ; lecture de 16 pixels
  STU   ,Y++           ; affichage de 16 pixels
  DECB                 ; decrementation n° segment
  BNE   TITR6          ; segment suivant 
  LEAY  -$38,Y         ; ligne au-dessus
  DECA                 ; decrementation n° ligne
  BNE   TITR5          ; ligne suivante
  
;------------------------------------------------------
; QUADRILLAGE ECRAN
;------------------------------------------------------
CADRE
  CLRA                 ; ligne 0 
CADRE1  
  LBSR  LIGNE
  INCA
  CMPA  #$B6           ; ligne 182
  BNE   CADRE1
  
;------------------------------------------------------
; AFFICHAGE GRILLE
;------------------------------------------------------
SETGR
  LDD   #GRILLES       ; adresse des grilles
  SUBD  #$51           ; adresse grilles -81
  STD   GRIADDR        ; stocke adresse grilles - 81 
  LDD   #$3030         ; "00"
  STD   GRINUM         ; zero dans numero grille courante
SETGR0 
  LDX   GRIADDR        ; pointeur grille courante
  LEAX  $51,X          ; grille suivante
  STX   GRIADDR        ; adresse grille suivante
  LDA   ,X             ; test fin des grilles
  BEQ   SETGR          ; retour a la premiere grille
  LDA   GRINUM+1       ; unite n° grille
  INCA                 ; +1
  CMPA  #$3A           ; test dizaine
  BNE   SETGR1         ; sinon afficher
  INC   GRINUM         ; ajout dizaine
  LDA   #$30           ; raz unite
SETGR1
  STA   GRINUM+1       ; mise a jour unite
  LDY   #GRILIB        ; adresse libelle grille
  LBSR  WSTR           ; affichage d'une chaine 
  CLRA                 ; numero de case
SETGR2   
  LDX   GRIADDR        ; adresse de la grille
  LDB   A,X            ; chiffre de la grille
;  BPL   SETGR3         ; chiffre d'origine           
;  LDB   #$30           ; raz chiffre joue
SETGR3  
  PSHS  B              ; sauvegarde du chiffre
  LBSR  CHIFFRE        ; afficher le chiffre
  PULS  B              ; restaurer le chiffre
  TSTB                 ; test du chiffre
  BMI   SETGR4         ; chiffre joue 
  CMPB  #$30           ; case vide
  BEQ   SETGR4         ; initialisation case vide
  LDB   ROUGE          ; couleur des chiffres
  BRA   SETGR5         ; initialisation couleur
SETGR4
  LDB   NOIR           ; couleur case vide
SETGR5
  LBSR  COLOR          ; change la couleur 
  INCA                 ; case suivante
  CMPA  #$51           ; test fin de grille 
  BNE   SETGR2         ; sinon continuer
  LDA   CURPOS         ; position curseur
  ORA   #$80           ; b7 pour affichage
  LBSR  DISPLAYC       ; affichage curseur
  LBRA  JEU1           ; suite du jeu

;------------------------------------------------------
; CONTROLE DES COMPTEURS
;------------------------------------------------------
COMPT2
  PSHS  A              ; empilage de A
  LDY   #COMPTEUR      ; adresse compteurs
  LDB   #$09           ; dernier compteur
COMPT3
  LDA   B,Y            ; valeur compteur
  CMPA  #$01           ; comparaison a 1 
  BGT   COMPT4         ; chifre en double 
  DECB                 ; decrementation indice
  BNE   COMPT3         ; compteur precedent
  CLRA                 ; sortie sans erreur
  PULS  A,PC           ; retour
COMPT4
  COMA                 ; sortie en erreur 
  PULS  A,PC           ; retour

;------------------------------------------------------
; INITIALISATION DES COMPTEURS
;------------------------------------------------------
COMPT0
  LDY   #COMPTEUR      ; adresse compteurs
  LDB   #$09           ; dernier compteur
COMPT1
  CLR   B,Y            ; raz compteur
  DECB                 ; decrementation indice
  BNE   COMPT1         ; compteur precedent
  RTS                  ; retour

;------------------------------------------------------
; CONTROLE DE VALIDITE DES LIGNES
;------------------------------------------------------
CONTROL1
  LDX   GRIADDR        ; pointeur grille courante
  LDA   #$09           ; debut deuxieme ligne
  STA   MAXA           ; stokage de la valeur
  CLRA                 ; debut premiere ligne
CONTR11
  BSR   COMPT0         ; initialisation des compteurs
CONTR12
  LDB   A,X            ; chiffre ligne
  ANDB  #$0F           ; isole la valeur 0-9
  INC   B,Y            ; incremente le compteur
  INCA                 ; chiffre suivant
  CMPA  MAXA           ; test fin de ligne
  BNE   CONTR12        ; nouveau chiffre
  BSR   COMPT2         ; test des compteurs
  BCS   CONTROL8       ; erreur ligne
  CMPA  #$51           ; test de fin
  BEQ   CONTROL2       ; test des colonnes
  ADDA  #$09           ; fin ligne suivante
  STA   MAXA           ; stokage de la valeur
  SUBA  #$09           ; debut nouvelle ligne  
  BRA   CONTR11        ; nouvelle ligne

;------------------------------------------------------
; CONTROLE DE VALIDITE DES COLONNES
;------------------------------------------------------
CONTROL2
  LDX   GRIADDR        ; pointeur grille courante
  LDA   #$51           ; fin premiere colonne + 1
  STA   MAXA           ; stokage de la valeur
  CLRA                 ; debut premiere colonne
CONTR21
  BSR   COMPT0         ; initialisation des compteurs
CONTR22
  LDB   A,X            ; chiffre colonne
  ANDB  #$0F           ; isole la valeur 0-9
  INC   B,Y            ; incremente le compteur
  ADDA  #$09           ; chiffre suivant
  CMPA  MAXA           ; test fin de colonne
  BNE   CONTR22        ; nouveau chiffre
  BSR   COMPT2         ; test des compteurs
  BCS   CONTROL8       ; erreur colonne
  CMPA  #$51           ; test de fin
  BEQ   CONTROL3       ; test des carres
  ADDA  #$09           ; fin ligne suivante
  STA   MAXA           ; stokage de la valeur
  SUBA  #$51           ; debut nouvelle colonne  
  BRA   CONTR21        ; nouvelle colonne

;------------------------------------------------------
; CONTROLE DE VALIDITE DES CARRES
;------------------------------------------------------
CONTROL3
  LDX   GRIADDR        ; pointeur grille courante
  LDA   #$1B           ; fin premier carre (27) 
  STA   MAXA           ; stokage de la valeur
  CLRA                 ; premiere case premier carre
CONTR31
  BSR   COMPT0         ; initialisation des compteurs
CONTR32
  LDB   A,X            ; chiffre colonne
  ANDB  #$0F           ; isole la valeur 0-9
  INC   B,Y            ; incremente le compteur
  INCA                 ; case suivante
  LDB   A,X            ; chiffre colonne
  ANDB  #$0F           ; isole la valeur 0-9
  INC   B,Y            ; incremente le compteur
  INCA                 ; case suivante
  LDB   A,X            ; chiffre colonne
  ANDB  #$0F           ; isole la valeur 0-9
  INC   B,Y            ; incremente le compteur
  ADDA  #$07           ; ligne suivante
  CMPA  MAXA           ; fin du carre
  BNE   CONTR32        ; nouveau chiffre
  LBSR  COMPT2         ; test des compteurs
  BCS   CONTROL8       ; erreur carre
  CMPA  #$57           ; test de dernier carre
  BEQ   CONTROL9       ; pas d'erreur
  CMPA  #$54           ; test de fin 6e carre
  BEQ   CONTR33        ; colonne suivante
  CMPA  #$51           ; test de fin 3e carre
  BEQ   CONTR33        ; colonne suivante       
  ADDA  #$1B           ; fin carre de dessous
  STA   MAXA           ; stokage de la valeur
  SUBA  #$1B           ; debut nouveau carre  
  BRA   CONTR31        ; nouveau carre
CONTR33
  SUBA  #$33           ; fin carre colonne suivante
  STA   MAXA           ; stokage de la valeur
  SUBA  #$1B           ; debut nouveau carre  
  BRA   CONTR31        ; nouveau carre

;------------------------------------------------------
; ERREUR DETECTEE LORS DU CONTROLE
;------------------------------------------------------
CONTROL8
  LDY   #GRIERR        ; grille erronee
  LBSR  WSTR           ; affichage d'une chaine 
  LDA   #$80           ; duree
  LDX   #$0100         ; periode
  LBSR  BUZZ           ; signal sonore
  BRA   JEU1           ; suite du jeu

;------------------------------------------------------
; PAS D'ERREUR APRES CONTROLE
;------------------------------------------------------
CONTROL9
  LDY   #GRIOK         ; grille OK
  LBSR  WSTR           ; affichage d'une chaine 
  LDA   #$20           ; duree
  LDX   #$0080         ; periode
  LBSR  BUZZ           ; signal sonore

;------------------------------------------------------
; DEROULEMENT DU JEU
;------------------------------------------------------
JEU
JEU1
  BSR   RCHAR          ; lecture clavier
  TSTB                 ; test code touche          
  BEQ   JEU1           ; pas de touche a traiter
  LDY   #GRIEFF        ; effacement du diagnostic
  LBSR  WSTR           ; affichage d'une chaine 
  BSR   CURSOR         ; deplacement curseur
  CMPB  #$0C           ; touche RAZ
  BEQ   RETOUR         ; retour au BASIC
  CMPB  #$02           ; touche STOP
  LBEQ  SETGR0         ; nouvelle gille
  CMPB  #$0D           ; touche ENTREE
  LBEQ  CONTROL1       ; controle de la grille
  CMPB  #$20           ; ESPACE
  BEQ   JEU2           ; effacement de la case
  CMPB  #$30           ; touche '0'          
  BLS   JEU1           ; inferieur ou egal a '0'
  CMPB  #$3A           ; touche ':'          
  BHS   JEU1           ; superieur ou egal a ':'
JEU2
  LDX   GRIADDR        ; pointeur grille
  LDA   A,X            ; case de la grille
  BMI   JEU3           ; emplacement déjà joue
  CMPA  #$30           ; test caractere '0'
  BNE   JEU4           ; emplacement occupe
JEU3
  LDA   CURPOS         ; A=position curseur           
  ORB   #$80           ; indicateur de chiffre joue
  LBSR  CHIFFRE        ; affichage du chiffre B
  BRA   JEU1           ; nouvelle boucle
JEU4
  LDA   #$10           ; duree
  LDX   #$0100         ; periode
  LBSR  BUZZ           ; signal sonore
  BRA   JEU1           ; nouvelle boucle

;------------------------------------------------------
; RETOUR AU BASIC
;------------------------------------------------------
RETOUR
  PULS  CC,A,B,DP,X,Y,U,PC

;------------------------------------------------------
; LECTURE DU CLAVIER (RETOUR DANS LE REGISTRE B)
; Version pour TO remplacee par SWI #$8A pour MO
;------------------------------------------------------
RCHAR
  JMP   $E806          ; lecture du clavier
  
;------------------------------------------------------
; DEPLACEMENT CURSEUR (B contient le code de la touche)
;------------------------------------------------------
CURSOR
  LDA   CURPOS         ; position du curseur

* Deplacement eventuel vers la gauche
CURS1  
  CMPB  #$08           ; backspace
  BNE   CURS2          ; ne rien faire
  CMPA  #$00           ; test premiere case
  BEQ   CURS2          ; deplacement impossible
  BSR   DISPLAYC       ; effacement curseur
  DECA                 ; position precedente
  BRA   CURS8          ; afficher curseur

* Deplacement eventuel vers la droite
CURS2  
  CMPB  #$09           ; horizontal tabulation
  BNE   CURS3          ; ne rien faire
  CMPA  #$50           ; test derniere case        
  BEQ   CURS3          ; deplacement impossible
  BSR   DISPLAYC       ; effacement curseur
  INCA                 ; position suivante
  BRA   CURS8          ; afficher curseur

* Deplacement eventuel vers le bas
CURS3
  CMPB  #$0A           ; line feed 
  BNE   CURS4          ; ne rien faire
  CMPA  #$48           ; test derniere rangee        
  BHS   CURS4          ; deplacement impossible
  BSR   DISPLAYC       ; effacement curseur
  ADDA  #$09           ; ligne suivante
  BRA   CURS8          ; afficher curseur

* Deplacement eventuel vers le haut
CURS4
  CMPB  #$0B           ; vertical tabulation
  BNE   CURS9          ; ne rien faire
  CMPA  #$08           ; test premiere rangee        
  BLS   CURS9          ; deplacement impossible
  BSR   DISPLAYC       ; effacement curseur
  SUBA  #$09           ; ligne precedente

* Afficher le curseur
CURS8
  STA   CURPOS         ; stockage position
  ORA   #$80           ; flag affichage
  BSR   DISPLAYC       ; affichage curseur
  CLRB                 ; raz code touche
CURS9
  RTS
  
;------------------------------------------------------
; AFFICHAGE/EFFACEMENT DU CURSEUR
; registre A b0-b6 = numero de case
; registre A b7 = 0 (effacement) ou 1 (affichage)
;------------------------------------------------------
DISPLAYC
  PSHS  A              ; sauvegarde de A
  LDY   VRAM0          ; adresse debut ecran
  LDX   #CASE_X        ; pointeur table coordonnees
  ANDA  #$7F           ; isole le n° de case 
  LEAX  A,X            ; additionner A deux fois  
  LEAX  A,X            ; car 2*A peut être negatif  
  LDD   ,X             ; coordonnees case
  TST   ,S             ; test affichage/effacement
  BMI   DISPLAYC1      ; affichage
  LDX   #CURSM2        ; masque effacement curseur     
  BRA   DISPLAYC2      ; affichage
DISPLAYC1   
  LDX   #CURSM1        ; masque curseur colonne impaire     
  TSTA                 ; test pour controler le bit 7 
  BMI   DISPLAYC2      ; colonne impaire
  LDX   #CURSM0        ; masque curseur colonne paire     
DISPLAYC2  
  ANDA  #$7F           ; supprime le bit de parite 
  ADDD  #$02D1         ; position curseur dans la case 
  LEAY  D,Y            ; adresse du curseur
  LDA   ,X             ; masque du curseur
  STA   ,Y             ; affichage
  PULS  A,PC           ; retour
  RTS

;------------------------------------------------------
; AFFICHAGE D'UN CHIFFRE B en CASE A
;------------------------------------------------------
CHIFFRE
  PSHS  A              ; sauvegarde n° de case
  LDX   GRIADDR        ; adresse grille courante
  STB   A,X            ; stocke le chiffre dans la grille
  LDY   #FONT          ; pointeur table des chiffres
  ANDB  #$0F           ; isole le chiffre
  LSLB                 ; multiplie par 2
  LSLB                 ; multiplie par 4
  LEAY  B,Y            ; pointeur chiffre*4 
  LSLB                 ; multiplie par 8
  LEAY  B,Y            ; pointeur chiffre*12 
  LDX   #CASE_X        ; pointeur table coordonnees
  LEAX  A,X            ; demi-deplacement
  LEAX  A,X            ; demi-deplacement
  LDD   ,X             ; adresse de la case
  LDX   VRAM0          ; adresse debut ecran
  TSTA                 ; test parite colonne
  BMI   CHIFFR2        ; colonne impaire
  ADDD  #$00A1         ; pointeur haut du chiffre
  LEAX  D,X            ; adresse dans X
  LDB   #$0C           ; pour 12 boucles
CHIFFR1  
  LEAX  $28,X          ; ligne suivante
  LDA   ,Y+            ; octet du chiffre
  STA   ,X             ; affichage
  DECB                 ; decrementation compteur
  BNE   CHIFFR1        ; boucle suivante
  BRA   CHIFFR9        ; retour
CHIFFR2
  ANDA  #$7F           ; suppression bit de parite  
  ADDD  #$00A1         ; pointeur haut du chiffre
  LEAX  D,X            ; adresse dans X
  LDB   #$0C           ; pour 12 boucles
CHIFFR3
  LEAX  $28,X          ; ligne suivante
  LDA   ,Y             ; octet du chiffre
  LSRA                 ; decalage
  LSRA                 ; a droite
  LSRA                 ; d'un
  LSRA                 ; demi-octet
  STA   ,X             ; affichage partie gauche
  LDA   ,Y+            ; octet du chiffre
  LSLA                 ; decalage
  LSLA                 ; a gauche
  LSLA                 ; d'un
  LSLA                 ; demi-octet 
  STA   1,X            ; affichage partie droite
  DECB                 ; decrementation compteur
  BNE   CHIFFR3        ; boucle suivante
CHIFFR9
  PULS  A,PC           ; retour
  
;------------------------------------------------------
; CHANGEMENT CASE A EN COULEUR B
;------------------------------------------------------
COLOR
  PSHS  B,A            ; sauvegarde case et couleur
  BSR   VIDEOC         ; selection video couleur
  LDA   ,S             ; A=case
  LDX   #CASE_X        ; pointeur table coordonnees
  LEAX  A,X            ; demi-deplacement
  LEAX  A,X            ; demi-deplacement
  LDD   ,X             ; adresse de la case
  LDX   VRAM0          ; adresse debut ecran
  TSTA                 ; test parite colonne
  BMI   COLOR2         ; colonne impaire
  ADDD  #$00A1         ; pointeur haut du chiffre
  LEAX  D,X            ; adresse dans X
  LDA   1,S            ; A=couleur
  LDB   #$0C           ; pour 12 boucles
COLOR1  
  LEAX  $28,X          ; ligne suivante
  STA   ,X             ; changement couleur
  DECB                 ; decrementation compteur
  BNE   COLOR1         ; boucle suivante
  BRA   COLOR9         ; retour
COLOR2
  ANDA  #$7F           ; suppression bit de parite  
  ADDD  #$00A1         ; pointeur haut du chiffre
  LEAX  D,X            ; adresse dans X
  LDA   1,S            ; A=couleur
  LDB   #$0C           ; pour 12 boucles
COLOR3
  LEAX  $28,X          ; ligne suivante
  STA   ,X             ; couleur partie gauche
  STA   1,X            ; couleur partie droite
  DECB                 ; decrementation compteur
  BNE   COLOR3         ; boucle suivante
COLOR9
  BSR   VIDEOF         ; selection video forme 
  PULS  A,B,PC         ; retour

;------------------------------------------------------
; SELECTION PAGE VIDEO COULEUR
;------------------------------------------------------
VIDEOC  
  TST   >$FFF2         ; poids fort du vecteur SWI3
  BPL   VIDEOCTO       ; positif --> TO 
VIDEOCMO
  LDA   $A7C0          ; chargement PA du PIA systeme
  ANDA  #$FE           ; raz b0 (page video couleur) 
  STA   $A7C0          ; selection video couleur
  RTS
VIDEOCTO
  LDA   $E7C3          ; chargement PRC du 6846
  ANDA  #$FE           ; raz b0 (page video couleur) 
  STA   $E7C3          ; selection video couleur
  RTS

;------------------------------------------------------
; SELECTION PAGE VIDEO FORME
;------------------------------------------------------
VIDEOF  
  TST   >$FFF2         ; poids fort du vecteur SWI3
  BPL   VIDEOFTO       ; positif --> TO 
VIDEOFMO
  LDA   $A7C0          ; chargement PA du PIA systeme
  ORA   #$01           ; set b0 (page video forme) 
  STA   $A7C0          ; selection video forme
  RTS
VIDEOFTO
  LDA   $E7C3          ; chargement PRC du 6846
  ORA   #$01           ; set b0 (page video forme) 
  STA   $E7C3          ; selection video forme
  RTS

;------------------------------------------------------
; AFFICHAGE CHAINE TERMINEE PAR ZERO (Adresse dans Y)
; Le registre B est preserve
;------------------------------------------------------
WSTR 
  PSHS  B
WSTR1
  LDB   ,Y+            ; caractere a ecrire
  BEQ   WSTR9          ; fin de la chainee
  BSR   WCHAR          ; envoi caractere
  BRA   WSTR1          ; caractere suivant
WSTR9
  BSR  VIDEOF          ; selection video forme 
  PULS  B,PC           ; retour

;------------------------------------------------------
; AFFICHAGE CARACTERE (CARACTERE DANS REGISTRE B)
; Version TO remplacee par SWI #$82 pour MO
;------------------------------------------------------
WCHAR
  JMP   $E803          ; envoi caractere

;------------------------------------------------------
; INVERSION VIDEO
;------------------------------------------------------
INVERS
  LDB   #$1B           ; sequence d'echappement
  BSR   WCHAR          ; envoi caractere
INVER1
  LDB   #$5C           ; inverse video pour TO
                       ; remplace par #$7B pour MO
  BSR   WCHAR          ; envoi caractere
  RTS

;------------------------------------------------------
; Affichage ligne A du quadrillage
;------------------------------------------------------
LIGNE
  PSHS  A
  LDB   #$28           ; nombre d'octets par ligne  
  MUL                  ; multiplication par le numero
  LDY   VRAM0          ; adresse debut memoire video
  LEAY  D,Y            ; adresse debut de ligne
  LDA   ,S             ; restaurer A
  LDX   #LBLANC        ; adresse ligne blanche   
  LDB   #$80           ; A=0 B=$80
  LSRA
  BCC   LIGNE1
  LSRB                 ; A=1 B=$40
LIGNE1  
  LSRA
  BCC   LIGNE2
  LSRB
  LSRB                 ; A=2 B=$10
LIGNE2  
  LSRA
  BCC   LIGNE3
  LSRB
  LSRB
  LSRB
  LSRB                 ; A=4 B=$01
LIGNE3  
  ANDB  A,X            ; type de ligne
  BEQ   LIGNE4         ; ligne blanche
  LDX   #LNOIR         ; adresse ligne noire   
LIGNE4  
  LDB   #$17           ; pour 23 boucles
LIGNE5
  LDA   ,X+            ; octet a afficher
  STA   ,Y+            ; affichage
  DECB
  BNE   LIGNE5
  PULS  A,PC
  
;------------------------------------------------------
; TEMPORISATION EN FONCTION DE X
;------------------------------------------------------
TEMPO
  PSHS  X
TEMPO1
  LEAX  -1,X
  BNE   TEMPO1
  PULS  X,PC  

;------------------------------------------------------
; EMISSION SIGNAL SONORE
; TEMPO DANS X
; DUREE DANS A
;------------------------------------------------------
BUZZ
; ORCC  #$50           ; masque les interruptions
  PSHS  A              ; compteur duree note
  TST   MOTO           ; test du type d'ordinateur
  BNE   BUZZ2
BUZZ1  
  LDY   #BUZZMO        ; masques pour buzzer MO
  BRA   BUZZ3
BUZZ2  
  LDY   #BUZZTO        ; masques pour buzzer MO
BUZZ3
  LDA   <$C1           ; registre du buzzer
BUZZ4
  ORA   ,Y             ; masque buzzer haut
  STA   <$C1           ; buzzer etat haut 
  BSR   TEMPO          ; temporisation 
  ANDA  1,Y            ; masque buzzer bas
  STA   <$C1           ; buzzer etat bas
  BSR   TEMPO          ; temporisation 
  DEC   ,S             ; decrementation compteur
  BNE   BUZZ4
BUZZ9
  PULS  A              ; depile duree note
; ANDCC #$AF           ; restaure les interruptions
  RTS

;------------------------------------------------------
; Ligne noire du tableau
;------------------------------------------------------
LNOIR
  FCB   $FF,$FF,$FF,$FF,$FF,$FF,$FF
  FCB   $FF,$FF,$FF,$FF,$FF,$FF,$FF
  FCB   $FF,$FF,$FF,$FF,$FF,$FF,$FF
  FCB   $FF,$FC

;------------------------------------------------------
; Ligne blanche du tableau
;------------------------------------------------------
LBLANC
  FCB   $C0,$00,$08,$00,$00,$80,$00
  FCB   $0C,$00,$00,$80,$00,$08,$00
  FCB   $00,$C0,$00,$08,$00,$00,$80
  FCB   $00,$0C

;------------------------------------------------------
; Image de titre 16x48
;------------------------------------------------------
TITRE
  FDB   $1818,$0000,$0000,$0000,$3800,$0000,$0000,$0000
  FDB   $300C,$0000,$0000,$0000,$1800,$0000,$0000,$0000
  FDB   $63E6,$07CF,$3E3C,$63C0,$19E6,$D9E3,$C7E7,$9F9E
  FDB   $67F6,$0FDF,$BF7E,$63C0,$1BF6,$DBF3,$C7EF,$DF9E
  FDB   $6E36,$0CD9,$8366,$6300,$1B36,$DB03,$060C,$D80C
  FDB   $6E06,$0CD8,$1F66,$630E,$1B36,$DBE3,$038C,$CE0C
  FDB   $6E06,$0CD8,$3E66,$630E,$1B36,$DBF3,$01CC,$C70C
  FDB   $6E36,$0CD9,$B066,$6300,$1B36,$DB33,$00CC,$C30C
  FDB   $67F6,$0FDF,$BF7E,$F780,$1B36,$DBF7,$806C,$C18C
  FDB   $63E6,$07CF,$1E3C,$F780,$1B36,$D9E7,$806C,$C1AC
  FDB   $6006,$00C0,$0000,$6300,$0000,$D803,$066C,$D9BC
  FDB   $300C,$00C0,$0000,$7B00,$1806,$D803,$07EF,$DF9C
  FDB   $1818,$00C0,$0000,$7800,$1806,$D800,$03C7,$8F0C
  FDB   $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
  FDB   $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
  FDB   $0000,$0000,$0000,$0000,$0000,$0000,$0000,$0000
  FDB   $6006,$0000,$0E00,$E000,$00E0,$0040,$C000,$0070
  FDB   $7807,$0000,$0F00,$F000,$01E0,$00E0,$C000,$0078
  FDB   $7E07,$8078,$0F81,$FC00,$07E0,$00E1,$E003,$C07C
  FDB   $7F07,$C0FE,$0FC3,$FE00,$0FF0,$00E1,$F00F,$E07C
  FDB   $7FEF,$E3FF,$8FE3,$FF00,$1FFC,$00E1,$F01F,$F87E
  FDB   $7FFF,$E3FF,$CFE3,$FF80,$3FFE,$01E1,$F81F,$FE7F
  FDB   $7FFF,$FBFF,$EFF3,$FFC0,$7FFF,$01E1,$FC1F,$FF7F
  FDB   $7FFF,$FBFF,$FFF3,$FFE0,$7FCF,$01E1,$FC3F,$FFFF
  FDB   $179F,$F3FC,$7FF3,$DFE0,$FF07,$81E3,$FE3F,$E1FF
  FDB   $001F,$E7F8,$0FF3,$C7F0,$FE03,$C1E3,$FC3F,$80FF
  FDB   $001F,$C7F0,$0FE3,$C3F8,$FE01,$E1E7,$F83F,$807F
  FDB   $001F,$C7F0,$0FE3,$C3F8,$FC01,$F1E7,$F03F,$007F
  FDB   $003F,$87E0,$0FE3,$C1FC,$FC01,$F1E7,$F03F,$007F
  FDB   $003F,$87E0,$0FE3,$C0FC,$F800,$F1E7,$F03F,$007F
  FDB   $003F,$07E0,$0FE3,$E0FE,$F800,$FBE7,$E03F,$007F
  FDB   $007E,$07E0,$0FE3,$E07E,$F800,$FBE7,$C03F,$007E
  FDB   $007E,$07E0,$0FC3,$E07E,$F800,$FBE7,$C03F,$007E
  FDB   $007C,$07E0,$0FC3,$E07E,$F800,$FBEF,$803E,$007E
  FDB   $00F8,$07C0,$0F83,$E07E,$F800,$FBEF,$003E,$007C
  FDB   $00F8,$07C0,$0F83,$E07E,$F800,$FBEF,$003E,$007C
  FDB   $00F0,$07C0,$0F83,$E07E,$F800,$FBFE,$003E,$007C
  FDB   $01E0,$07C0,$0F83,$E07E,$7800,$FBFE,$003E,$0078
  FDB   $01E0,$07C0,$0F07,$E07E,$7800,$FBFC,$003E,$0078
  FDB   $03C0,$07C0,$0F07,$E07E,$7800,$FBFC,$003E,$0078
  FDB   $0380,$07C0,$0F07,$E07E,$7801,$FBFF,$803E,$0078
  FDB   $0780,$07C0,$0F07,$E07C,$3C01,$FBF7,$E03E,$0070
  FDB   $0700,$07C0,$0E07,$E07C,$3C01,$F3F7,$F03E,$0070
  FDB   $0E00,$07C0,$0E07,$E078,$1E03,$F3F1,$FE3E,$0070
  FDB   $5E00,$07E0,$0E07,$E0F8,$0E07,$E3F0,$7FBE,$0070
  FDB   $FC00,$07E0,$0E07,$E0F8,$0F0F,$E3F0,$3FBE,$0060
  FDB   $FE00,$C7E0,$0E07,$C1F0,$071F,$C3F0,$1FBF,$0060
  FDB   $7FFF,$C3E0,$0C0F,$C3E0,$03BF,$83F0,$0FBF,$0060
  FDB   $FFFF,$C3E0,$0C0F,$C3E0,$01FF,$83F0,$079F,$0060
  FDB   $1FFF,$C3E0,$0C0F,$C7C0,$00FF,$03F0,$011F,$0060
  FDB   $07FF,$C3E0,$0C0F,$DF80,$003E,$03F0,$001F,$0040
  FDB   $01FF,$8040,$0C07,$FC00,$003C,$00F0,$0002,$0040
  
;------------------------------------------------------
; Position du curseur dans l'ecran
; Premier octet = numero de ligne
; Deuxieme octet b0-b6 = numero de colonne
; Deuxieme octet b7 = 0 (colonne paire) ou 1 (impaire)
;------------------------------------------------------
CADDR
  FDB  $1201,$1283,$1206,$1288,$120B,$128D,$1210,$1292,$1215
  FDB  $2601,$2683,$2606,$2688,$260B,$268D,$2610,$2692,$2615
  FDB  $3A01,$3A83,$3A06,$3A88,$3A0B,$3A8D,$3A10,$3A92,$3A15
  FDB  $4E01,$4E83,$4E06,$4E88,$4E0B,$4E8D,$4E10,$4E92,$4E15
  FDB  $6201,$6283,$6206,$6288,$620B,$628D,$6210,$6292,$6215
  FDB  $7601,$7683,$7606,$7688,$760B,$768D,$7610,$7692,$7615
  FDB  $8A01,$8A83,$8A06,$8A88,$8A0B,$8A8D,$8A10,$8A92,$8A15
  FDB  $9E01,$9E83,$9E06,$9E88,$9E0B,$9E8D,$9E10,$9E92,$9E15
  FDB  $B201,$B283,$B206,$B288,$B20B,$B28D,$B210,$B292,$B215
  
;------------------------------------------------------
; Coordonnees du coin haut-gauche des cases (b0-b14)
; b15=0 (colonne paire) ou b15=1 (colonne impaire)
;------------------------------------------------------
CASE_X
  FDB  $0000,$8002,$0005,$8007,$000A,$800C,$000F,$8011,$0014
  FDB  $0320,$8322,$0325,$8327,$032A,$832C,$032F,$8331,$0334
  FDB  $0640,$8642,$0645,$8647,$064A,$864C,$064F,$8651,$0654
  FDB  $0960,$8962,$0965,$8967,$096A,$896C,$096F,$8971,$0974
  FDB  $0C80,$8C82,$0C85,$8C87,$0C8A,$8C8C,$0C8F,$8C91,$0C94
  FDB  $0FA0,$8FA2,$0FA5,$8FA7,$0FAA,$8FAC,$0FAF,$8FB1,$0FB4
  FDB  $12C0,$92C2,$12C5,$92C7,$12CA,$92CC,$12CF,$92D1,$12D4
  FDB  $15E0,$95E2,$15E5,$95E7,$15EA,$95EC,$15EF,$95F1,$15F4
  FDB  $1900,$9902,$1905,$9907,$190A,$990C,$190F,$9911,$1914

;------------------------------------------------------
; CHIFFRES
;------------------------------------------------------
FONT
  FDB  $0000,$0000,$0000,$0000,$0000,$0000  ; ' '
  FDB  $0818,$2848,$0808,$0808,$0808,$0808  ; '1'
  FDB  $3C42,$8101,$0102,$0C30,$4080,$80FF  ; '2'
  FDB  $3C42,$8101,$020C,$0201,$0181,$423C  ; '3'
  FDB  $0202,$060A,$0A12,$2222,$42FF,$0202  ; '4'
  FDB  $FF80,$8080,$FC02,$0101,$0181,$423C  ; '5'
  FDB  $3E41,$8080,$80BC,$C281,$8181,$423C  ; '6'
  FDB  $FF01,$0202,$0404,$0808,$1010,$2020  ; '7'
  FDB  $3C42,$8181,$423C,$4281,$8181,$423C  ; '8'
  FDB  $3C42,$8181,$8143,$3D01,$0101,$827C  ; '9'

;------------------------------------------------------
; GRILLES
; Les zeros sont remplaces par les chiffres joues,
; ils sont differencies par le positionnement du bit 7
;------------------------------------------------------
GRILLES
; ----------------- grille 1
  FCC  "000000001"
  FCC  "210000904"
  FCC  "403500600"
  FCC  "900204500"
  FCC  "002705800"
  FCC  "001608003"
  FCC  "004007309"
  FCC  "709000068"
  FCC  "100000000"
; ----------------- grille 2
  FCC  "060230000"
  FCC  "008004000"
  FCC  "305008047"
  FCC  "002000001"
  FCC  "500060009"
  FCC  "900000700"
  FCC  "740900506"
  FCC  "000400900"
  FCC  "000083070"
; ----------------- grille 3
  FCC  "003850090"
  FCC  "000000100"
  FCC  "600000027"
  FCC  "000100900"
  FCC  "060507080"
  FCC  "008003000"
  FCC  "150000003"
  FCC  "002000000"
  FCC  "090085400"
; ----------------- grille 4
  FCC  "075006800"
  FCC  "000000003"
  FCC  "300510600"
  FCC  "020000000"
  FCC  "054801290"
  FCC  "000000050"
  FCC  "002059006"
  FCC  "700000000"
  FCC  "003100980"
; ----------------- grille 5
  FCC  "605000040"
  FCC  "000002076"
  FCC  "000700300"
  FCC  "000620080"
  FCC  "087050620"
  FCC  "000084000"
  FCC  "001005000"
  FCC  "520800000"
  FCC  "060000905"
; ----------------- grille 6
  FCC  "000360100"
  FCC  "000080000"
  FCC  "941502000"
  FCC  "050008007"
  FCC  "060020090"
  FCC  "800900050"
  FCC  "000106978"
  FCC  "000040000"
  FCC  "008097000"
; ----------------- grille 7
  FCC  "970000000"
  FCC  "305002940"
  FCC  "000095000"
  FCC  "000200005"
  FCC  "004080200"
  FCC  "500009000"
  FCC  "000670000"
  FCC  "082900703"
  FCC  "000000081"
; ----------------- grille 8
  FCC  "000003009"
  FCC  "048006072"
  FCC  "100000400"
  FCC  "709430000"
  FCC  "000020000"
  FCC  "000067201"
  FCC  "002000007"
  FCC  "930700610"
  FCC  "400600000"
; ----------------- grille 9
  FCC  "000100003"
  FCC  "000005800"
  FCC  "010007694"
  FCC  "000058000"
  FCC  "054902380"
  FCC  "000710000"
  FCC  "678300020"
  FCC  "003500000"
  FCC  "900001000"
; ----------------- grille 10
  FCC  "000000608"
  FCC  "569300000"
  FCC  "007600000"
  FCC  "100000500"
  FCC  "080975020"
  FCC  "050000004"
  FCC  "000007200"
  FCC  "000004753"
  FCC  "903000000"
; ----------------- grille 11
  FCC  "080000103"
  FCC  "709000824"
  FCC  "005000007"
  FCC  "020809000"
  FCC  "000401000"
  FCC  "000206080"
  FCC  "200000500"
  FCC  "451000302"
  FCC  "807000060"
; ----------------- grille 12
  FCC  "006007590"
  FCC  "000000020"
  FCC  "000063100"
  FCC  "095870002"
  FCC  "000040000"
  FCC  "100035960"
  FCC  "007380000"
  FCC  "040000000"
  FCC  "059700600"
; ----------------- grille 13
  FCC  "003009060"
  FCC  "708000409"
  FCC  "500000200"
  FCC  "001200000"
  FCC  "000805000"
  FCC  "000006100"
  FCC  "005000004"
  FCC  "804000307"
  FCC  "020500900"
; ----------------- grille 14
  FCC  "000780000"
  FCC  "070000200"
  FCC  "010500497"
  FCC  "800012500"
  FCC  "500000006"
  FCC  "006350004"
  FCC  "432005060"
  FCC  "001000050"
  FCC  "000039000"
; ----------------- grille 15
  FCC  "500007000"
  FCC  "000008703"
  FCC  "370010002"
  FCC  "200000500"
  FCC  "005362400"
  FCC  "001000008"
  FCC  "600090045"
  FCC  "104500000"
  FCC  "000200009"
; ----------------- grille 16
  FCC  "000050600"
  FCC  "103000700"
  FCC  "450300000"
  FCC  "020005060"
  FCC  "049020180"
  FCC  "030100090"
  FCC  "000008016"
  FCC  "005000903"
  FCC  "006030000"
; ----------------- fin des grilles
  FCB  $00

;------------------------------------------------------
; Initialisation ecran
;------------------------------------------------------
ECRAN
  FCB   $0C            ; effacement ecran   
  FCB   $1B,$20,$40    ; couleur noire
  FCB   $1B,$20,$57    ; fond blanc
  FCB   $1B,$67        ; bordure blanche
  FCB   $1B,$46        ; ecriture cyan
  FCB   $1F,$58,$43    ; locate 3,24
  FCC   "D"
  FDB   $1642          ; accent aigu  
  FCC   "eplacement avec les quatre fl"
  FDB   $1641          ; accent grave  
  FCC   "eches"
  FCB   $1F,$47,$59    ; locate 25,4
  FCC   "1-9:" 
  FCB   $1F,$48,$59    ; locate 25,5
  FCC   "Place le chiffre" 
  FCB   $1F,$4A,$59    ; locate 25,7
  FCC   "Espace:" 
  FCB   $1F,$4B,$59    ; locate 25,8
  FCC   "Efface la case" 
  FCB   $1F,$4D,$59    ; locate 25,10
  FCC   "Entr" 
  FDB   $1642          ; accent aigu  
  FCC   "ee:" 
  FCB   $1F,$4E,$59    ; locate 25,11
  FCC   "Contr" 
  FDB   $1643          ; accent circonflexe  
  FCC   "ole grille" 
  FCB   $1F,$50,$59    ; locate 25,13
  FCC   "STOP:" 
  FCB   $1F,$51,$59    ; locate 25,14
  FCC   "Grille suivante" 
  FCB   $1F,$53,$59    ; locate 25,16
  FCC   "RAZ:" 
  FCB   $1F,$54,$59    ; locate 25,17
  FCC   "Sort et sauve" 
  FCB   $1B,$40,$00    ; ecriture noire 
  
;------------------------------------------------------
; Libelles pour affichage
;------------------------------------------------------
GRILIB
  FCB   $1F,$56,$59    ; locate 24,20
  FCB   $1B,$53        ; fond jaune 
  FCC   "Grille "
GRINUM 
  FDB   $3030          ; numero de grille
  FCB   $1B,$57        ; fond blanc 
  FCB   $00 
GRIOK    
  FCB   $1F,$56,$63    ; locate 33,20
  FCB   $1B,$52        ; fond vert 
  FCC   " OK "           ; "OK"
  FCB   $1B,$57        ; fond blanc 
  FCB   $00            ; fin de chaine
GRIERR    
  FCB   $1F,$56,$63    ; locate 33,20
  FCB   $1B,$51        ; fond rouge 
  FCC   " ERR "          ; "ERR"
  FCB   $1B,$57        ; fond blanc 
  FCB   $00            ; fin de chaine
GRIEFF    
  FCB   $1F,$56,$63    ; locate 33,20
  FCB   $1B,$57        ; fond blanc 
  FCC   "     "          ; "   "
  FCB   $00            ; fin de chaine
  
;------------------------------------------------------
; Zones de travail
;------------------------------------------------------
MOTO
  FCB   $00            ; type d'ordinateur 0=MO,1=TO
BUZZMO
  FDB  $01FE           ; masques pour actionner le buzzer MO   
BUZZTO
  FDB  $08F7           ; masques pour actionner le buzzer TO
VRAM0
  FDB   $4000          ; adresse debut memoire video TO
ROUGE
  FDB   $CFCF          ; couleur rouge/blanc TO 
NOIR
  FDB   $C7C7          ; couleur noir/blanc TO 
CURPOS
  FCB  $00             ; position curseur (numero de la case 0-80)
CURDIR
  FCB  $00             ; direction curseur (0=horizontal, 1=vertical)
CURSM0 
  FCB  $F0             ; masque affichage curseur colonne paire
CURSM1 
  FCB  $0F             ; masque affichage curseur colonne impaire
CURSM2 
  FCB  $00             ; masque effacement curseur
GRIADDR  
  FDB  $0000           ; adresse grille courante
COMPTEUR 
  FCB  $00,$00,$00,$00,$00,$00,$00,$00,$00,$00  ; 10 compteurs de chiffres
MAXA 
  FCB  $00             ; limite pour le controle ligne, colonne, carre   
  END
Daniel
L'obstacle augmente mon ardeur.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par __sam__ »

Oui oui l'optim n'est pas très utile ici, c'était une prétexte pour faire joujou avec les hyperliens sur du code asm :)

Par contre en redémarrant l'émulateur ce matin tout va bien même en SDDrive... j'ai du être passé dans une réalité alternative hier soir (les histoires de mises à jour windows qui viennent même hanter le coté thomson, va savoir :? )
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
CMO5
Messages : 39
Inscription : 25 janv. 2021 09:20

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par CMO5 »

Hello,
Merci pour le programme. ;)
Daniel a écrit : 10 juil. 2021 22:03 Dans l'état actuel il n'y a que 16 grilles différentes intégrées au programme, mais il est prévu dans une prochaine version de stocker les grilles dans des fichiers annexes pouvant contenir un nombre de grilles non limité.
sudoku_moto.zip
Peut être une astuce : si on ne cherche à respecter que les règles de base (ligne et colonne), alors théoriquement une permutation de ligne ou de colonne dans le même groupement de carrés (cad en restant dans la même zone (1-3 ou 4-6 ou 7-9) donne une grille toujours valide. Donc à partir d'une seule grille; on peut en obtenir des tonnes par plusieurs permutations ligne/colonne d'affilée.
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par Daniel »

La nouvelle version ne stocke plus les grilles dans le programme, mais dans des fichiers séparés.
Le fichier GRILLV.BIN contient 16 grilles à compéter. On peut le remplacer par un fichier personnel, contenant au maximum 99 grilles.
La structure du fichier GRILLV.BIN est décrite dans le fichier sudoku.txt. Un exemple est donné.

Les grilles complètes ou en cours de résolution peuvent être sauvées dans les fichiers GRILLMO.BIN (avec un MO) et GRILLTO.BIN (avec un TO).
Ces fichiers ne sont pas interchangeables car ils sont chargés à des adresses différentes.

Normalement le fichier .sd doit fonctionner avec tous les contrôleurs de cartes SD sur tous les Thomson 8 bits (sauf TO9).
Si vous avez un TO9, ou si vous n'avez pas de contrôleur de carte SD, vous pouvez convertir le .sd en .fd et créer une disquette 3"1/2.

N'hésitez pas à apporter des suggestions dans le forum...
sudoku_moto.zip
(28.44 Kio) Téléchargé 80 fois

Code : Tout sélectionner

=========================================
SUDOKU pour MO et TO
(c) dcsoft - juillet 2021
=========================================

Le programme SUDOKU vous permet de résoudre
des problèmes de SUDOKU, de contrôler la
validité des chiffres ajoutés et de sauver
les grilles en cours de résolution.

La disquette contient 16 grilles vierges
à compléter, dans le fichier GRILLV.BIN.
Il est possible de charger ses propres
grilles en remplaçant ce fichier.

Les grilles partiellement ou totalement
complétées peuvent être sauvegardées dans
le fichier GRILLMO.BIN (pour les MO) ou
GRILLTO.BIN (pour les TO). Ces fichiers
peuvent être chargés à la demande.
Notez que les grilles MO ne peuvent pas
être chargées sur TO et réciproquement.

Le fichier GRILLV.BIN est constitué d'
une chaîne de 81 caractères pour chaque
grille. La chaîne décrit la grille ligne
par ligne, de gauche à droite et de haut
en bas. Les case vides sont représentées
par un 0, les cases renseignées par un
chiffre de 1 à 9.

Les chaînes de plusieurs grilles sont
mises à la suite, sans aucun séparateur.
Il y a au maximum 99 grilles dans un
fichier. La dernière grille est suivie
d'un zéro binaire.

Pour mettre ce fichier dans la disquette
il faut le faire précéder du bloc de
début de fichier Thomson :
En hexadécimal : 00 xx XX 00 00
(xx xx = longueur du fichier en octets)
Et il faut le faire suivre du bloc de
fin de fichier :
En hexadécimal : FF 00 00 00 00

Pour des précisions supplémentaires, vous
pouvez poser toutes les questions dans le
forum https://forum.system-cfg.com
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
fxrobin
Messages : 102
Inscription : 07 mars 2019 13:51
Localisation : RENNES
Contact :

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par fxrobin »

__sam__ a écrit : 11 juil. 2021 00:00 Une question: pourquoi CMPB #0 et pas TSTB en $91E2 ?
J'adore, j'suis un gros fan de toi Samuel :D

Daniel, super ton jeu, très instructif aussi sur diverses techniques de prog MO-TO. Merci
Fan d'ATARI 2600, de THOMSON MO5-TO8 et d'ATARI ST
Mes articles : https://www.fxjavadevblog.fr/retro-programming/
Membre du groupe wide-dot.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par __sam__ »

__sam__ a écrit : 11 juil. 2021 00:00 Je serais plus du genre à écrire un programme qui le résout pour moi :)
Et hop!
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
Daniel
Messages : 17316
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par Daniel »

Merci, mais je n'ai pas réussi à le compiler pour le MO5 :lol:
Par contre c'est bon dans Windows 10 avec un interpréteur LUA 8)

J'avais déjà un programme de résolution, j'ai écrit aussi un programme de génération de grilles au hasard, ce que je cherche maintenant est un programme pour générer les problèmes.

C'est compliqué : il faut que la solution soit unique (c'est facile à vérifier), mais il faut surtout que le problème ne soit ni trop simple ni trop difficile. C'est ce critère de difficulté que je ne sais pas bien évaluer.

fxrobin a écrit : 11 juil. 2021 22:45 très instructif aussi sur diverses techniques de prog MO-TO.
Attention, en matière de programmation je ne suis pas un modèle. Il vaut mieux faire confiance à préhisto ou à __sam__ :wink:
J'ai voulu tester l'assembleur LWASM (recommandé par Bentoc). Comme je ne suis pas très fana de jeux d'action j'ai choisi de faire un programme de Sudoku, car il n'y en avait pas pour Thomson. La logique est simple, la vitesse n'est pas critique, je n'ai fait aucune optimisation, le programme est resté à l'état brut. Il est très largement perfectible.

LWASM est très bien. Avant j'utilisais A09, il ne signalait pas toujours les possibilités de remplacer un déplacement long par un déplacement court. LWASM, avec les bonnes options, les détecte toutes.
Daniel
L'obstacle augmente mon ardeur.
Avatar de l’utilisateur
fxrobin
Messages : 102
Inscription : 07 mars 2019 13:51
Localisation : RENNES
Contact :

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par fxrobin »

J'aime bien quand même découvrir les différentes subtilités pour faire du code compatible MO/TO, entre autre.
Par exemple le code d'initialisation qui remplace le code WCHAR par défaut. le JMP qui se transforme en SWI, c'est TOP comme tactique.
Vous (les dévs THOMSON MO/TO) vous devez connaitre ce genre de trucs depuis des années, mais moi je découvre :-)

@Sam || @Prehisto : vous avez un endroit où vous partagez auprès de la plèbe (en l’occurrence des gars comme moi) votre immense savoir ?
Fan d'ATARI 2600, de THOMSON MO5-TO8 et d'ATARI ST
Mes articles : https://www.fxjavadevblog.fr/retro-programming/
Membre du groupe wide-dot.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par __sam__ »

Pour ma part je privilégie plutôt le forum de logicielsmoto pour tout ce qui est logiciel. Le dernier exemple en date est ce qui m'a conduit à faire l'outil d'étude de trace.

@Daniel: oui le solveur c'est du lua, langage que je trouve sympa pour maquetter. Mais maintenant que j'ai trouvé un algo, que j'ai pu déterminer quelle stratégie pour jouer est la mieux (rapide, simple).. bah une version 6809e n'est pas exclue. Il faut juste "un peu de pile" car l'algo de recherche a besoin d'une profondeur identique au nombre de cases vides. Si je compte correctement, l'espace d'état à chaque étape peut être réduit à 5 octets:
  • un pour connaitre sur laquelle des 81 cases on travaille
  • deux pour connaitre le masque des choix possibles (il faut 9 bits ==> donc deux octets)
  • deux pour l'adresse de retour (mais ca je crois qu'on peut s'en passer)
Soit au pire avec une grille vide même pas 1/2ko octets de pile (81*5 pour être précis). La seule inconnue est la vitesse de résolution. Sur les exemples qui ont autour de 25 indices (cases non vides) la résolution est de l'ordre de 10ms en interprété, et 10 fois moins avec le LuaJIT. Le plus difficile est l'exemple 17 que j'ai ajouté car il n'a que 17 indices. En interprété il lui faut 2 minutes (et 4ms avec le JIT.. décidément le JIT c'est quelque chose.) Ca sera un petit challenge de voir le 6809 résoudre des sudoku parmi les plus difficiles.
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 : 3469
Inscription : 29 nov. 2017 10:23

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par hlide »

Juste une remarque, quand je joue au Sudoku :

- je repère en premier la ligne, la colonne ou le carré où il n'y a qu'une case vide qui me donne la solution immédiate.
- ensuite à deux cases vides où j'ai une chance sur deux de me tromper.
- ensuite à trois cases vides où j'ai une chance sur trois de me tromper.
- et ainsi de suite.

En règle générale, le fait de remplir une case va réduire les possibilités de solution sur d'autres cases. L'idée étant de réduire au maximum les possibilités via cet enchainement.

Donc je ne sais pas si vous le faites dans l'algorithme qui recherche les solutions mais ce serait sans doute pas idiot de choisir la case vide à résoudre en traitant en priorité celles qui présentent le moins de possibilités pour éviter de faire de si tôt des récursions qui n'aboutiraient pas.

J'imagine que la difficulté pourrait être évaluée par les multiples choix. Si on applique la priorité par ordre de croissance des possibilités, on obtient un arbre dont la branche désigne un enchainement à une seule possibilité et le nombre de départ de branches en fonction du nombre de possibilités. L'arbre commencera avec un nombre de branches réduits et avec un peu de chance il en sera de même pour les suivantes. De plus, si on a qu'un seul chemin qui donne une résolution totale on saura alors que la solution est bien unique. La densité pourrait donner une idée de la difficulté. Le nombre de feuilles qui ne sont pas des solutions par exemple ou le nombre de séparation de branche par niveau ? etc.
Avatar de l’utilisateur
hlide
Messages : 3469
Inscription : 29 nov. 2017 10:23

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par hlide »

En testant plusieurs bases de données représentant des milliers de grilles, les auteurs de l'étude ont conclu que le meilleur indicateur de la difficulté d'un sudoku était précisément le temps que l'algorithme mettait à sortir de ce chaos. Plus il s'en dépêtrait vite, plus la grille était simple. Plus il vasouillait, plus la grille était difficile.
l'échelle ERT est une échelle logarithmique. Entre 0 et 1, on y trouve les grilles faciles, entre 1 et 2 les grilles moyennes, entre 2 et 3 les difficiles et au-delà de 3, les plus compliquées. Pour le moment, tout comme on n'a pas encore enregistré de séisme avec une magnitude de 10 sur l'échelle de Richter, il n'a pas été trouvé de grille atteignant la note de 4.
https://www.lemonde.fr/passeurdescience ... 70970.html

Il y aussi une technique qui m'arrivait d'appliquer (je ne connais pas son nom) :

J'ai le carré 1 qui ne peut contenir 1 que sur la ligne 1 et les colonnes 1 ou 2 (pas important de savoir à quelle place est le 1) parce que :
- le carré 3 qui contient un 1 en ligne 2,
- le carré 7 qui contient un 1 en colonne 3,
- le carré 1 qui contient deux nombres autres que le 1 en colonne 1 et 2 en ligne 3

Donc je sais que le 1 ne peut être que dans le carré 1 et non dans les cases vides de la même ligne des carrés 2 et 3 : on réduit par cette technique le nombre de possibilités dans ces cases vide.
En ce qui concerne Le Sudoku, les règles de classification suivantes ont été adoptées :
• facile : la déduction de chaque chiffre est directe ; aucune technique avancée n'est nécessaire
• moyen : soit la déduction est directe, soit il faut utiliser la technique du ...
• difficile : il faut utiliser la technique du ... ou la technique du ...
• expert : c'est seulement à l'aide de la technique du ... que vous pourrez résoudre cette catégorie de puzzles
Bref, si les techniques commencent à mettre leur bout de nez pour classifier la difficulté, on n'est pas sorti de l'auberge.
__sam__
Messages : 7923
Inscription : 18 sept. 2010 12:08
Localisation : Brest et parfois les Flandres

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par __sam__ »

hlide a écrit : 12 juil. 2021 17:16 Donc je ne sais pas si vous le faites dans l'algorithme qui recherche les solutions mais ce serait sans doute pas idiot de choisir la case vide à résoudre en traitant en priorité celles qui présentent le moins de possibilités pour éviter de faire de si tôt des récursions qui n'aboutiraient pas.
C'est ce que je fais (algo no 1).

Par contre la recherche de la case ayant le moins de possibilités est une opération couteuse (on doit chercher les possibilités pour chacune des cases libres à chaque étape.) Aussi j'ai essayé d'autre algos: s'arrêter à la premiere case non remplie (no 2). Enfin l'algo no 3: Avoir une estimation de la case ayant le moins de possibilités en prenant celle qui a le plus de cases fixes dans sa ligne, sa colonne et son "groupe de 9" (le nombre de fixe dans ces colonnes/ligne/groupe est précalculé et stocké dans un tableau et n'a pas besoin d'être calculé pour chaque case libre). J'aurais pu essayer aussi l'algo de tirer au pif la case libre à essayer... ou des algos bien plus savants (j'y suis allé à l'inspiration.)

Cela dit, les machines actuelles sont si rapides que ces algos terminent tous en un clin d'oeil et le simple fait de bouger la souris fait énormément varier le timing. Le second est généralement le plus lent des trois et le premier le plus rapide. Je ne comprends pas bien pourquoi car la recherche du minimum sans heuristique (raccourcis) me semble être une opération couteuse. Mais peut-être que, toujours sur les machines actuelles, l'heuristique de l'algo no3 qui utilise des tableaux est finalement trop couteux (les accès mémoire sont plus lents que du calcul pur-cpu). Ou alors l'heuristique ne donne pas un choix pas toujours vraiment super pertinent. En effet, c'est pas parce qu'on a plein de valeurs fixées en ligne et en colonne qu'on réduit notre choix (cas lorsque ces chiffres se recouvrent majoritairement au lieu de couvrir le plus de valeurs distinctes).
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 : 3469
Inscription : 29 nov. 2017 10:23

Re: [Thomson] SUDOKU, nouveau jeu pour MO et TO

Message par hlide »

Il y a de la technique... https://sudoku.megastar.fr/techniques/

__sam__, tes algorithmes sont en mesure de résoudre les Sudoku de difficulté "expert" ?
Répondre