Logicielsmoto.com

Nous sommes le 28 Mar 2024, 12:25

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 21 messages ]  Aller à la page 1, 2  Suivante
Auteur Message
MessagePosté: 11 Fév 2022, 16:06 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Bonjour à tous,
j'oriente ma question à SAM, mais ceux qui savent peuvent aussi me donner des éléments.

J'ai réussi à faire mon propre bootloader qui s'écrit dans le bootsector en m'inspirant du code de Sam que j'ai trouvé sur le forum.
Pour mémoire voici le code de SAM :

Code:
        setdp   $60

        org     $6200

init    lda     #$2
        sta     <$6048
        sta     <$604C
        ldd     $001E
        std     ,s      ! retour basic
        ldd     #$6300  ! addr. charg.
        std     <$604F
        jsr     $E82A   ! load secteur
        stb     <$6080  ! clear sema.
        bcs     exit    ! erreur?
        inc       <$604F  ! 256 oct. suivant
        inc       <$604C   ! secteur suivant
        jsr     $E82A   ! load secteur
        stb     <$6080  ! clear sema.
        bcs     exit    ! erreur?
        jmp     $6300   ! sinon jsr
exit    rts


Voici mon code

Code:
*****************************************************
* BOOTLOADER
*
* Charge N secteurs à partir du secteur 2 de la première
* piste du lecteur en cours à une adresse d'implantation
* définie par l'equate TARGET_ADDR.
*
* Voir les equates pour les paramètres.
*
* Auteur: F.X. Robin, fév. 2022
* Inspiré par "bootbloc" de Samuel Devulder Mars 2012
*****************************************************

** EQUATES PARAMETRES **
START_SECTOR    EQU $02
NB_READ_SECTORS EQU $02
TARGET_ADDR     EQU $6300

** EQUATES ROUTINES et REGISTRES **
DKCO                   EQU $E82A
REG_TARGET_ADDR        EQU $604F
REG_DISKOP             EQU $6048
REG_SECTOR             EQU $604C
DISKOP_SECT_READ       EQU $02
*****************************************************

        ORG     $6200
        SETDP   $60

BEGIN   
        LDA #$60
        TFR A,DP

        LDX     $001E
        STX     ,S                      * retour au BASIC à la fin avec RTS

        LDX     #TARGET_ADDR            * addresse d'implantation des données
        STX     <REG_TARGET_ADDR

        LDA     #DISKOP_SECT_READ       * opération de lecture       
        STA     <REG_DISKOP

        LDB     #START_SECTOR
        STB     <REG_SECTOR
        LDA     #NB_READ_SECTORS
READ_SECTOR_LOOP               
        JSR     DKCO                    * charge le secteur
        BCS     END                     * test le carry flag si une erreur est survenue, si oui, on quitte
        INC     <REG_TARGET_ADDR        * 256 bytes suivants pour l'adresse du buffer. On incrémente l'octet de poids fort de l'adresse 6300 devient 6400, etc.
        INC     <REG_SECTOR             * incrémentation du secteur lu
        DECA
        BNE     READ_SECTOR_LOOP        * on boucle si on a pas tout lu   
        JMP     TARGET_ADDR             * tout est chargé, on jump à l'adresse d'implantation
END     RTS


J'ai donc plusieurs questions :

1 - dans le code de SAM (et le mien parce que j'ai recopié honteusement), il y a un
Code:
ldd     $001E
suivi de
Code:
std     ,s
avec le commentaire "retour BASIC". Je comprends pas trop $001E. c'est pas l'espace cartouche ?

2- si jamais j'appelle PUTC dans mon bootloader (ce qui n'est pas le cas ici) pour afficher une chaîne de caractères, ça fout un sacré bordel (et ça plante) alors que la même routine appelée dans mon programme qui a été logé en $6300 fonctionne sans problème. Je comprends pas pourquoi. On dirait que les routines du moniteur (PUTC) vont mettre le brin en $6200 et +. Ça me change des OPCODEs quand je DEBUG avec DCMOTO.

3- SAM a utilisé $6080 "Sémaphore de présence du contrôleur de disque" pour y placer B c'est à dire quoi ? et pourquoi ? (l'octet de poids faible de D ? donc 00 ?). J'ai retiré ce point, et mon Bootloader fonctionne quand même mais j'aimerais comprendre pourquoi SAM le fait. (ça ne doit pas être pour les beaux yeux de la princesse ...)

Merci à vous

Pour info, voici ce que ça fait quand ça s'exécute :-)

phpBB [video]

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 11 Fév 2022, 20:04 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
1) Oui c’est l’espace cartouche. L’adresse contient le pointeur du boot pour toutes les cartouches thomson, en particulier le boot du basic si l’espace cartouche le contient. Le code recopie donc l’adresse du boot de la cartouche en lieu et place de l’adresse de retour d’origine empilée par la ROM. Et donc un simple RTS démarrera la cartouche en place (typiquement le basic). On aurait pu faire un JMP [$001E] directement au lieu de cette recopie + RTS.

2) oui le bootblock est démarré avant l’init écran du moniteur. Tu peux toi même appeler cette initialisation avec un JSR $E800 dans ton bootcode avant le 1er appel à PUTC si j’ai bonne mémoire.

3) je n’ai plus de souvenir précis, mais il me semble que cela nettoie le code d’erreur que les routines D7 sont susceptibles de renseigner lors d’un retour avec CC=1. Il faudrait vérifier dans le manuel techniques des to8/to9/to9+. Je pense que ça marche chez toi par ce que justement il n’y a pas eu d’erreur de lecture de D7.

4) pour la video ça devrait aussi fonctionner si tu click sur 1 ou 2 (les différents basic quoi).

(J’espère n’avoir pas dit trop de bêtises, je suis loin de tout ordi et ne peux vérifier les docs et c’est un code que j’ai moi-même probablement piqué à Prehisto)

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 11 Fév 2022, 21:42 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Merci beaucoup Sam.

Il y a quand même un truc que je pige pas sur le coup du PUTC.
Effectivement si c'est dans mon bootloader, le comportement est chaotique surtout avec les codes spécifiques d'échappement, et ça plante.

Mais le même code, en 6300, appelé par le bootloader fonctionne, alors que l'initialisation du moniteur n'est pas plus passé qu'avant puisque le prog est appelé à la fin du bootloader par un JMP.

Merci encore.

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 12 Fév 2022, 00:31 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
De mémoire l’appel en $E800 positionne les pointeurs de début et fin écran en page 0 du moniteur. Donc si on ne fait pas cet appel, le moniteur récupère un peu n’importe quoi comme pointeur écran et va écrire en mémoire au hasard. De là à ce que ca trash en $6200, il n’y a qu’un pas je suppose.

Pour en avoir le cœur net, un passage au debugger pas à pas, ou l’usage des trace si l’emulateur le permet, peut aider à mieux comprendre le phénomène.

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 12 Fév 2022, 17:57 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Bon, après quelques essais, ce qui est sûr c'est que PUTC va mettre le brin en $6200+ et ce, même si j'appelle l'init du moniteur en $E800 avant.
Impossible de mettre un PUTC (en boucle pour afficher une chaîne de caractères) sans que les OPCODEs ne soient changés.
Le même programme, implanté et lancé en 6300 n'est pas perturbé par PUTC et donctionne comme il se doit.

Je ferai une séance de DEBUGGER plus tard pour voir quels instructions de PUTC viennent écrire en $6200+

Merci pour ton aide Sam !
PS : toutes les infos engrangées dans le cadre de ce petit test de bootloader + bootsector "finiront" dans un article sur mon blog, histoire d'avoir de la doc sur ce truc où j'en ai trouvé aucune à part chercher sur ce forum.

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 12 Fév 2022, 20:29 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Bon ca veut dire que mémoire fait défaut. Il faudrait que je mattes le code de la demo "rockfort" de 2014 pour trouver les autres trucs du moniteur pour avoir un PUTC fonctionnel dans le code du bootblock. Si seulement j’avais tout sous github....

[Edit] non zut rockfort c'est du LOADM. Ça doit être ailleurs. Sensiblement a la même époque +/- 1 an.

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 15 Fév 2022, 16:16 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
J'ai mis les Strings à afficher dans la partie "data" du bootloader, après la checksum (à l'offset 128), visiblement c'est ça qui est tripoté.
Après c'est pas très grave j'ai contourné le problème en allant mettre le vrai prog en $6300 et le booloader ne fait que charger les secteurs nécessaires en $6300.

J'avais envie de tenter une "bootsector" demo, mais si je n'ai plus que 119 bytes et sans PUTC, ça va pas être simple :-) (pour une démo bootsector console)

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 15 Fév 2022, 16:33 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Regardes la diskette TOale (viewtopic.php?f=10&t=446)
https://www.pouet.net/prod.php?which=59046

Et tiens, dans le code asm (dans le fil du 1er lien), il y a la routine d’init du PUTC que je cherchais plus haut. Donc c’est un saut en $E800 suivi d’un PUTC du caractère #12 (form feed? ). Après cela PUTC marche comme il faut. Pour les modifs en $6200, le me demande si c’est après $6280 et lié au calcul du checksum sans rapport avec le putc.

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 16 Fév 2022, 11:31 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Le calcul de la checksum est fait par un programme en Java que voici.

Code:
package fr.fxjavadevblog.to8bs;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;

import lombok.extern.slf4j.Slf4j;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

@Command(name = "bootsectorbuilder", description = "build a bootsector for TO8")
@Slf4j
public class MainCommand implements Runnable
{
   
   protected static final byte[] SIGNATURE = { 0x42, 0x41, 0x53, 0x49, 0x43, 0x32 }; // signature : "BASIC2"
   protected static final byte SIGNATURE_CHECK_SUM = 0x6C; // precalculated signature checksum
   protected static final byte CHECK_SUM_INIT_VALUE = 0x55;

   @Option(names = { "-b", "--boot-bin-raw" }, paramLabel = "Boot BIN RAW compiled File", description = "the RAW code file of the bootsector. The code will be place between index 0 and 118 included")
   File bootFile;

   @Option(names = { "-o", "--output-fd" }, paramLabel = "Destination File", description = "Destination file in .fd format to use in emulators or to write on a floppy disk")
   File destFile;
   
   @Option(names = { "-d", "--data-file"}, paramLabel = "RAW Data File", description = "Data file. These raw data will be placed at index 128 of the bootsector, after the checksum")
   File dataFile;
   
   @Option(names = { "-p", "--prog-raw-file"}, paramLabel = "Prog RAW File", description = "The Prog RAW File is an extended prog, which must be called by the bootsector. The prog RAW file is placed right after the sector 1")
   File progFile;

   public static void main(String[] args)
   {
      CommandLine cmdLine = new CommandLine(new MainCommand());
      cmdLine.execute(args);
   }

   @Override
   public void run()
   {
      log.info("Building a TO8 bootsector");
      log.info("Converting {} into {}", bootFile, destFile);
      log.info("bootFile : {}", bootFile == null ? "no code into bootsector" : bootFile);
      log.info("progFile : {}", progFile == null ? "no extended prog" : progFile);
      log.info("dataFile : {}", dataFile == null ? "no data to insert in bootsector" : dataFile);

      byte[] finalDisk  = new byte[ 2 * 80 * 16 * 256]; // 640 Ko, 1 disquette double-face
      Arrays.fill(finalDisk, (byte) 0x00);
      
      byte[] bootSector = initBootSector();   
      log.info("Signature data : {}", hexa(SIGNATURE));
      log.info("Signature checksum : 0x{}", hexa(SIGNATURE_CHECK_SUM));

      try
      {
         byte[] sourceBinData = loadBootSectorRawCode();      
         byte checkSum = (byte) (CHECK_SUM_INIT_VALUE + SIGNATURE_CHECK_SUM);
         checkSum = insertBin(bootSector, checkSum, sourceBinData);
         insertSignature(bootSector, SIGNATURE);
         insertChecksum(bootSector, checkSum);   
         if (dataFile != null) insert(dataFile, bootSector,128);
         copyBootSectorOnDisk(finalDisk, bootSector);
         if (progFile != null) insert(progFile, finalDisk,256);   
         writeDisk(finalDisk);
         log.info("DISK written : {} ", destFile);
      }
      catch (IOException e)
      {
         log.error(e.getMessage());
      }

   }



   private void insert(File file, byte[] dest, int insertAt) throws IOException
   {
      byte[] sourceData = Files.readAllBytes(file.toPath());
      log.info("Insert {} bytes from {} into buffer at index 0x{}", sourceData.length, file, hexa((byte)insertAt));
      arraySetData(sourceData, dest, insertAt);   
   }
   
   private void arraySetData(byte[] source, byte[] dest, int startingAt)
   {
      System.arraycopy(source, 0, dest, startingAt, source.length);
   }
   
   
   private void copyBootSectorOnDisk(byte[] disk, byte[] bootsector)
   {
      arraySetData(bootsector, disk, 0);
   }

   private void writeDisk(byte[] bootSector) throws IOException
   {
      Files.write(destFile.toPath(), bootSector, StandardOpenOption.CREATE);
   }

   private byte[] loadBootSectorRawCode() throws IOException
   {
      byte[] sourceBinData = Files.readAllBytes(bootFile.toPath());
      log.info("Bootsector code length : {} bytes", sourceBinData.length);
      return sourceBinData;
   }

   private byte[] initBootSector()
   {
      byte[] bootSector = new byte[256];
      Arrays.fill(bootSector, (byte) 0x00);
      return bootSector;
   }

   private void insertChecksum(byte[] bootSector, byte checkSum)
   {
      bootSector[127] = checkSum;
      log.info("Checksum : 0x{}", hexa(checkSum));
   }

   private void insertSignature(byte[] bootSector, byte[] signature)
   {
      // placement de la signature à partir de l'octet 120 jusqu'à 125 inclus
      arraySetData(signature, bootSector, 120);
   }

   private byte insertBin(byte[] bootSector, byte checkSum, byte[] sourceBinData)
   {
      int sourceIndex = 0;

      
      for (int i = 0; i < bootSector.length; i++)
      {
         byte finalByte = 0x00;

         if (i < 120 && sourceIndex < sourceBinData.length)
         {
            // placement du programme de 0 à 119 : avec complément à 2
            byte data = sourceBinData[sourceIndex++];
            checkSum += data; // la checkSum est calculée sur l'octet réel et non pas sur le complément à deux.
            finalByte = twosComplement(data); // complément à 2
            log.info("at {} : {} transformed into {}", hexa((byte) i), hexa(data), hexa(finalByte));

         }
         else if (i > 127 && sourceIndex < sourceBinData.length)
         {
            finalByte = sourceBinData[sourceIndex++];
            // pas de checkSum à calculer sur cette partie, ni de transformation en complément à deux.
         }

         bootSector[i] = finalByte;
      }
      return checkSum;
   }

   private byte twosComplement(byte b)
   {
      return (byte) (256 - b);
   }

   private String hexa(byte value)
   {
      return String.format("%02X", value);
   }

   private String hexa(byte[] values)
   {
      StringBuilder sb = new StringBuilder();
      for (byte b : values)
      {
         sb.append(hexa(b)).append(" ");
      }
      return sb.toString().trim();
   }

}


Ça fonctionne bien pour le code "bootloader.asm" sans problème, mais c'est vrai que je ne "colle" rien derrière la checksum dans ce cas.

Par exemple, le code qui ne fonctionne pas :

Code:
*************************************************************
* EQUATES
*************************************************************
GETCH        EQU $E806     * routine getchar
KEY_ENTER    EQU $0D      * touche entrée
PUTC         EQU $E803    * routine PUTC
SET_PALETTE   EQU $EC00   * routine setpalette
PALETTE_SEL   EQU $E7DB   * selecteur de palette
PALETTE_REG   EQU $E7DA   * registre lecture/écriture palette
*************************************************************

    ORG $6200
   
DEBUT
    PSHS Y,X,A
   
    * full black avant de changer de résolution
    JSR $E800              * init du moniteur
   

    * reglage palette couleur 1 sur CYAN (FF0)
    LDA #$01
    LDX #$FFF0
    LDY #$0FF0
    JSR SET_PALETTE

    * init graphique
    * LDX #INIT
    * BSR PRINT_STRING

    * affichage du texte
    LDX #$6280     * les datas se situent en 6280, c'est à dire à l'offet 128.
    BSR PRINT_STRING

    * attente clavier
    BSR KEY_ECHO

    PULS A,X,Y
FIN   
    RTS

* PALETTE FULL BLACK
PALETTE_BLACK   
    LDA #$10                * 16 couleurs
    CLR PALETTE_SEL         * on part de la couleur 0
PALETTE_BLACK_LOOP         
    CLR PALETTE_REG         * on y met du noir octet poids fort, l'adresse d'écriture de la palette s'auto-incrémente
    CLR PALETTE_REG         * on y met du noir octet poids faible, l'adresse d'écriture de la palette s'auto-incrémente
    DECA                    * place le bit d'égalité à 00 automatiquement, pas besoin de faire un CMPA #$00
    BNE PALETTE_BLACK_LOOP 
    RTS


********************************************************
* Routine : PRINT_STRING
* Affichage d'une chaine de caractères
* X contient l'adresse de la chaine, terminée par un $00
* Usage : LDX #STRING
*         BSR PRINT_STRING
********************************************************
PRINT_STRING
    PSHS B
PRINT_STRING_NEXT_CHAR   
    LDB ,X+
    BEQ PRINT_STRING_EXIT      * si B est égal à 0, on sort
    JSR PUTC
    CMPB #$0A       * si c'est retour chariot, on rajoute retour à la ligne.
    BNE PRINT_STRING_NEXT_CHAR
    LDB  #$0D
    JSR PUTC
    BRA PRINT_STRING_NEXT_CHAR
PRINT_STRING_EXIT   
    PULS B
    RTS
********************************************************   


********************************************************
* Routine : KEY_ECHO
* Affiche un curseur et toutes les touches saisie
* jusqu'à ce que le code KEY (equate) soit rencontré
* Usage : BSR KEY_ECHO
********************************************************
KEY_ECHO 
    PSHS B
LOOP_KEY_ECHO
    LDB #$7F    * curseur carré
    JSR PUTC   
    LDB #$08    * on revient un cran en arrière (pour l'écraser par la suite)
    JSR PUTC 
    JSR GETCH   * on attend une touche saisie B contient le caractère tapé
    CMPB #KEY_ENTER    * est-ce le caractère de sortie ?
    BEQ EXIT_LOOP_KEY_ECHO     
    JSR PUTC    * on l'affiche si ce n'était pas le caractère de sortie       
    BRA LOOP_KEY_ECHO
EXIT_LOOP_KEY_ECHO 
    PULS B
    RTS 
********************************************************


**************************************************************************************
* DATA
**************************************************************************************
INIT
    FCB $1B,$5B                  * passage en mode 80 colonnes. Oui PUTC peut faire ça
    FCB $1B,$41,$1B,$50,$1B,$60  * screen 1,0,0
    FCB $11,$0C,$00              * effacement du curseur, effacement de l'écran
**************************************************************************************   
    END   


ensuite je passe ce code compilé en RAW à mon générateur de bootsector écrit en JAVA.
Voici le log de mon programme

Code:
11:15:56.406 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - Building a TO8 bootsector
11:15:56.407 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - Converting /home/robin/tmp/bootprog-small.raw into /home/robin/tmp/disk-small.fd
11:15:56.407 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - bootFile : /home/robin/tmp/bootprog-small.raw
11:15:56.408 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - progFile : no extended prog
11:15:56.408 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - dataFile : /home/robin/tmp/data-txt.raw
11:15:56.413 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - Signature data : 42 41 53 49 43 32
11:15:56.414 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - Signature checksum : 0x6C
11:15:56.414 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - Bootsector code length : 103 bytes
11:15:56.415 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 00 : 34 transformed into CC
11:15:56.415 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 01 : 32 transformed into CE
11:15:56.415 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 02 : BD transformed into 43
11:15:56.415 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 03 : E8 transformed into 18
11:15:56.416 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 04 : 00 transformed into 00
11:15:56.416 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 05 : 86 transformed into 7A
11:15:56.416 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 06 : 01 transformed into FF
11:15:56.416 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 07 : 8E transformed into 72
11:15:56.416 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 08 : FF transformed into 01
11:15:56.416 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 09 : F0 transformed into 10
11:15:56.416 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 0A : 10 transformed into F0
11:15:56.417 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 0B : 8E transformed into 72
11:15:56.417 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 0C : 0F transformed into F1
11:15:56.417 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 0D : F0 transformed into 10
11:15:56.418 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 0E : BD transformed into 43
11:15:56.418 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 0F : EC transformed into 14
11:15:56.418 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 10 : 00 transformed into 00
11:15:56.419 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 11 : 8E transformed into 72
11:15:56.419 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 12 : 62 transformed into 9E
11:15:56.419 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 13 : 80 transformed into 80
11:15:56.419 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 14 : 8D transformed into 73
11:15:56.419 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 15 : 14 transformed into EC
11:15:56.420 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 16 : 8D transformed into 73
11:15:56.420 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 17 : 29 transformed into D7
11:15:56.420 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 18 : 35 transformed into CB
11:15:56.420 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 19 : 32 transformed into CE
11:15:56.420 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 1A : 39 transformed into C7
11:15:56.421 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 1B : 86 transformed into 7A
11:15:56.421 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 1C : 10 transformed into F0
11:15:56.421 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 1D : 7F transformed into 81
11:15:56.421 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 1E : E7 transformed into 19
11:15:56.421 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 1F : DB transformed into 25
11:15:56.422 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 20 : 7F transformed into 81
11:15:56.422 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 21 : E7 transformed into 19
11:15:56.422 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 22 : DA transformed into 26
11:15:56.422 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 23 : 7F transformed into 81
11:15:56.422 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 24 : E7 transformed into 19
11:15:56.422 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 25 : DA transformed into 26
11:15:56.423 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 26 : 4A transformed into B6
11:15:56.423 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 27 : 26 transformed into DA
11:15:56.423 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 28 : F7 transformed into 09
11:15:56.423 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 29 : 39 transformed into C7
11:15:56.423 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 2A : 34 transformed into CC
11:15:56.423 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 2B : 04 transformed into FC
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 2C : E6 transformed into 1A
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 2D : 80 transformed into 80
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 2E : 27 transformed into D9
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 2F : 0E transformed into F2
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 30 : BD transformed into 43
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 31 : E8 transformed into 18
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 32 : 03 transformed into FD
11:15:56.424 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 33 : C1 transformed into 3F
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 34 : 0A transformed into F6
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 35 : 26 transformed into DA
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 36 : F5 transformed into 0B
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 37 : C6 transformed into 3A
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 38 : 0D transformed into F3
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 39 : BD transformed into 43
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 3A : E8 transformed into 18
11:15:56.425 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 3B : 03 transformed into FD
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 3C : 20 transformed into E0
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 3D : EE transformed into 12
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 3E : 35 transformed into CB
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 3F : 04 transformed into FC
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 40 : 39 transformed into C7
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 41 : 34 transformed into CC
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 42 : 04 transformed into FC
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 43 : C6 transformed into 3A
11:15:56.426 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 44 : 7F transformed into 81
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 45 : BD transformed into 43
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 46 : E8 transformed into 18
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 47 : 03 transformed into FD
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 48 : C6 transformed into 3A
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 49 : 08 transformed into F8
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 4A : BD transformed into 43
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 4B : E8 transformed into 18
11:15:56.427 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 4C : 03 transformed into FD
11:15:56.428 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 4D : BD transformed into 43
11:15:56.428 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 4E : E8 transformed into 18
11:15:56.428 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 4F : 06 transformed into FA
11:15:56.428 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 50 : C1 transformed into 3F
11:15:56.428 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 51 : 0D transformed into F3
11:15:56.428 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 52 : 27 transformed into D9
11:15:56.428 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 53 : 05 transformed into FB
11:15:56.429 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 54 : BD transformed into 43
11:15:56.429 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 55 : E8 transformed into 18
11:15:56.429 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 56 : 03 transformed into FD
11:15:56.429 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 57 : 20 transformed into E0
11:15:56.429 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 58 : EA transformed into 16
11:15:56.429 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 59 : 35 transformed into CB
11:15:56.429 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 5A : 04 transformed into FC
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 5B : 39 transformed into C7
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 5C : 1B transformed into E5
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 5D : 5B transformed into A5
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 5E : 1B transformed into E5
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 5F : 41 transformed into BF
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 60 : 1B transformed into E5
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 61 : 50 transformed into B0
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 62 : 1B transformed into E5
11:15:56.430 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 63 : 60 transformed into A0
11:15:56.431 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 64 : 11 transformed into EF
11:15:56.431 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 65 : 0C transformed into F4
11:15:56.431 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - at 66 : 00 transformed into 00
11:15:56.431 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - Checksum : 0x09
11:15:56.431 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - Insert 128 bytes from /home/robin/tmp/data-txt.raw into buffer at index 0x80
11:15:56.432 [main] INFO fr.fxjavadevblog.to8bs.MainCommand - DISK written : /home/robin/tmp/disk-small.fd


ensuite, à l'offset 128, je colle les datas ASCII :

Code:
00000000 47 52 45 45 54 49 4e 47 53 20 50 52 4f 46 45 53   GREETINGS PROFES
00000010 53 4f 52 20 46 41 4c 4b 45 4e 0a 0a 3e 20 48 45   SOR FALKEN..> HE
00000020 4c 4c 4f 0a 0a 41 20 53 54 52 41 4e 47 45 20 47   LLO..A STRANGE G
00000030 41 4d 45 2e 0a 5a 48 45 20 4f 4e 4c 59 20 57 49   AME..ZHE ONLY WI
00000040 4e 4e 49 4e 47 20 4d 4f 56 45 20 49 53 0a 4e 4f   NNING MOVE IS.NO
00000050 54 20 54 4f 20 50 4c 41 59 2e 0a 0a 48 4f 57 20   T TO PLAY...HOW
00000060 41 42 4f 55 54 20 41 20 4e 49 43 45 20 47 41 4d   ABOUT A NICE GAM
00000070 45 20 4f 46 20 43 48 45 53 53 3f 0a 0a 3e 20 00   E OF CHESS?..> .


j'obtiens donc le bootsector suivant :

Code:
00000000  cc ce 43 18 00 7a ff 72  01 10 f0 72 f1 10 43 14  |..C..z.r...r..C.|
00000010  00 72 9e 80 73 ec 73 d7  cb ce c7 7a f0 81 19 25  |.r..s.s....z...%|
00000020  81 19 26 81 19 26 b6 da  09 c7 cc fc 1a 80 d9 f2  |..&..&..........|
00000030  43 18 fd 3f f6 da 0b 3a  f3 43 18 fd e0 12 cb fc  |C..?...:.C......|
00000040  c7 cc fc 3a 81 43 18 fd  3a f8 43 18 fd 43 18 fa  |...:.C..:.C..C..|
00000050  3f f3 d9 fb 43 18 fd e0  16 cb fc c7 e5 a5 e5 bf  |?...C...........|
00000060  e5 b0 e5 a0 ef f4 00 00  00 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 00 00 00 00  42 41 53 49 43 32 00 09  |........BASIC2..|
00000080  47 52 45 45 54 49 4e 47  53 20 50 52 4f 46 45 53  |GREETINGS PROFES|
00000090  53 4f 52 20 46 41 4c 4b  45 4e 0a 0a 3e 20 48 45  |SOR FALKEN..> HE|
000000a0  4c 4c 4f 0a 0a 41 20 53  54 52 41 4e 47 45 20 47  |LLO..A STRANGE G|
000000b0  41 4d 45 2e 0a 54 48 45  20 4f 4e 4c 59 20 57 49  |AME..THE ONLY WI|
000000c0  4e 4e 49 4e 47 20 4d 4f  56 45 20 49 53 0a 4e 4f  |NNING MOVE IS.NO|
000000d0  54 20 54 4f 20 50 4c 41  59 2e 0a 0a 48 4f 57 20  |T TO PLAY...HOW |
000000e0  41 42 4f 55 54 20 41 20  4e 49 43 45 20 47 41 4d  |ABOUT A NICE GAM|
000000f0  45 20 4f 46 20 43 48 45  53 53 3f 0a 0a 3e 20 00  |E OF CHESS?..> .|


Je vais essayer de rajouter l'appel à PUTC avec #12 et on verra.
Je te tiens au courant.

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Dernière édition par fxrobin le 17 Fév 2022, 15:31, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
MessagePosté: 17 Fév 2022, 10:54 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Bon et bien j'ai trouvé la raison.
Il y a une sous-routine du PUTC qui va regarder :
- le contenu du registre $601C, qui pointe sur $6200
- le contenu du registre $601E, qui pointe sur $6218
- qui boucle sur cette tranche d'adresse et qui met "$FF" sur les 18 octets.

pas de chance, c'est le code du Bootsector à cette endroit. PUTC fait donc "comme à la maison" il se prend la place sur la canapé, il se croit chez mamie.

Code:
* DP pointe sur $60

F095 LDX <$1C
F097 LDA #$FF
F099 STA ,X+
F09B CMPX <$1E
F09D BLS $F099


Pour info, c'est à l'init du TO8 de l'adresse $0065 à $ 006D que les registres $601C et $601E sont initialisés à la valeur $6200, non seulement à l'allumage, mais aussi lors du boot.

on y trouve :

Code:
0065 LDA #$62
0067 STA #601A
006A STA #601C
006D STA #601E


Pour l'instant je ne sais pas à quoi sert ce bout de routine qui initialise une zone mémoire à $FF, je suis tenté de mettre $6200 en $601E au tout début de mon programme de bootsecteur pour voir ce que ça fait, comme ça il ne bouclerait pas.

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 17 Fév 2022, 11:37 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Bon et bien mon petit "trick" fonctionne.

Code:
    LDX #$6200 * little trick
    STX $601E  * pour éviter l'écrasement du bootsector par PUTC, le méchant
   
    * init graphique
    LDX #INIT
    BSR PRINT_STRING  * cette routine appelle PUTC


Le code du bootsecteur fonctionne maintenant correctement.

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 17 Fév 2022, 15:18 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Donc, histoire d'avoir l'ensemble (pour la postérité) :

Code:
************************************************************************************************
* EQUATES
************************************************************************************************
GETCH        EQU $E806     * routine getchar
KEY_ENTER    EQU $0D      * touche entrée
PUTC         EQU $E803    * routine PUTC
SET_PALETTE   EQU $EC00   * routine setpalette
PALETTE_SEL   EQU $E7DB   * selecteur de palette
PALETTE_REG   EQU $E7DA   * registre lecture/écriture palette
MESSAGE       EQU $6280   * adresse du message text de Joshua. $6280, c'est à dire à l'offet 128
************************************************************************************************

** MACROS : DEBUT **********************************
PCHAR MACRO       * Affiche un caractère
    LDB \1
    JSR PUTC
    ENDM

PRINT MACRO       * Affiche une chaine de caractères
    LDX \1
    BSR PRINT_STRING
    ENDM
** MACROS : FIN ************************************   

    ORG $6200

DEBUT
    PSHS Y,X,A

    * PALETTE_BLACK : DEBUT   
    LDA #$20                * 16 couleurs, 2 octets par couleur
!   STA PALETTE_SEL         * debut de boucle
    CLR PALETTE_REG         * on y met du noir octet poids fort, l'adresse d'écriture de la palette s'auto-incrémente
    CLR PALETTE_REG         * on y met du noir octet poids faible, l'adresse d'écriture de la palette s'auto-incrémente
    DECA                    * on se decale de deux crans, car
    DECA                    * place le bit d'égalité à 00 automatiquement, pas besoin de faire un CMPA #$00
    BNE <                   * on boucle sur l'étiquette "!"
    * PALETTE_BLACK : FIN

    LDX #$6200 * little trick
    STX $601E  * pour éviter l'écrasement du bootsector par PUTC, le méchant
       
    * init graphique
    PRINT #INIT

    * reglage palette couleur 1 sur CYAN (FF0)
    LDA #$01
    LDX #$FFF0
    LDY #$0FF0
    JSR SET_PALETTE

    * affichage du texte
    PRINT #MESSAGE     

    * attente clavier
    BSR KEY_ECHO

    PULS A,X,Y
FIN   
    RTS

********************************************************
* Routine : PRINT_STRING
* Affichage d'une chaine de caractères
* X contient l'adresse de la chaine, terminée par un $00
* Usage : LDX #STRING
*         BSR PRINT_STRING
********************************************************
PRINT_STRING
    PSHU B 
!   LDB ,X+
    BEQ >      * si B est égal à 0, on sort
    JSR PUTC
    CMPB #$0A       * si c'est retour chariot, on rajoute retour à la ligne.
    BNE <
    PCHAR #$0D
    BRA <
!   PULU B
    RTS
********************************************************   


********************************************************
* Routine : KEY_ECHO
* Affiche un curseur et toutes les touches saisie
* jusqu'à ce que le code KEY (equate) soit rencontré
* Usage : BSR KEY_ECHO
********************************************************
KEY_ECHO 
    PSHS B
!   PCHAR #$7F          * curseur carré 
    PCHAR #$08          * on revient un cran en arrière (pour l'écraser par la suite)
    JSR GETCH           * on attend une touche saisie B contient le caractère tapé
    CMPB #KEY_ENTER     * est-ce le caractère de sortie ?
    BEQ >               * on sort de la boucle
    JSR PUTC            * on l'affiche si ce n'était pas le caractère de sortie       
    BRA <               * on boucle
!   PULS B
    RTS 
********************************************************


**************************************************************************************
* DATA
**************************************************************************************
INIT
    FCB $1B,$5B                  * passage en mode 80 colonnes. Oui PUTC peut faire ça
    FCB $1B,$41,$1B,$50,$1B,$60  * screen 1,0,0
    FCB $11,$0C,$00              * effacement du curseur, effacement de l'écran
**************************************************************************************   
    END   


(avec l'usage de macro et des boucles offertes par LWASM)
Une fois compilé : 111 octets, ce qui rentre bien dans les 119 premiers octets du boot + 128 octets de data, qui sont donc rajouté à l'offset 128 et comble ainsi le premier secteur.

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 17 Fév 2022, 15:51 
Hors ligne

Inscription: 21 Aoû 2006, 09:06
Messages: 1802
Localisation: Brest
Quelques remarques :
  • Pourquoi deux DECA consécutifs au début? Un seul SUBA #2 fait pareil en deux fois moins de temps.
  • Plus loin LDA #$01 suit un BNE. Donc en ce point A=0, et un INCA fait pareil avec 2 fois moins d’octets.
  • Plus loin encore tu sépares le PULS et le RTS qui suit. Tu peux les combiner en ajoutant le PC à la liste des registres. Tu gagnes 1 octet, et 3 cycles.
  • pour passer la palette en noir, pourquoi le fais tu en décroissant et en positionnant le reg d’indexe à chaque tour? Tu peux décroître un compteur, et laisser le registre d’index palette s’auto incrémenter. Comme tu couvres tous les octets de la palette, et que f’est cyclique, pas besoin d’initialiser. Bref moi je ferais un truc genre
    Code:
       LDD #$0020
    !  STA PALETTE_REG    ; STA est plus rapide que CLR
       DECB
       BNE  <
    Tu économises un max d’octets (et des cycles)

_________________
Good morning, that's a nice Tnetennba


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 17 Fév 2022, 16:06 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Merci pour toutes ces "astuces".

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
MessagePosté: 17 Fév 2022, 16:13 
Hors ligne

Inscription: 12 Fév 2021, 15:54
Messages: 78
Localisation: Rennes
Malheureusement pour la palette ça ne fonctionne pas.

En effet, il faut écrire d'abord dans le sélecteur de couleur pour que le registre qui va prendre les informations BVR fonctionne correctement.
Donc à chaque itération il faut écrire dedans obligatoirement.

_________________
Fan de Atari 2600, Thomson MO5, Thomson TO8, Atari STE.
Retro-Codeur à mes heures perdues. https://www.fxjavadevblog.fr


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 21 messages ]  Aller à la page 1, 2  Suivante

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 22 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages
Vous ne pouvez pas joindre des fichiers

Rechercher:
Aller à:  
Développé par phpBB® Forum Software © phpBB Group
Traduction par phpBB-fr.com