*******************************************************
* F A S T B O O T I N S T A L L E R                   *
* Chargeur de programme d'amorçage des disquettes     *
*                                                     *
* CODAGE DEVPAC   Pierre Philippe Launay              *
* COPYRIGHT © 14 avril 1993                           *
*-----------------------------------------------------*
* A la mise sous tension, l'allumage, l'Amiga possède *
* en mémoire un programme rudimentaire chargé de voir *
* s'il y a un volume dans l'un des lecteurs.          *
*                                                     *
* S'il y a un volume (disquette, disque dur,...) le   *
* programme rudimentaire va tester superficiellement  *
* s'il s'agit d'une disquette formatée. Pour cela, il *
* lit la première piste pour déceler une valeur       *
* spéciale dit de synchronisation. Si cela est bon,   *
* le programme rudimentaire va tester s'il s'agit d'  *
* une disquette Amiga. C'est ici qu'on intervient. Le *
* premier bloc de la disquette possède tout d'abord   *
* le mot DOSn où n est une valeur dépendant de la     *
* version du WorkBench. Mettre 0 rend la disquette    *
* compatible avec toutes les machines Amiga. Il y a   *
* ensuite une valeur de contrôle puis l'adresse du    *
* bloc racine (ROOT), c'est-à-dire de la table des    *
* matières de la disquette. En résumé, sur le bloc 0, *
* on aura :                                           *
*    DOS0   Contrôle 880   puis le code d'amorçage    *
*                                                     *
* La somme de contrôle vérifie superficiellement que  *
* le code d'amorçage est correct. Si cette somme est  *
* exacte, Amiga considérera que notre code d'amorçage *
* est correct et il lancera notre codage. Le volume   *
* sera auto-amorcé. A l'inverse, le volume ne sera    *
* pas lancé et seuls apparaîtront ses icônes.         *
*                                                     *
* Parlons maintenant du codage d'amorçage. Ce codage  *
* doit être très court car on ne dispose que de 1012  *
* octets. Il sera écrit dans les blocs 0 et 1 du      *
* volume et doit ici s'appeler BOOT.S pour l'include. *
*                                                     *
*     Bloc 0   DOS0       ( 4 octets)                 *
*              Contrôle   ( 4 octets)                 *
*              Racine     ( 4 octets)                 *
*              Données    500 octets                  *
*     Bloc 1   Données    512 octets                  *
*     ------   --------   ----------                  *
*     TOTAL    CODAGE     1012 octets                 * 
*                                                     *
*-----------------------------------------------------*
* On va utiliser le tracdisk.device                   *
* Pour cela, on recherche l'adresse de notre tâche    *
* On se réserve une petite zone de mémoire (un port)  *
* pour recevoir ou envoyer des informations (message) *
* On cherche le bon dispositif de lecture (device)    *
* On peut commencer. On lit les 2 blocs d'amorçages   *
* initiaux, on remplace par le notre, on modifie ce   *
* qu'il y a à modifier, on réécrit les deux nouveaux  *
* blocs. On arrête le moteur du lecteur. C'est fini.  *
* Il ne reste qu'à nettoyer le système en enlevant le *
* port puis le dispositif.                            *
*-----------------------------------------------------*
* Pour écrire votre codage d'amorce, il est presque   *
* impératif d'utiliser l'assembleur. Le C est à la    *
* limite possible mais un peu lourd ici.              *
*                                                     *
* Amicalement,                                        *
*                                                     *
* Pierre Philippe Launay                              *
*******************************************************

****************************
*  CONSTANTES              *
****************************

*%%%%%%%%%%%%%%%%%%
*  EXEC           %
*%%%%%%%%%%%%%%%%%%
_ExecBase   =  4
;Forbid      =  -132
;Permit      =  -138
;AllocMem    =  -198
;FreeMem     =  -210
FindTask    =  -294  Recherche de l'adresse d'une tâche
AddPort     =  -354  Ajout d'un port de message
RemPort     =  -360  Suppression d'un port de message
OldOpenLib  =  -408  Ouverture d'une bibliothèque
CloseLib    =  -414  Fermeture d'une bibliothèque
OpenDevice  =  -444  Ouverture d'un dispositif périphérique
CloseDevice =  -450  Fermeture d'un dispositif périphérique
DoIO     =  -456     Labcement des actions

*%%%%%%%%%%%%%%%%%%
*  DIVERS         %
*%%%%%%%%%%%%%%%%%%
cmd_read    =  2     Lecture
cmd_write   =  3     Ecriture
etd_motor   =  9     Stop

bloc        =  0     Numéro du bloc à lire
longueur    =  512   Octets par bloc

unit        =   0
mp_sigtask  =  16    Pointeur où va le signal

mn_replyport=  14    Pointeur port réponse
io_command  =  28    Commande du trackdisk.device
io_lenght   =  36    Longueur d'une piste
io_data     =  40    Pointeur des données
io_offset   =  44    Secteur

****************************
*  MACRO                   *
****************************

EXECALL  MACRO
   move.l   (_ExecBase).w,a6
   jsr   \1(a6)
   ENDM



****************************
*  CODAGES                 *
****************************
   section  prg,code_c
   opt   d+,p-


   sub.l a1,a1                On cherche nous même
   EXECALL  FindTask
   lea      readreply(pc),a0
   move.l   d0,mp_sigtask(a0)

   lea      readreply(pc),a1  On crée un port de messages
   EXECALL  AddPort
   lea      diskio(pc),a1
   move.l   #unit,d0
   moveq    #0,d1
   lea      devname(pc),a0
   EXECALL  OpenDevice        On ouvre un dispositif
   tst.l    d0
   bne      erreur

   lea      readreply(pc),a0  On lit l'amorce initiale
   lea      diskio(pc),a1
   move.l   a0,mn_replyport(a1)
   move.w   #cmd_read,io_command(a1)
   move.l   #$40000,io_data(a1)
   move.l   #22*longueur,io_lenght(a1)
   move.l   #bloc*longueur,io_offset(a1)
   EXECALL  DoIO

   bsr      checksum          Calcul de la somme de contrôle
   bsr      copy              On se recopie

   lea      diskio(pc),a1     On écrit notre amorce
   move.w   #cmd_write,io_command(a1)
   move.l   #$40000,io_data(a1)
   move.l   #22*longueur,io_lenght(a1)
   move.l   #bloc*longueur,io_offset(a1)
   EXECALL  DoIO

   lea      diskio(pc),a1     On arrête le moteur
   move.w   #etd_motor,io_command(a1)
   move.l   #0,io_lenght(a1)
   jsr      DoIO

   lea      readreply(pc),a1  On supprime le port message
   EXECALL  RemPort

   lea      diskio(pc),a1     On suprime le dispositif
   EXECALL  CloseDevice
erreur:
   rts


****************************
*  ROUTINES                *
****************************

*%%%%%%%%%%%%%%%%%%
* CHECKSUM        %
*%%%%%%%%%%%%%%%%%%
; Il est possible d'optimiser ce codage (bcs). A vos clavier.
checksum:
   lea      BootBlockIntro+8(pc),a0  ChekSum
   lea      $3f8(a0),a1              Fin du bloc amorce
   moveq    #0,d0
   moveq    #0,d1
   move.w   #$444f,d0                'DO' en d0
   move.w   #$5300,d1                'S0' en d1
l1:
   add.w    (a0)+,d0                 Ajout de 1 mot à d0
   bcs.S    m1                       Débordement?
w1:
   add.w    (a0)+,d1                 Ajout de 1 mot à d1
   bcs.S    m2                       Débordement
w2:
   cmp.l    a0,a1                    Fin?
   bne.S    l1                       Sinon on continue
   not.w    d0                       Inverse d0
   not.w    d1                       Inverse d1
   swap     d0                       LO-word en HI-word
   move.w   d1,d0                    Nouveau d1 Lo-word en d0
   move.l   d0,BootBlockIntro+4      Ecriture de la somme contrôle
   rts      Fin
m1:
   addq.w   #1,d1                    Débordement en d0: increment d1
   bra.S    w1
m2:
   addq.w   #1,d0                    Débordement en d1: increment d0
   bra.S w2

*%%%%%%%%%%%%%%%%%%
*  COPY           %
*%%%%%%%%%%%%%%%%%%
copy:
   lea      BootBlockIntro(pc),a0    Origine de la copie
   lea      $40000,a1                Cible de la copie
   move.w   #$ff,d0                  Longueur 1024 octets
loopy:
   move.l   (a0)+,(a1)+              Et bonzalles
   dbf      d0,loopy
   rts      Fin
****************************
*  VARIABLES   *
****************************
devname:    dc.b "trackdisk.device",0
even
diskio:     ds.l  20
readreply:  ds.l  8
deb:
BootBlockIntro:
   dc.l $444f5300,0,$370             DOS0,checksum,Rootblock
   include  "boot.s"
fin:
