;Namelmd V1.03 - utilitaire de modification du SRC ID des fichiers listmode ;du XL System-II - (c) 11/1/2001 JPG - Support the Free Software Foundation ; ;Dans les fichiers listmode FCS2, les debut et fin des segments de donnees ;sont sauvegardes dans le segment d'entete, sous forme de pointeurs codes ;decimal sous forme d'une chaine ASCII. ;Les zones vides entre les pointeurs et libres en fin des segments sont ;des caracteres "espace" (20H). ;Le SRC ID est conserve, si il est present (ID entree en fin d'analyse), ;dans le second segment, le segment de texte, entre les champs $BTIM et ;$SMNO. ;Quand il est present, le champs SRC ID prend la forme "$SRC![chaine ID]!" ;Les fichiers generes par System II ont un segment d'entete compris entre ;les offsets 0 a 127 et un segment texte commence a l'offset 128 et se ;termine avant l'offset 2048. ;L'octet de poids faible du pointeur d'offset de fin du segment texte est ;situe a l'offset 19H, celui du pointeur d'offset de debut du segment data ;(toujours a 2048 avec System-II) a l'offset 21H. .model small .code ORG 100H DTA EQU 81H ;offset de la DTA dans le PSP LENGTH EQU 800H ;taille segments header + text START: mov si,DTA ;si pointe la DTA FNAME_SRCH: lodsb cmp al,20H jne FNAME_SRCH ;recherche du parametre nom de mov di,OFFSET FNAME ;fichier LMD FNAME_LOAD: lodsb cmp al,20H je SRC_SRCH stosb jmp FNAME_LOAD ;sauvegarde nom de fichier LMD SRC_SRCH: lodsb cmp al,'"' ;erreur de syntaxe jne DOS_RETURN ;retour au DOS mov di,OFFSET SRC_ID SRC_LOAD: cmp di,OFFSET SRC_ID+20H ;erreur par oubli de fermeture des je DOS_RETURN ;guillemets ou chaine ID trop longue lodsb cmp al,'"' je OPEN_FILE stosb jmp SRC_LOAD ;sauvegarde nouveau SRC ID OPEN_FILE: mov dx,OFFSET FNAME mov ax,3D02H ;ouverture fichier avec acces r/w int 21H ;en utilisant le file handle jc DOS_RETURN ;erreur d'ouverture - quite sans fermer mov bx,ax ;sauve le file handle dans bx call FILE_OK ;ok? est-ce bien un fichier LMD FCS 2.0? jc CLOSE_FILE ;erreur de fichier, ferme et abandonne mov si,OFFSET OLD_STR BTIM_SRCH: cmp si,OFFSET OLD_STR+LENGTH je CLOSE_FILE ;limite la recherche au text segment lodsb cmp al,'$' jne BTIM_SRCH lodsw cmp ax,'TB' jne BTIM_SRCH lodsw cmp ax,'MI' jne BTIM_SRCH ;reperage du champ $BTIM mov cx,si ;si pointe apres $BTIM! sub cx,OFFSET OLD_STR ;calcul de cet offset dans fichier add cx,0AH ;offset fin champ $BTIM dans fichier mov si,OFFSET OLD_STR ;si et di pointent les buffers image mov di,OFFSET NEW_STR ;ancien et nouveau LMD MOVE_START: lodsb stosb ;recopie du fichier LMD jusqu'au champs loop MOVE_START ;$Btim inclus call INSERT_SRC ;routine d'insertion SRC ID call ADD_END_TXT ;routine d'ajustement fin segemnt texte call PTR_ADJUST ;routine d'ajustement pointeur fin txt call SAVE_LMD ;routine de recriture du fichier LMD CLOSE_FILE: mov ah,3EH int 21H ;fermeture du fichier DOS_RETURN: mov ah,4CH ;rend la main au DOS int 21H FNAME DB 32 dup (0) ;variable nom de fichier LMD SRC_ID DB 32 dup (0) ;variable nouveau SRC ID OLD_STR DB 2048 dup (?) ;buffer anciens segments header et txt NEW_STR DB 2048 dup (20H) ;buffer nouveaux segm. header et txt ;Fonction qui determine si le fichier trouve par la routine OPEN_FILE est ;utilisable. Elle retourne nc dans ce cas, sinon elle retourne c. ;Qu'est-ce rend le fichier utilisable?: ; a) L'extension doit etre LMD. ; b) Le champ signature dans l'entete LMD doit etre 'FCS2.0'. ; (Les six premiers octets du fichier). FILE_OK: mov si,OFFSET FNAME ;si pointe le nom et path du fichier FO1: lodsb or al,al jz FEX ;pas d'extension, ce n'est pas un LMD cmp al,'.' jne FO1 lodsw or ax,2020H cmp ax,'ml' jne FEX lodsb or al,20H cmp al,'d' jne FEX ;mauvaise extension, pas un LMD mov cx,LENGTH ;copie le LMD header et le text segment mov dx,OFFSET OLD_STR ;dans le buffer OLD_STR pour mov ah,3FH ;examination et modification int 21H jc FEX ;erreur de lecture fichier, abandon mov ax,WORD PTR [OLD_STR] cmp ax,'CF' jne FEX mov ax,WORD PTR [OLD_STR+2] cmp ax,'2S' jne FEX mov ax,WORD PTR [OLD_STR+4] cmp ax,'0.' jne FEX ;erreur de signature FCS2, abandon mov ax,WORD PTR [OLD_STR+20H] cmp ax,'84' ;erreur de signature System-II, abandon jne FEX jne FEX clc ;carry link a zero si tout OK OK_END: ret FEX: stc ;retour avec carry link a 1 si erreur jmp OK_END ;Routine d'insertion du champ $SRC contenant le nouveau SRC ID entre les ;champs $BTIM et $SMNO. INSERT_SRC: mov ax,'S$' stosw mov ax,'CR' stosw mov al,'!' stosb ;d'abord ajoute $SRC! a la chaine push si mov si,OFFSET SRC_ID MOVE_SRC: lodsb or al,al jz SRC_END stosb ;puis le nouvel SRC ID jmp MOVE_SRC SRC_END: mov al,'!' stosb ;enfin le '!' de fin de champ pop si ret ;Routine d'ajustement de fin du segment texte. Au lancement du programme, ;le buffer NEW_STR a ete initialise avec 2048 caractere 'espace' (20). Ce ;sous-programme ajoute la portion de segment texte allant du debut du champ ;$SMNO a la fin du champ $TOT. ADD_END_TXT: lodsb cmp al,'$' jne ADD_END_TXT lodsw cmp ax,'MS' ;recherche du champs $SMNO jne ADD_END_TXT sub si,3 ;ajustement si au debut du champ END_SRCH: lodsb stosb cmp al,'$' jne END_SRCH lodsw stosw cmp ax,'OT' jne END_SRCH lodsw stosw ;recopie du segment texte jusqu'au cmp ax,'!T' ;debut du champ $TOT jne END_SRCH mov cx,0DH MOVE_TOT: lodsb ;recopie des 13 derniers octets du stosb ;champ $TOT jusqu'au '!' final loop MOVE_TOT ret ;routine d'ajustement de la valeur du pointeur d'offset de fin du segment ;de texte. Le registre di pointe actuellement cette valeur plus 1 plus ;l'offset du buffer NEW_STR dans ce programme. Il faut donc retrancher ces ;deux valeurs a si pour obtenir la valeur binaire du pointeur, qui est ;ensuite convertie en decimal, puis codee sous forme ASCII, et enfin ;relogee de maniere que la chaine resultante ait l'octet representant le ;digit de poids faible a l'offset 19H du fichier d'entete. Si l'octet de ;poids fort (le quatrieme en partant de la droite) est un zero, alors le ;caractere ASCII '0' (30H) est remplace par un caractere 'espace' (20H). PTR_ADJUST: std ;set direction flag (decrementer) mov ax,di ;pour aller de droite a gauche mov di,OFFSET NEW_STR+19H ;di pointe l'offset fin texte sub ax,OFFSET NEW_STR+1 ;ax = valeur binaire pointeur mov cx,4 mov dl,0AH ;conversion decimale sur 4 digits ASCII_PTR: div dl push ax mov al,ah or al,30H ;conversion chiffre --> ASCII stosb pop ax xor ah,ah loop ASCII_PTR ;boucle pour 4 conversions inc di mov si,di lodsb cmp al,30H jne PTR_END mov al,20H ;si digit de poids fort est un zero, stosb ;alors remplacer code par un espace PTR_END: cld ;clear direction flag (incrementer) ret ;pour reprendre travail normal SAVE_LMD: xor cx,cx ;deplacement a zero par rapport xor dx,dx ;au pointeur fichier mov ax,4200H ;initialise le pointeur au int 21H ;debut du fichier mov cx,LENGTH ;recopie de 2048 octets de l'image mov dx,OFFSET NEW_STR ;header + text segment LMD vers mov ah,40H ;le debut du fichier int 21H ret END START