home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_2.iso
/
files
/
785b.lha
/
M2A_v1.0
/
m2a.s
< prev
next >
Wrap
Text File
|
1992-06-10
|
18KB
|
600 lines
;
; programme de conversion Ascii Mac <--> Amiga
;
; conçu et réalisé par Jean-Pierre Rivière en février 1991
;
ExecBase = $4
OpenLibrary = -$228
CloseLibrary = -$19e
AllocMem = -$c6
FreeMem = -$d2
MemfPublic = $1
ModeOldFile = $3ed ; ModeNewFile = ModeOldFile ^ 3
Open = -$1e
Close = -$24
Read = -$2a
Write = -$30
DefTaille = 7808 ; = 16 * 488 : taille du tampon d'E/S par défaut
LgrUsageMess = 264 ; ne changez pas la longueur des messages!!
LgrOuvrirMess = 26
LgrEcrireMess = 42
LgrLireMess = 42
LgrMemMess = 40
EUH = $c9 ; caractère Amiga sans équivalent Macintosh
;###############################################################################
; --- d'abord les initialisations d'usage ---
init:
move.l d0,d5 ; sauvegarde de d0
movea.l a0,a3 ; sauvegarde de a0
move.l ExecBase,a6
lea.l DosName,a1
move.l #0,d0 ; version indifferente
jsr OpenLibrary(a6)
move.l d0,DosBase
beq fermerTout
; --- maintenant on va explorer la ligne de commande ---
; === utilisation des registres ===
; d3.b : nombre de caractère du mot actuel de la ligne de commande
; d4.b : nombre d'arguments passés hors option(s)
; d6.l : mode d'ouverture du prochain fichier
; a0.l : poisition actuelle dans la ligne de commande
; a1.l : dernier caractère de la ligne de commande
; a2.l : premier caractère utile de la ligne de commande
; a3.l : premier caractère unitile après le caractère repéré par a2.l
; a5.l : pointe sur le premier pointeur de fichier
; a6.l : base pour appels aux fonctions des bibliothèque
; === utilisation de la mémoire ===
; Source : pointeur de fichier source - suivi immédiatement par Cible
; Cible : pointeur de fichier cible
; optionMem : octet indiquant si l'unique option a déjà été activée
moveq.b #0,d4 ; nombre d'arguments
movea.l a3,a1 ; restauration de l'adresse de la ligne de commande
add.l d5,a1 ; on ajoute le nombre de caractères
subq.l #1,a1 ; pointe sur la fin de la ligne de commande
lea.l Source,a5 ; debut des pointeurs de fichiers
move.l #ModeOldFile,d6
encore:
move.l a3,a0 ; c'est ici qu'est la ruse :
; cela permet de reboucler directement ici au cas où
; on aboutit à un mot vide (et assure aussi la
; progression quand il n'y a pas d'erreur).
jsr traiter ; examen de la ligne de commande
cmpa.l #0,a3 ; a3 nul indique une erreur
beq.s suite
cmpi.b #1,d3 ; mot vide ?
beq.s encore ; fausse alerte (mot = "", ce qui est ignoré)
move.b #0,(a3)+ ; on finit le mot selon la convention du C.
; c'est nécessaire pour l'ouverture d'un fichier.
; La postincrémentation est là pour permettre
; l'astuce en cas de mot vide (aller au delà du
; second guillemet est obligatoire).
cmpi.b #$2d,(a2)+ ; un tiret ?
beq option
cmpi.b #2,d4 ; a-t-on déjà eu deux arguments ?
beq modedEmploi ; si oui message d'explication affiché et terminé
addq.b #1,d4 ; et un argument de plus
move.l DosBase,a6
subq.l #1,a2
move.l a2,d1
move.l a1,a2 ; sauvegarde a1 dans a2
move.l d6,d2
jsr Open(a6)
move.l d0,(a5)+ ; sauvegarde du pointeur de fichier à sa place
beq uneErreur ; fichier refusant de s'ouvrir !
eori.b #$3,d6 ; ModeOldFile <##> ModeNewFile (addq.l en toute rigueur)
move.l a2,a1 ; restaure a1
move.b #32,-(a3) ; ici nécessaire pour reprendre l'algo
; la prédécrémentation est là suite à la ruse
move.b #10,(a1) ; et cela pour le cas extrême l'est aussi par suite
bra encore
; --- la ligne de commande est finie d'être explorée ---
; --- peut-on travailler ou y a-t-il eu un problème ? ---
suite:
cmpi.b #2,d4 ; les 2 fichiers sont-ils ouverts ?
bne uneErreur ; non : il y a eu une erreur.
movea.l ExecBase,a6
move.l Taille,d0
moveq.l #MemfPublic,d1
jsr AllocMem(a6)
tst.l d0
beq erreurMem
move.l d0,Tampon
move.l -(a5),a3 ; fichier cible
move.l -(a5),a2 ; fichier source
move.l d0,(Tampon)
tst.b optionMem
bne.s suite2
jsr MacToAmiga ; conversion de Mac vers Amiga (blessing)
; --- C'est fini, on ferme ! ---
fermerTout:
lea.l Source,a5
tst.l (a5)
beq.s fermerTout2
move.l (a5)+,d1
move.l DosBase,a6 ; on ferme le fichier source (ouvert en premier)
jsr Close(a6)
tst.l (a5)
beq.s fermerTout2
move.l (a5),d1 ; on ferme le fichier destination
jsr Close(a6)
fermerTout2:
movea.l ExecBase,a6
move.l Tampon,a1
cmpa.l #0,a1
beq.s fermerTout3
move.l Taille,d0 ; on libère la mémoire
jsr FreeMem(a6)
fermerTout3:
movea.l DosBase,a1
jsr CloseLibrary(a6)
rts ; programme terminé !
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; --- conversion avec option -i ---
suite2: ; option -i active
jsr AmigaToMac ; conversion Amiga vers Mac (doom, bane & cursing)
bra.s fermerTout
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; --- première option ---
option:
ori.b #32,(a2) ; majuscule ##> minuscule
cmpi.b #$62,(a2)+ ; est-ce un b ?
bne.s option2
move.b (a2)+,d0
cmpi.b #$39,d0 ; ensuite, est-ce un chiffre ?
bgt modedEmploi
subi.b #$30,d0 ; si oui, on le transforme en chiffre binaire
blt modedEmploi
tst.b (a2) ; encore un signe ?
bne modedEmploi
move.l #488,d1
lsl.l d0,d1 ; on décale à gauche d'autant que le chiffre l'indique
move.l d1,Taille
move.b #32,-(a3) ; pour bien repartir sur la ligne (de commande)
move.b #10,(a1) ; et sans oublier ça
bra encore
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; --- seconde option ---
option2:
cmpi.b #$69,-1(a2) ; est-ce un i ?
bne.s modedEmploi ; option inconnu
st optionMem ; on peut répéter l'option plusieurs fois...
tst.b (a2) ; encore un signe ?
bne modedEmploi
move.b #32,-(a3) ; pour bien repartir sur la ligne (de commande)
move.b #10,(a1) ; et sans oublier ça
bra encore
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; --- pas d'allocation mémoire possible ---
erreurMem:
jsr OuvrirStd
beq fermerTout
move.l #MemMess,d2
move.l #LgrMemMess,d3
jsr Write(a6)
bra fermerTout
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; --- quelle erreur ? ---
uneErreur:
jsr OuvrirStd
beq fermerTout
cmpa.l #0,a3 ; une erreur de syntaxe avant tout ?
beq.s modedEmploi
move.l a3,d2
sub.l d3,d2
move.l d1,d4 ; sauvvegarde d1 = entrée standard
jsr Write(a6) ; longueur déjà en d3
move.l d4,d1
move.l #ouvrirMess,d2
move.l #LgrOuvrirMess,d3
jsr Write(a6)
bra fermerTout
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; --- - Comment ça marche, ce truc ? - T'as qu'à lire ! ---
modedEmploi:
jsr OuvrirStd
beq fermerTout
move.l #usageMess,d2
move.l #LgrUsageMess,d3
jsr Write(a6)
bra fermerTout
;################################################################
; *** ouvrir le canal du Shell d'appel ***
; === sortie ===
; d0.l : contient le canal du Shell (ou 0)
; d1.l : égal à d0.l
; ccr : Z est à 1 ssi une erreur est survenue
; a0.l et a1.l sont modifiés
; a6.l : DosBase
OuvrirStd:
movea.l DosBase,a6
move.l #Shell,d1
move.l #ModeOldFile,d2
jsr Open(a6)
move.l d0,d1 ; teste si erreur en même temps
rts
;################################################################
; *** erreur en lecture ***
LireErreur:
jsr OuvrirStd
beq fermerTout ; Qu'avez-vous fait du Shell ?
move.l #LireMess,d2
move.l #LgrLireMess,d3
jsr Write(a6)
rts
;################################################################
; *** erreur en écriture ***
EcrireErreur:
jsr OuvrirStd
beq fermerTout ; Qu'avez-vous fait du Shell ?
move.l #ecrireMess,d2
move.l #LgrEcrireMess,d3
jsr Write(a6)
rts
;################################################################
; *** trouve le premier mot (sa partie "efficace") et le mesure ***
; *** version adaptée spécialement à la ligne de commande ***
; === entrée ===
; a0.l : pointe sur le premier caractère
; a1.l : pointe sur le dernier caractère
; === sortie ===
; a0 et a1 : inchangés
; a2.l : pointe sur le premier caractère "efficace" du premier mot
; a3.l : pointe juste après le dernier caractère "efficace" du premier mot
; a3.l est nul s'il y a une erreur de repérée
; d3.b : longueur "efficace" du premier mot, plus un
; on exploite le fait que le dernier caractère est toujours LF, de code 10
; et donc en particulier on n'a pas particulièreement à le sauver.
; il s'en suit que pour explorer autre chose qu'une ligne de commande,
; il faut encore adapter ce bout de code.
traiter:
movea.l a0,a2
; ici la sentinelle vaut LF
sauter:
cmp.b #32,(a2)+
beq.s sauter
cmp.b #10,-(a2) ; dernier caractère (en fait) ?
beq.s erreurTrait
movea.l a2,a3
cmp.b #$22,(a2) ; un guillemet (") ?
beq.s guillemets
move.b #32,(a1) ; sentinelle = espace
compter:
cmp.b #32,(a3)+ ; sentinelle = espace
bne.s compter
; remarque: le dernier caractère d'une ligne
; de commande est LF (code 10). Donc on a
; plus de test à faire sur a3 avant de placer
; la sentinelle dessus.
finTraiter:
move.b #10,(a1)
move.l a3,d3
sub.l a2,d3
cmp.b #1,d3
beq finDeLigne
sub.l #1,a3 ; il faut revenir un caractère en arrière
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
finDeLigne:
movea.l #0,a3 ; erreur : il n'y a plus de mots sur la ligne
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
guillemets:
move.b #$22,(a1) ; sentinelle = guillemet
addq.l #1,a3
compter2:
cmp.b #$22,(a3)+
bne.s compter2
move.b #10,(a1)
cmp.b #$22,-(a3) ; si pas un guillemet alors erreur
bne.s erreurTrait
move.l a3,d3
sub.l a2,d3
addq.l #1,a2
cmpi.b #1,d3 ; rien entre les guillemets ?
beq special
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
special: ; il n'y a rien entre les guillemets
addq.l #1,a3 ; dans ce cas il faut incrémenter a3
; de façon à ne pas retomber sur le second
; guillemet lors du prochain appel
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
erreurTrait:
movea.l #0,a3 ; signale une erreur (EOL ou guillemet manquant)
rts
; ##########################################################################
; *** convertit le fichier source Macintosh en fichier Amiga ***
; === entrée ===
; a2.l : pointeur du fichier source
; a3.l : pointeur du fichier cible
; === sortie ===
; a2.l et a3.l pointent à la fin de leur fichier.
; a4.l : inchangé
; a6.l : DosBase
; d0,d1,d2,d3,d4,a0,a1,a4,a5 sont modifiés
; le fichier cible est entièrement constitué.
MacToAmiga:
lea.l Mac2Amiga,a4; tableau utilisé pour la conversion
move.l Taille,d3
movea.l Tampon,a5
movea.l DosBase,a6
AccesDisqueMtoA:
move.l a2,d1
move.l a5,d2
jsr Read(a6)
tst.l d0
ble.s MtoA_erreur1 ; erreur (EOF ou autre)
move.l d0,d2 ; nombre d'octets lus et donc à traduire
move.w d0,d4
subq.w #1,d2
moveq.b #0,d0 ; sinon bug pour conversion ascii étendu
MtoA:
move.b (a5)+,d0
cmpi.b #127,d0 ; code ascii étendu ( > 127 ) ?
bvs.s MtoA_Ext
cmpi.b #13,d0 ; code = CR ?
beq.s MtoA_CR
MtoA_fin:
dbf.s d2,MtoA ; a-t-on tout traduit ?
move.l a3,d1
movea.l Tampon,a5
move.l a5,d2
move.l d4,d3 ; nombre d'octets à recopier (et evt à relire)
jsr Write(a6)
tst.l d0 ; erreur d'écriture ?
blt.s MtoA_erreur2
cmp.l Taille,d4
beq.s AccesDisqueMtoA
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MtoA_erreur1:
jsr LireErreur
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MtoA_erreur2:
jsr EcrireErreur
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MtoA_Ext:
and.b #$7F,d0 ; --> indice du tableau Mac2Amiga correspondant
move.b 0(a4,d0),-1(a5); conversion en le caractère Mac équivalent
bra.s MtoA_fin
MtoA_CR:
move.b #10,-1(a5) ; code devenu LF
bra.s MtoA_fin
; ################################################################
; *** convertit le fichier source Amiga en fichier Macintosh ***
; === entrée ===
; a2.l : pointeur du fichier source
; a3.l : pointeur du fichier cible
; === sortie ===
; a2.l et a3.l pointent à la fin de leur fichier.
; a4.l : inchangé
; a6.l : DosBase
; d0,d1,d2,d3,d4,a1,a4,a5 sont modifiés
; le fichier cible est entièrement constitué.
AmigaToMac:
lea.l Amiga2Mac,a4; tableau utilisé pour la conversion
move.l Taille,d3
movea.l Tampon,a5
movea.l DosBase,a6
AccesDisqueAtoM:
move.l a2,d1
move.l a5,d2
jsr Read(a6)
tst.l d0
ble.s AtoM_erreur1 ; erreur (EOF)
move.l d0,d2 ; nombre d'octets lus et donc à traduire
move.w d0,d4
subq.w #1,d2
moveq.b #0,d0 ; sinon bug pour conversion ascii étendu
AtoM:
move.b (a5)+,d0
cmp.b #127,d0 ; code ascii étendu ( > 127 ) ?
bvs.s AtoM_Ext
cmp.b #10,d0 ; code = LF ?
beq.s AtoM_CR
AtoM_fin:
dbf.s d2,AtoM ; a-t-on tout traduit ?
move.l a3,d1
movea.l Tampon,a5
move.l a5,d2
move.l d4,d3 ; nombre d'octets à recopier (et evt à relire)
jsr Write(a6)
tst.l d0 ; erreur d'écritue ?
blt.s AtoM_erreur2
cmp.l Taille,d4
beq.s AccesDisqueAtoM
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AtoM_erreur1:
jsr LireErreur
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AtoM_erreur2:
jsr EcrireErreur
rts
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AtoM_Ext:
and.b #$7F,d0 ; --> indice du tableau Amiga2Mac correspondant
move.b 0(a4,d0),-1(a5); conversion en le caractère Amiga équivalent
bra.s AtoM_fin
AtoM_CR:
move.b #13,-1(a5) ; code devenu CR
bra.s AtoM_fin
; *********************************************************************
; === variables & constantes ===
DosBase: dc.l 0 ; pointeur sur DosBase
Source: dc.l 0 ; pointeur de fichier source
Cible: dc.l 0 ; pointeur de fichier cible
Tampon: dc.l 0 ; pointeur sur le tampon de mémoire dynamique
Taille: dc.l DefTaille ; taille du tampon d'E/S
optionMem dc.b 0 ; drapeau sur l'option
DosName: dc.b "dos.library",0
Shell: dc.b "*",0
usageMess: dc.b "USAGE : m2a [-i] [-b#] source cible",10
dc.b "m2a traduit un fichier ascii Macintosh en un fichier ascii Amiga.",10
dc.b "Utilisez l'option -i pour faire le travail inverse.",10
dc.b "La taille du buffer en octets est de 488*2^# avec l'option -b#",10
dc.b "Sa taille par défaut est de 7808 octets. (-b4)",10,0
ouvrirMess: dc.b " : ouverture impossible.",10,0
ecrireMess: dc.b "erreur en écriture sur le fichier cible.",10,0
LireMess: dc.b "erreur en lecture sur le fichier source.",10,0
MemMess: dc.b "impossible d'allouer assez de mémoire.",10,0
Mac2Amiga:
dc.b 'Ä','Â',
dc.b 'Ç',
dc.b 'É',
dc.b 'Ñ',
dc.b 'Ö',
dc.b 'Ü',
dc.b 'á','à','â','ä','ã','å',
dc.b 'ç',
dc.b 'é','è','ê','ë',
dc.b 'í','ì','î','ï',
dc.b 'ñ',
dc.b 'ó','ò','ô','ö','õ',
dc.b 'ú','ù','û','ü',
dc.b $80,'°','¢','£','§','·','¶','ß',
dc.b '®','©',$81,'´','¨',$82,'Æ','Ø',
dc.b $83,'±',$84,$85,'¥','µ','ð',$86,
dc.b $87,$88,$89,'ª','º',$8a,'æ','ø',
dc.b '¿','¡','¬',$8b,$8c,$8d,$8e,'«',
dc.b '»',$8f,$a0,'À','Ã','Õ',$90,$91,
dc.b '','¯','"','"','`',$2c,'÷',$92,
dc.b 'ÿ',$93,'/','¤',$94,$95,$96,$97,
dc.b $98,'.','¸',$99,$9a,'Â','Ê','Á',
dc.b 'Ë','È','Í','Î','Ï','Ì','Ó','Ô',
dc.b $9b,'Ò','Ú','Û','Ù',$9c,'^','~',
dc.b '',$9d,'·','°',$9e,'"','.',$9f
Amiga2Mac:
dc.b $a0,$aa,$ad,$b0,$b2,$b3,$b7,$b8,
dc.b $b9,$ba,$bd,$c3,$c4,$c5,$c6,$c9,
dc.b $ce,$cf,$d7,$d9,$dc,$dd,$de,$df,
dc.b $e0,$e3,$e4,$f0,$f5,$f9,$fc,$ff,
dc.b $ca,$c1,$a2,$a3,$db,$b4,EUH,$a4,
dc.b $ac,$a9,$bb,$c7,$c2,$d0,$a8,$d1,
dc.b $a1,$b1,EUH,EUH,$ab,$b5,$a6,$a5,
dc.b $e2,EUH,$bc,$c8,EUH,EUH,EUH,$c0,
dc.b $cb,$e7,$e5,$cc,$80,$81,$ae,
dc.b $82,
dc.b $e9,$83,$e6,$e8,
dc.b $ed,$ea,$eb,$ec,
dc.b EUH,$84,
dc.b $f1,$ee,$ef,$cd,$85,
dc.b EUH,$a0,
dc.b $f4,$f2,$f3,$86,
dc.b EUH,
dc.b EUH,$a7,
dc.b $88,$87,$89,$8b,$8a,$8c,$be,
dc.b $8d,
dc.b $8f,$8e,$90,$91,
dc.b $93,$92,$94,$95,
dc.b $b6,$96,
dc.b $98,$97,$99,$9b,$9a,
dc.b $d6,$bf,
dc.b $9d,$9c,$9e,$9f,
dc.b EUH,EUH,$d8
end