| Win3x.Org http://www.win3x.org/win3board/ |
|
| Apprentissage du BASIC Microsoft sous DOS http://www.win3x.org/win3board/viewtopic.php?f=14&t=19163 |
Page 1 sur 1 |
| Auteur : | gm86 [ 21 août 2015 14:04 ] |
| Sujet du message : | Apprentissage du BASIC Microsoft sous DOS |
| Je fais suite à mon message au lien suivant : viewtopic.php?p=138605#p138605 Je lance un projet sur ce qui m'a fait apprécier l'utilisation d'un ordinateur, l'apprentissage du BASIC. C'était il n'y a pas si longtemps (si, si, je vous promets, je n'ai guère changé depuis !), j'ai découvert avec enthousiasme la possibilité de faire faire ce qu'on désirait à une machine via des bouquins des années 80. Les mots programmation et BASIC me sont restés liés. Cela a commencé brièvement avec un TO8, plus sérieusement sur une TI-82, et enfin, sur PC. Le langage qui m'a le plus marqué, a été en fait celui le plus basique, c'est le cas de la dire. Il s'agit d'un BASIC générique de la firme Microsoft. Il se trouvait en ROM sur la plupart des vieux micro-ordinateurs, mais surtout, a été présent en version disque pour les systèmes d'exploitation CP/M puis MS-DOS. Pas de graphisme ni de son pour cette dernière, mais des instructions puissantes malgré une certaine lenteur dans l'interprétation et une mémoire limitée. Voici les prémisses à ce projet sur ce forum :
|
| Auteur : | Big Monstro [ 21 août 2015 16:40 ] |
| Sujet du message : | Re: Apprentissage du BASIC Microsoft sous DOS |
| Permettre le lancement d'un exécutable CMD sous MS-DOS, voilà une idée bien sympathique... Non seulement cette initiative est bien ancrée dans la thématique originelle de Win3x.Org (l'informatique 16-bit) mais elle implique aussi de la programmation. Voilà le genre de projet que j'attendais depuis si longtemps !!! En effet, c'est triste à dire mais on n'a guère vu de projets de programmation 16-bit au-delà de 2007/2008 (à l'exception de SuperKoko en 2010). En outre, le niveau général a bien baissé : les quelques réalisations intéressantes (pour systèmes 32-bit) étaient noyées par une infinité de "projets" insipides se résumant à personnaliser un Windows et à s'en attribuer les mérites pour avoir prétendument créé "son" système d'exploitation. La plupart du temps, ce n'était jamais achevé et parfois même pas entamé ; juste de l'esbroufe pour caresser son ego. Dix fois, ça passe encore, mais quand on voit ça 100x fois... On a l'impression que les auteurs de projets ont oublié l'existence de la section "Programmation et librairies", créée en novembre 2006 pour les aider à concevoir des logiciels 16-bit. A tel point que j'ai envisagé - à plusieurs reprises - de supprimer la dite section et relocaliser ses sujets dans "Applications". A l'évidence, son contenu n'intéresse plus suffisamment de monde pour justifier la séparation. Mais vous êtes, gm86, l'exception qui confirme la règle et je vous remercie d'emblée pour nous avoir présenté ce projet. Bonne continuation ! Très cordialement, Big Monstro |
| Auteur : | gm86 [ 16 avr. 2017 12:46 ] |
| Sujet du message : | Re: Apprentissage du BASIC Microsoft sous DOS |
| Vendredi 21/08/2015 Hélas, le shell est vraiment la partie modeste du projet. On peut faire la même chose avec DEBUG. Un lanceur universel d'applications CP/M-86 est trop ambition — d'autres ont déjà relevé le défi. Le chargement des différents modèles de mémoire n'est pas si facile à étudier sous DOS Plus. En revanche, un patch pour un logiciel CP/M-86 compatible avec la partie de l'API CP/M reprise par le DOS est simple. Merci pour le soutien, manier le seize bits équivaut à un pêché chez moi ! La partie la plus passionnante est le cours. Le BASIC est vraiment un langage agréable pour parler simplement à une machine. C'est une possibilité de nos machines depuis l'ère des 8 bits. Mercredi 30/09/15 Je remonte le sujet pour une précision. Lorsque le shell se lancera, la zone de transfert de données, dite DTA, se trouvera dans son PSP. Or MBASIC.CMD possèdera son propre PSP au début du segment de données. Il faudra donc y redéfinir la nouvelle DTA avant de lui passer la main. Jeudi 28/01/16 Actuellement, j'ai un accès limité à l'informatique. Je présenterai une prochaine fois le format COM, sous DOS bien sûr, et le format CMD de CP/M-86, équivalent à l'exécutable EXE du DOS. Le but est de mieux appréhender les mécanismes d'exécution des applications. Samedi 30/04/16 Dans une ancienne revue en anglais archivée sur le net, un lecteur écrivait au sujet du bug des instructions FIX et INT avec le zéro négatif en double précision. Sur processeur 8086, seule la version 5.28 réglait ce souci alors que les révisions 5.2x 8 bits étaient corrigées. Cf. http://books.google.fr/books?id=WYnHD9W ... =RA2-PA252 N'ayant pas réapparu sur ce forum depuis un moment, j'ai décidé d'attaquer l'impossibilité par cette dernière version pour MS-DOS de reconnaître la fonction USR. J'ai profité du fait que j'ai coupé à mon astreinte cette nuit pour faire une comparaison avec la révision précédente. J'ai deux solutions : taper l'instruction NOP à l'offset 1D4Ah via DEBUG, ou remplacer l'octet 83h à l'offset 1D47h par 81h. Dans les deux cas, on évite l'octet FFh superflu après l'instruction CMP DX,-1 soit en le supprimant (CMP DX,-01h puis NOP) soit en l'intégrant (CMP DX,0FFFFh). En fait, Microsoft avait tenté de remplacer l'ancienne instruction CMP DL,-1 qui causait le même bug lorsque la fonction USR pointait une adresse finissant par FFh. Je me suis aidé du vieux logiciel CRACKER de la société Wendin. J'expliquerai la méthode utilisée pour faire le diagnostic conjointement à DEBUG. Vendredi 06/05/16 Aujourd'hui, je vais vous expliquer comment j'ai débuggé le BASIC Microsoft pour reconnaître à nouveau les fonctions USR[x]. Les fonctions USR sont une ancienne façon d'appeler des routines en langage machine. Un maximum de dix peut être défini (par défaut, la première équivaut à USR0). Les appels CALL sont plus souples d'emploi et acceptent un nombre quelconque de paramètres. Néanmoins, bien que USR ne fut gardé que par raison de compatibilité, j'estime que l'emploi d'une fonction en langage machine est un luxe dont je ne me priverai pas. Malheureusement, le dernier BASIC Microsoft pour MS-DOS (pas spécifique au PC) renvoie un message d'erreur lorsqu'il rencontre une fonction USR, comme si nous avions oublié de la déclarer. Or, cette version 5.28 est améliorée par rapport à la précédente. Par exemple, un 0# enregistré en -0# ne pose plus de problème pour les fonctions INT et FIX qui renvoient la partie entière d'un nombre positif voire négatif. En effet, on avait droit à une erreur arithmétique avec les anciens BASIC-86 :
C'est donc bien triste que le dernier BASIC-86, enfin débarrassé de cette faiblesse, introduise un nouveau problème. Nouveau ? Pas si sûr, mais je préfère ne rien dire pour l'instant. Dans un premier temps, modifions un programme de Peter Norton qui illustrait l'appel CALL dans un BASIC interprété. La routine d'assemblage d'origine renvoyait la valeur absolue d'un entier (autre que -32768 vu que 32768 n'existe pas en mot signé de 16 bits). Ce que je souhaite, c'est traiter aussi les réels et avoir une fonction fonctionnant comme ABS. Voici la routine à assembler avec l'assembleur de Microsoft :
Résultat avec la révision 5.27 :
Dans un second temps, prenons les choses en main. Utilisons l'outil de mise au point DEBUG sur la version 5.28.
Désassemblons MSBASIC.COM avec CRACKER de Wendin et cherchons une référence à cette table dans le fichier MSBASIC.LST obtenu :
DX est ensuite comparé à l'octet FFh. Et là est le piège : c'est un octet signé, donc équivalent à -1 et par conséquent égal au mot signé FFFFh. On a affaire à une instruction optimisée (gain d'espace d'un octet). Cependant, elle est tout de même suivie d'un autre octet FFh qui modifie l'instruction suivante. Remplaçons ce déchet par l'instruction NOP pour le prouver :
Maintenant, quel est le pourquoi de cette faute lourde de Microsoft ? En fait c'est une correction loupée d'un bug qui se produisait une fois sur 256 et qui n'avait, alors, aucune incidence sur la pile. Et avant de l'oublier, je l'avais déjà rencontré. Exécutons mon programme BASIC avec la révision 5.27 après avoir modifié la ligne 190 :
80 FA FF cmp dl,FF par l'instruction préférée des assembleurs lorsqu'ils rencontrent CMP DX,0FFFFh, 83 FA FF cmp dx,-01 voire dans la logique du programmeur par 81 FA FF FF cmp dx,FFFF et non pas 83 FA FF cmp dx,-01 FF aïe ! push... ? inc... ? Pour conclure, voici les modifications à effectuer aux BASIC-86 :
Deux problèmes principaux restaient avec le BASIC Microsoft 5.28 : - les arguments incorrects de ligne de commande provoquant parfois l'erreur NO RESUME voire un résultat plus qu'imprévisible, surtout lors du second essai ; - l'erreur critique (souvent disque ou imprimante) provoquant le plantage de l'interprète de commande avec un DOS moderne. Le premier vient de la valeur non initialisée d'un mot en DS:04CBh testé en cas d'option non reconnue au démarrage. Le second au fait que les trois adresses de vecteur du PSP (INT22h à 24h) sont initialisés à leur valeur d'origine au retour du traitement d'erreur critique (INT24h). En effet, ce dernier demande à DOS via AL=02h de terminer le programme en se branchant au vecteur de l'INT22h détournée par le BASIC. Solution du premier : on met à zéro cette valeur dès que le registre de données DS est initialisé. Pour le second, c'est plus épineux. Le programme sauvegarde le mot en CS:[16h] avant de le modifier. Il s'agit du segment du processus parent (très probablement l'interprète de commande COMMAND.COM). Il est modifié par la valeur du segment de son propre PSP. Ainsi, le programme est parent de lui-même tel que se comporterait l'interprète de commande lui-même ! Ce mot, apparu avec DOS 2, n'était pas documentée par Microsoft. Il permet à un programme fils de connaître son père. Son but théorique : puisque le BASIC détourne l'INT24h afin que DOS pense le terminer en pointant le vecteur de l'INT22h redéfinie elle-aussi, on évite que DOS 2 ne change de processus actif et que la mémoire ne soit libérée. En effet, puis que DOS crée un PSP pour chaque programme chargé, son segment sert à définir ce processus. Cette précaution est plus importante encore à partir de MS-DOS 3, qui apporta le support réseau mais qui n'existait pas encore à l'époque. Or il faut aussi mettre à jour pour ces versions les adresses de vecteur du PSP ; sans oublier de restaurer les originaux lorsqu'on voudra réellement quitter le BASIC ! Le plus simple est de modifier la table d'interruptions puis de recréer le PSP via la fonction 26h du DOS (INT21h). J'ai pu essayer différentes modifications car le BASIC comporte du code superflu qu'on peut optimiser et remplacer. J'ai néanmoins choisi un moyen plus simple. La routine de l'INT22h du BASIC suit l'instruction IRET de la routine appelée par l'INT24h du DOS. Le BASIC détecte si la version est DOS 2. J'estime donc, si elle est supérieure, de faire continuer la routine INT24h dans INT22h sans passer par le DOS. Il suffit de remplacer IRET par l'instruction NOP via du code auto-modifiant. D'ailleurs, notre BASIC n'utilise pas les arguments passés sur la pile lors de l'erreur critique mais restaure plus tard son propre pointeur. Donc, on se fiche de l'état du haut de la pile et il nous reste en plus un mot en DS:[016Eh] inutilisé mais décrivant l'erreur ! D'ailleurs, la version 5.27 du BASIC ne comportait pas de routine 22h mais nettoyait [une partie de] la pile de l'INT24h [pour récupérer DS et ES]. Code original : Vous remarquez que le BASIC 5.28 original active, sous DOS 2, le contrôle étendu de Ctrl-C sans se soucier de son état précédent afin de le restaurer. Je préfère laisser le choix à l'utilisateur de DOS via la commande interne BREAK. Dimanche 24/07/16 L'inconvénient du patch est qu'il laisse le DOS dans un état second jusqu'à l'appel d'une nouvelle fonction disque. En effet, le drapeau d'erreur critique reste activé. L'usage des piles par le DOS est modifié et certains programmes résidents risquent d'attendre pour traiter des actions en tâche de fond. Une solution serait de demander à la routine INT24h de transformer elle-même l'abandon en échec (AL=3) et de modifier l'adresse de retour complète, en BP+18h, pour qu'elle pointe la routine INT22h. Il ne faut pas oublier en effet que l'interruption 24h peut être déclenchée dans une routine en langage machine déposée par l'utilisateur dans le segment de données du BASIC. Il faut donc étudier le code suivant : En revanche, je peux vous expliquer l'assignation différente des trois cases mémoire selon la version du DOS. La première pointe la routine datant de CP/M pour intercepter Ctrl-C et Ctrl-S (redondante avec le DOS) : sous DOS 2+, on vérifiera cinq fois moins souvent car la fonction six d'E/S appelle régulièrement l'interruption des tâches de fond lorsqu'aucun caractère n'est lu.* Le deuxième pointe la fonction utilisée comme sortie de caractère : sous DOS 2+, on préfère la numéro deux à la six car elle appelle régulièrement cette même interruption.** Enfin, la troisième pointe la routine obtenant le vecteur d'une interruption : sous DOS 2+, il existe une fonction pour cela qui consulte DOS avant de regarder dans le table des interruptions du processeur (par exemple pour une routine personnelle d'interception de Ctrl-C avec DOS comme intermédiaire). * MS-BASIC utilise une particularité non documentée de la Fct6 en mode entrée (DL=FFh) : le fait qu'AL=0 après appel si rien n'est lu. Cf. http://spike.scu.edu.au/~barry/interrupts.html ** La fréquence d'appel de l'INT28h est passée d'un caractère sur quatre à un sur soixante-quatre depuis DOS 4. Cf. http://sites.google.com/site/pcdosretro/dosapinotes Jeudi 4 août 2016 Récapitulatif de l'interaction de la routine d'INT24h de MS-BASIC avec différents DOS : - MS-DOS 1 : système purement monotâche, se branche à la routine INT22h de MS-BASIC ; - MS-DOS 2 : système possiblement multitâche, ne libère pas la mémoire de MS-BASIC qui est son propre parent et se branche à sa routine INT22h ; - MS-DOS 3 ou plus : système réseau, retourne à l'invite de commande en plantant car la mémoire de MS-BASIC n'est pas libérée ; - DOS Plus : système CP/M-86 compatible avec les fonctions documentées de DOS 2.11, retourne à l'invite de commande sans planter ; - DR DOS : compatible DOS 3.31, remarque que MS-BASIC est son propre parent et transforme l'erreur critique en échec de fonction (possibilité de DOS 3). Le détournement de l'INT22h via la table des interruptions sous ces trois derniers DOS ne sert plus que lors de la création d'un nouveau PSP (fct 26h de l'INT21h). (...) Je patche ensuite le DOS des versions 3 et plus de Microsoft (et IBM) pour éviter que les vecteurs sauvés dans le PSP soient inscrits dans la table des interruptions. L'inconvénient est qu'un processus abandonné après une erreur critique ne restaure pas forcément les vecteurs des interruptions 23h et 24h. Mystérieusement, COMMAND.COM ne requiert pas, dans ce cas précis, de restauration à partir du PSP. Tant pis pour un autre processus parent. Pour patcher, comparons DOS 2: Par exemple, avec MS-DOS 6.22 en mémoire basse :
Dimanche 14 août 2016 Vous avez compris que je trouve stupide qu'après MS-DOS 2, on ait enlevé autant d'utilité à l'usage de l'interruption 22h. Il est vrai qu'elle était mal documentée : - son rôle premier de retour au processus parent était à peine officialisé ; - la documentation officielle citait à sa place l'appel à l'interruption 23h (Ctrl-C) lors de la demande d'abandon dans une routine d'erreur critique (INT 24h) ; à l'exception du guide du programmeur de PC-DOS 7 qui ne change rien à la donne. On comprend pourquoi on ajoutait des appels bidons au DISK RESET (fct 0Dh) ou GET DOS VERSION (fct 30h) comme alternative sous GW-BASIC pour quitter le mode critique du DOS. Pour finir le patch de MSBASIC, insistons sur le fait que les messages précis d'erreur disque apportés par MS-DOS ne sont jamais appelés. La révision 5.27 copie bien DI dans le registre général AX après une erreur critique, mais ne traite pas pour autant ce code. Pire, la version 5.28 est un foutoir vu son caractère triple : application destinée à MS-DOS 1, reconnaissant DOS 2 et restant compatible avec son ancêtre sous CP/M. Malgré tout, le code d'erreur critique est bien stocké dans le mot DS:[16eh] pour un usage ultérieur. Ainsi, la révision 5.27 affiche Disk I/O error car seul un lecteur de disque pouvait provoquer une erreur critique à l'époque. DOS 2 étendit cela aux imprimantes et périphériques divers, d'où le message Device I/O error. Cependant, tous les DOS reconnaissent un lecteur de disquette vide ou une disquette protégée contre l'écriture ; quoique les GW/BASIC pour DOS 3 préfèrent afficher Permission Denied comme pour une violation de partage. Nous avons donc Disk write protected et Disk not Ready (avec une majuscule car Ready était en concurrence avec le prompt Ok !). Reste l'identification d'une disquette défectueuse. Voyons les codes d'erreur critique traditionnels du DOS :
Sous DOS 2, avec l'arrivée des disques durs et périphériques installables via un gestionnaire, Disk media error fut réservé pour le code 7, ce qui est un peu ambigu : une disquette non-DOS n'est pas un médium forcément défectueux. Le reste redevient Device I/O error. Par expérience, je peux dire que les codes 6 et 8 sont souvent signe d'un disque défectueux, des informations écrites lors du formatage bas niveau ayant disparu (index de secteur, par exemple). Néanmoins, le premier peut être provoqué par une tête de lecteur désalignée voire une mauvaise alimentation, et le second par une tête sale voire un numéro de secteur erroné. En revanche, l'erreur quatre, valable aussi pour les CD gravés (quel bond dans le temps !), signifie une lecture possible mais altérée des données. Mardi 23 août 2016 Passons à la mise en œuvre. La sauvegarde du registre AX lors d'une INT24h est inutile. De plus, on n'est pas obligé de passer par un registre général pour copier une variable mémoire dans DS. J'ai viré la modification de BREAK. J'ai ainsi pu déplacer le saut inconditionnel à la place du saut inconditionnel : les variables sont fixées d'abord pour DOS 2 et ensuite pour DOS 1 le cas échéant. J'ai économisé cinq octets en utilisant l'instruction LES pour choper deux mots continus et en remplaçant un saut normal en saut court, afin d'y écrire une table d'erreurs. Cette liste de numéros apporte de la souplesse ; je me suis inspiré de GW-BASIC 2 pour cela. L'instruction ROR suivie d'une comparaison m'a permis de ne garder que les cinq premiers codes pairs, tout en transformant AL en index pour XLAT (adresse de base en BX). Nous obtenons enfin une gestion d'erreur digne du DOS. (...) Ce qu'apporte le patch : - plus de plantage lorsqu'on commet une erreur de ligne de commande ; - la correction du bug de la fonction USR ; - l'attribution correcte des numéros d'erreur disque... Ce que n'apporte pas le patch : la compatibilité de la gestion d'erreur critique avec DOS 3+ et DOS Plus. MS-DOS nécessite une petite modification de son noyau pour ne pas planter ; DR DOS transforme l'erreur critique en erreur normale alors que DOS Plus met fin au BASIC. Vendredi 2 septembre 2016 Il est très facile de rendre MS BASIC compatible DOS 3+. Il suffit de mettre à jour le PSP en le recréant. Cependant, DOS Plus (compatible 2.11) ainsi que DR DOS 6 d'avant le correctif PAT312 planteront. Comme MS-DOS 2 et son prédécesseur, DOS Plus modifie le saut long appelé par CALL 5 du nouveau PSP pour que son offset indique une mémoire libérée de ce dernier (FFF0h au lieu de FEF0h maximum). Or le code pointé tient sur plus d'un paragraphe et dépasse donc la limite du nouveau segment. Hier matin, j'ai assemblé un passage entier via MASM afin d'inclure dans un code serré les particularités suivantes : - remettre BREAK dans son état d'origine une fois BASIC terminé ; - rendre compatible BASIC avec MS-DOS 3 et suivants grâce à la mise à jour du PSP ; - rendre compatible BASIC avec DR DOS et suivants (correctif PAT312 nécessaire à cause de la mise à jour du PSP ci-dessus) ; - prendre en compte les nouveaux numéros d'erreur disque ; - la possibilité d'appeler facilement la routine d'obtention d'un vecteur d'interruption depuis un sous-programme en langage machine (call far [140h])... Pour les curieux explorant via DEBUG, sachez que MS BASIC contient du code [qui risque de] vous contrer. Il s'agit de l'appel CALL 3041 qui est suivi d'un octet de donnée qu'il compare à la suite d'une instruction BASIC. Cet octet, en plus d'embrouiller le désassemblage, risque d'être écrasé par l'instruction de pas-à-pas INT3. Samedi 11 septembre 2016 (...) Les 278 octets inscrits à l'offset 452Ch [seront] obtenus via un fichier à assembler. J'ai même fait en sorte que le pointeur de pile soit après l'erreur critique exactement comme avant. (...) Samedi 17 septembre 2016 J'espère que vous aurez compris l'utilité de l'assembleur dans l'utilisation des logiciels anciens. On peut se poser à présent la question de l'utilité d'un mini-shell pour MBASIC.CMD sous CP/M-86. Il peut être intéressant de modifier l'en-tête du programme pour le transformer au format COM de MS-DOS. À bientôt. Jeudi 29 septembre 2016 Merci de la remontée.
L'affichage des nombres se trouvent à l'adresse 6158h. On remarque le point décimal (norme américaine) à l'offset 615Eh, et surtout, la déconcertante virgule à l'offset 616Eh séparant les milliers lors d'une sortie formatée (PRINT USING "#######,,.##";nombre par exemple). Rien ne vous empêche de la remplacer par une apostrophe. Dimanche 16 octobre 2016 Si je devais proposer en ligne le BASIC corrigé, je pense que le mieux serait d'éviter de supprimer du code issu de la conversion 8 bits en 16 bits. J'ai fait un premier essai avec l'aide du désassembleur Soucer v.8 avec qui je n'arrive plus à afficher le code après appel CALL 3041 (puisque non-retour), bien que j'ai pensé à remplacer l'octet de données suivant par un NOP et activé les mêmes options que précédemment. J'ai donc procédé avec l'ancien désassemblage sous forme de fichier LST et non ASM ; ce qui m'oblige à imprimer et faire les corrections manuellement. Quelle galère ! Nous savons qu'un 8086 ne peut faire que des sauts courts lorsqu'ils conditionnels. Ce qui nous obligent, lorsqu'il ne peut être court, à le remplacer par un saut inconditionnel précédé d'un saut à la condition inversée qui pointe après. (...) J'exposerai une méthode moins risquée. P.S. : avec SYMDEB à la place de DEBUG, il faut remplacer XCHG DX,AX par XCHG AX,DX pour obtenir la troisième forme optimisée sur un octet, c'est-à-dire, DB 92h. BASIC a besoin de cinq octets minimum de libre pour éviter de détruire la pile avant un Out memory. Samedi 5 novembre 2016 BASIC, une fois lancé, peut planter par manque de pile (lors d'une seconde erreur de syntaxe par exemple). D'ailleurs, le dernier paramètre de l'instruction CLEAR ne peut être inférieur à 79. Au démarrage, il effectue un premier calcul de la mémoire libre, considère son huitième afin de fixer la taille de la pile qui n'excédera pas 512 octets (200h). Or il est dangereux de descendre trop en-dessous de 80 (50h). Je me suis aidé du désassembleur SOURCER de V Communications pour pouvoir créer le fichier DEBUT.ASM dans lequel j'ai souligné les changements sous forme de paragraphes. Cf. futur message J'ai mis à jour le fichier DEBUT.ASM du fait d'un bug mineur. La combinaison de touche Ctrl-A (^A) rappelle le contenu du tampon clavier (saisie précédente) débutant à l'adresse DS:0373h. Or au lancement, il vaudrait mieux qu'il soit initialisé par un caractère nul. 18 novembre 2016 On comprend pourquoi DOS alloue le maximum de mémoire aux programmes au format COM : la plupart ne se soucient pas où ils écrivent. Le BASIC pour 8086 a la bonne idée de créer un nouveau PSP, mais il tarde à calculer la mémoire libre (mot à l'offset 6) et initialise plusieurs variables entretemps. Samedi 25 mars 2017 J'ai légèrement modifié le patch. Pour récapituler, la gestion des fichiers restera incompatible avec la FAT32 en mode MS-DOS sous Windows 9x, ainsi qu'avec Windows Me. Le handler d'erreur critique serait à revoir pour DOS Plus. Samedi 1er avril 2017 Si DOS Plus, lorsqu'il crée un nouveau PSP, reportait une mémoire libre (offset 6) non grandie de 256 octets par rapport au PSP original, l'appel 5 ne pointerait jamais un code devant se contenter du dernier paragraphe d'un segment. Il se comporterait un peu plus comme DOS 3 qui déduit la taille du PSP lorsqu'on use de la fonction 26h, et qui restitue lui aussi tous les vecteurs DOS lors d'un abandon après une erreur critique. Corrigé de ce bug, on pourrait lancer MS-BASIC patché sur ce système d'exploitation. Mardi 4 avril 2017 Corriger DOS Plus est plus facile encore que DR DOS. On recherche la valeur FFF0h dans le premier segment, on observe le code (que je cible précisément ici) et on rectifie avec la valeur de mémoire maximale de FEF0h comme sous DOS 3 et plus :
16 avril 2017 (Pâques) J'ai configuré DOS Plus 1.2 en français pour constater que cela ne décalait pas le code ci-dessus. Sa gestion d'erreur critique est comme sous DOS 3+ bien qu'il soit un CP/M-86 compatible DOS 2 (au niveau des fonctions documentées). On peut dire que MS-BASIC fonctionne maintenant avec toute version de MS-DOS (sauf avec la FAT32 en mode MS-DOS sous Windows 9x ou avec les FCB de Windows Me), de PC-DOS, de DR DOS (plus le PAT312 pour la version 6) ainsi qu'avec DOS Plus (si corrigé pour que la création de PSP se fasse comme sous DOS3+) et Windows XP 32 bits. Il faut juste veiller que le DOS soit chargé en HMA si la ligne A20 est activée afin de garder la compatibilité CP/M (CALL 5). Fin du premier chapitre. 31 mai 2017 Un exemple d'annulation de la scrutation, longue en traitement, des commandes Ctrl-C et Ctrl-S par le BASIC :
Revenant au shell du tout début, il va de soi qu'il n'est pas fait pour être compatible avec DOS Plus. En effet, cet OS sait lancer les fichiers CMD. De toute façon, il n'inscrit pas de saut à l'adresse 0:000Ch, ce qu'on font les véritables DOS en gâchant les interruptions 30h et 31h. Mercredi 21 juin 2017 Il est intéressant de constater que l'initialisation de GW-BASIC est très fortement inspirée de ses ancêtres. Parfois, il s'en sort mieux pour éviter les problèmes du pile trop petite. Le code de la version CP/M aurait pu facilement imposer une pile minimale de 256 octets au lancement du BASIC, à l'instar de la pile maximale qu'il fixait à 512 octets. Il est tellement simple de vérifier s'il y a 256 octets disponibles via la condition du poids fort. |
| Auteur : | gm86 [ 05 janv. 2021 22:18 ] |
| Sujet du message : | Re: Apprentissage du BASIC Microsoft sous DOS |
| Le message précédent, se rapportant essentiellement à la version MS-DOS de BASIC, approchait les 90.000 caractères. C'était un fourre-tout de ce que j'avais découvert plus ou moins volontairement dans les méandres du DOS et du CP/M au fil des ans. Place à la version pour CP/M-86, très proche de la version CP/M ! Mardi 3 juillet 2017 Aujourd'hui, j'ai rapidement étudié les codes d'erreur des fonctions traditionnelles du CP/M-86. Comme sous DOS, AH vaut généralement FFh si une telle fonction échoue. Cependant, l'écriture d'un enregistrement RANDOM (FCT22h) en comporte d'autres que le BASIC étudie : les erreurs 1 (disque plein), 3 (problème d'allocation supérieure à 16 Ko) et 5 (répertoire saturé). La dernière n'apparaît pas à ce moment-là sous DOS ; par contre, la première correspond à l'erreur 2 sous DOS. Quant à la restante, spécifique à CP/M, elle provoque le branchement à l'offset 0798h (Disk I/O Error). Mercredi 4 juillet 2017 Revenant à la fonction 22h, elle comporte deux types seulement d'erreur sous DOS : - AH=1, disque plein ; - AH=2, débordement de segment (DTA insuffisante en fin de segment). Ils seront incrémentés si rencontrés pour correspondre aux erreurs Disk full et Disk I/O Error (Cannot close current extent). On imitera le comportement de CP/M-86 lorsqu'il charge un programme avec un en-tête de modèle small (un segment de code et un segment de données), sans plus. Ce patch, remplaçant l'en-tête du fichier CMD pour en faire un fichier COM, doit être générique. On supposera qu'aucun appel à une fonction spécifique au CP/M-86 existe. CALL 5 fait la vérification mais il est incompatible avec une HMA active lorsque le DOS est en mémoire basse. Mercredi 5 juillet 2017 Comment CP/M-86 charge-t-il MBASIC.CMD ? Il lit l'en-tête de 128 octets :
CP/M-86 lui crée une page zéro de 256 octets (appelée PSP sous DOS). Elle débute après la longueur de code indiquée, alors que le modèle 8080 la place au début du segment unique. Il y fait pointer DS ainsi que ES, vu qu'il n'y a aucun segment extra (type 4). Ensuite, il renseigne certains champs :
Nous remarquons que le mot à l'offset 6, ainsi que les 2 FCB et la DTA sont communs à CP/M et DOS. À présent, CP/M-86 peut donner la main au segment de code. Jeudi 6 juillet 2017 Voici le fichier source PATCH.ASM de l'en-tête DOS destiné à MBASIC.CMD (BASIC Microsoft pour CP/M-86) : Lundi 10 juillet 2017 Mise à jour pour prendre en compte l'écriture séquentielle, même si c'est encore moins indispensable vu la faible différence en MS-DOS et CP/M-86 sur ce point (erreur 1 : disc full au lieu de directory full). Le code occupe exactement les 80 octets de l'ancien en-tête ! La préservation de l'interruption E0h est-elle utile (je pense à DOS Plus) ? Jeudi 13 juillet 2017 À la lecture de la section 2.7 du CP/M-86 System Guide, je constate que l'adresse complète de terminaison du programme est laissée sur la pile du CCP (à l'instar de CP/M qui laisse un mot nul sur la pile). S'il ne redéfinie pas sa pile, le programme peut donc finir via l'instruction RETF. Cela mérite une nouvelle mise à jour. Vendredi 14 juillet 2017 (fête nationale) Le fichier source est complété d'autres commentaires. En testant le BASIC pour CP/M-86 d'origine, j'ai remarqué que DOS Plus le stoppait si un mauvais lecteur était indiqué devant le nom du programme BASIC. S'il s'agissait du BASIC pour MS-DOS, DOS Plus l'aurait laissé traiter ce problème ; par contre, il aurait dû le lui signaler via le registre AX (AL=FFh si la lettre du FCB1 est invalide). Mardi 25 juillet 2017 Le calcul de la mémoire disponible pour les données est plus sûr à présent, car sans risque de débordement. Jeudi 27 juillet 2017 Un oubli honteux ou comment inventer un code d'erreur pour une opération réussie. Tout est dans le titre : DOS risque de tromper un programme CP/M-86 en lui renvoyant un code d'erreur non nul. DOS connaît la taille exacte de chaque fichier grâce à la FAT. Par compatibilité CP/M, les fonctions FCB manipulent des blocs de 128 octets ; c'est pourquoi, un caractère EOF (^Z) marque souvent la fin réelle d'un fichier. D'ailleurs, DOS renvoie le code 3 pour prévenir que le dernier bloc lu d'un fichier a dû être comblé par des zéros. À l'inverse, DOS Plus renverrait un code nul s'il s'agissait d'un appel CP/M-86. Dimanche 7 janvier 2018 J'avais gardé pendant si longtemps un lien sans le consulter. Il s'agit d'un site formidable, heureusement archivé, sur le désassemblage du Microsoft BASIC de l'Altair : http://web.archive.org/web/200112121132 ... _dis_1.htm Je pointe sur cette page précisément car [j'avais pensé à mal]. Ce qui m'avait semblé être une pratique anti-DEBUG dans le BASIC n'était en fait que la [transcription en CALL (3 octets)] d'une merveilleuse [interruption] de vérification de syntaxe du BASIC de ROM. Pour la décrire brièvement, il s'agissait d'une [routine] appelée via une instruction sur un octet (RST 1) comparant l'octet lu avec l'octet suivant l'appel, incrémentant et échangeant avec la pile via l'instruction spécifique XTHL. Au passage, dans le MS-BASIC 5.28, j'aurais mieux fait de mettre à zéro le mot [372h] au lieu du seul octet [373h]. Car en plus de vider le tampon ligne, j'évite son débordement (tampon à la suite d'une improbable ribambelle d'espaces). De plus, le désassemblage du BASIC de l'Altair m'a confirmé le fait qu'il y avait bien une vérification de pile au démarrage pour le BASIC Microsoft (CheckEnoughMem) : http://web.archive.org/web/200112121104 ... _dis_2.htm Il ne résout pas le problème en cas d'absence quasi-totale d'octets de libre mais il confirme un de mes essais de correction du MS-BASIC 5.28 via DEBUG :
Parenthèse sur le chapitre précédent (que j'ai épuré). Si la pile est non nulle, elle peut se permettre de déborder de sept fois sa taille (vu qu'elle représente au moins le huitième de la mémoire libre). La procédure vérifiant sa suffisance (à l'offset 2F0Bh) peut se contenter de huit octets. De même, il serait bien [pour elle de faire débuter la mémoire libre par un mot nul]. Jeudi 18 janvier 2018 Voici une page de liens actuels sur le code source de l'Altair : http://groups.google.com/forum/m/#!topi ... rUH5Doy1es Le fichier MAC de la version 8K en plus du désassemblage, cité plus haut, de la version 4K ! Vendredi 2 février 2018 Hier, je me suis rendu compte que FILES de MS-BASIC 5.28 considérait la lettre Z de lecteur comme une erreur. Le bug se trouve dans le code ci-dessus :
Par contre, il faut remettre 'Z'+1 à la place de 'Z'. De plus, une procédure convertissant les minuscules en majuscules avait été ajoutée exprès (JA est une instruction sans équivalent direct 8080). Or elle est redondante à celle-ci :
À propos de FILES sous cette version de BASIC, le paramètre "." [se base sur le nom d'un] précédent appel [de fichier]. Néanmoins, le masque du fichier n'est pas initialisé à zéro comme le numéro de lecteur au démarrage. Mercredi 7 février 2018 Nous retiendrons que les défaillances de DEF USR et FILES"Z:" étaient dues à de malheureuses modifications par le personnel de Microsoft. Pour le reste, l'usage du DOS non documenté a démontré ses limites quant au futur des applications alors qu'un retour au code de l'Altair a permis de corriger élégamment celui issu de CP/M. Dimanche 11 février 2018 Rédaction en cours d'une petite documentation technique : Mardi 27 février 2018 Mise à jour du fait que le sommet de pile (mot en DS:487h) pointe en fait le dernier octet de mémoire libre (au moins, dans les versions MS-DOS). D'ailleurs, la routine en 2F0Bh peut imposer une pile avec un mot de plus que prévu sans contrarier l'instruction CLEAR en mode direct (tapée sans numéro de ligne). Dimanche 4 mars 2018 Pluie : j'en profite pour résoudre un bug dû, de manière inattendue, au fait que la longueur d'un nom de variable n'était vérifiée qu'une fois que celui-ci était mis en forme dans son tampon. [J'avais chargé un programme BASIC au format ASCII comportant une longue ligne sans caractère séparateur, ce qui écrasa les numéros de fonction de lecture/écriture aléatoire] Vendredi 9 mars 2018 Mise à jour grâce au code source du BASIC Microsoft 5.x pour CP/M disponible depuis l'été dernier : http://winworldpc.com/product/microsoft-basic/80 Samedi 24 mars 2018 Pour rappel, le compilateur DOS correspondant est numéroté 5.36, et sa fonction VARPTR(#n) renvoie l'adresse du FCB (comme sous GW-BASIC et non de la DTA). Samedi 15 décembre 2018 Selon le code source, la commande H de l'éditeur orienté ligne signifie Hack. J'avais donné un sens plus proche du monde fruitier (équeuter une cerise) : viewtopic.php?p=95496#p95496 Vendredi 6 septembre 2019 Ce sujet oublié est amené à être clos. J'ai ma petite idée pour distinguer discrètement le nouveau (C) par Micro$oft. L'archive comprendra le patch avec le MASM 2 corrigé d'IBM. Cela signifie que je ne suis pas tombé sur d'autre problème majeur. Jeudi 9 janvier 2020 Il existait deux modes de diffusion des programmes commerciaux, les versions compilées pour CP/M ou MS-DOS et les versions interprétées protégées. Ces dernières gardaient leur code à l'abri de l'utilisateur. Mais que ce passe-t-il si le code en clair est perdu ? Nos yeux pour pleurer ? Non, un petit logiciel de décryptage ou DEBUG encore. Le premier diffère selon qu'il s'agisse de MBASIC ou GW-BASIC, mais le chiffrement est tout aussi faible : genre double XOR, on est loin du cryptage quantique ! Le second utilitaire évite de casser le code car on y charge le BASIC qui décode tout bonnement en mémoire vive. La troisième solution vient de l'exploitation ingénieuse d'un bug. La personne à l'origine de cela est tout aussi ingénieuse : http://www.chebucto.ns.ca/~af380/GW-BAS ... s.html#tur C'est très simple de l'adapter depuis sa version GW-BASIC à notre BASIC Microsoft : - remplacer 97 de DEF par 98 ; - remplacer 98 de POKE par 99 ; - remplacer 1450 par 1510. Comme il le montre, connaître l'octet incriminé est un jeu d'enfant. Par contre, autour de 1000, on risque d'activer une erreur autre que Illegal function call. Dans notre cas, le désassemblage indique que l'octet 1510 est le premier initialisé. Ensuite, un copier-coller est facile sous Windows ou TaskMAX de DR DOS. Dans les autres cas, il faudra truander pour ne pas tout retaper. Et pour cela nous avons MERGE et une particularité de l'interpréteur. MERGE charge en mémoire un programme sans effacer l'ancien. Or nous, nous souhaitons exécuter nos ordres directement, donc sans numéro de ligne. BASIC ne signalera pas l'erreur si tout tient sur une ligne ; par contre, notre vieille version est obligée d'attendre l'utilisateur pour analyser : - supprimer tous les commentaires du bloc sous load"secret.bas" ; - réunir en une ligne unique en intercalant un double-point à chaque jonction ; - enregistrer cette LIGNE unique dans un fichier BAS sans retour à la ligne. Déroulement de la procédure : - SAVE"PRGM",P ; - LOAD"PRGM" ; - LIST échoue ; - MERGE"LIGNE" ; - touche ENTRÉE pour obtenir un second Ok ; - ?val(b$)456 qui provoque le BREAK salvateur ; - LIST fonctionne à nouveau. Samedi 11 janvier 2020 Une astuce pour obliger l'utilisateur à appuyer sur Entrée est que la ligne soit déjà pleine (255 octets). De même, il est sage qu'un caractère EOF (ASCII 26) la suive dans le fichier ; cela évite le malheureux message Direct statement in file dû à un éventuel retour à la ligne. CLEAR nous permet d'avoir un tableau à onze valeurs nulles par défaut. Ainsi, nous sommes sûr d'avoir au moins un octet nul de début de ligne BASIC et trois octets nuls de fin de programme. À présent, nous avons tout ce qu'il faut pour obtenir notre fichier PROFLG.BAS : 20 janvier 2020 Vous trouvez complexe la méthode précédente. Il en existe une bien plus simple à comprendre sous DOS. Il s'agit de la seconde exposée ici : http://www.petesqbsite.com/sections/zin ... s2-gwbasic Il suffit de charger un moignon de programme BASIC, au format token non protégé, par-dessus celui en mémoire. Lors d'un chargement, BASIC effectue d'abord une commande NEW, annulant par un mot nul l'offset pointant la deuxième ligne. Ensuite, il lit la valeur purement indicative de l'offset du nouveau programme et, si elle n'est pas nulle (fin de programme), la recalcule pour la configuration courante de la mémoire. Notre programme créé par DEBUG comportera donc l'octet descripteur 255 (tokens non cryptés) et un octet non nul :
Cette méthode ne fonctionne pas sous CP/M car cet OS ne connaît la taille des fichiers qu'en groupe de 128 octets, et le caractère EOF ne sert que dans les fichiers ASCII. Par exemple sous CP/M-86, il faut revenir à la méthode précédente avec 1395 au lieu de 1510. 24 mai 2020 Le code source du GW-BASIC (1983) est à présent disponible ici (code 8 bits traduit en 16 plus macro INS86) : https://github.com/microsoft/GW-BASIC/a ... master.zip 31 mai 2020 Le début du fichier PATCH.ASM apporte une nouvelle façon de corriger le problème suivant. MBASIC n'épargne pas d'un débordement le tampon NAMBUF (nom de variable de plus de 40 caractères). Voyons cet extrait du fichier GWDATA.ASM (GW-BASIC) :
2 juin 2020 J'en profite que le sujet a été remonté pour ajouter de la documentation au fichier PATCH.ASM (cf. le 7 février 2018). Les commentaires indiquent la structure des FBD (File Block Data) du BASIC-86 pour MS-DOS. Elle est très proche de celle du BASIC-80 pour CP/M ; seule la taille du FCB (File Control Block) diffère. Contrairement à GW-BASIC et au compilateur BASCOM, VARPTR(#n°fichier) ne pointe pas le FCB mais : - le tampon DTA (Disk Transfer Area) en mode d'accès séquentiel (INPUT, OUTPUT, APPEND) ; - le tampon FIELD en mode d'accès direct (RANDOM). La DTA était nommée DMA (Direct Memory Access) sous CP/M. Quant au mode d'accès, sa numérotation diffère sous GW-BASIC. Mardi 6 octobre 2020 Le bug analysé le 6/5/2016 s'explique par une mauvaise utilisation de la macro INS86 (OEM.H), dont le but est d'insérer des opcodes 8086 dans le code 8080 à convertir : INS86 203,372,65535D.
Je suis satisfait du patch peaufiné grâce au code source de GW-BASIC. D'ailleurs, on trouve dans ce dernier la correction de la fonction de partie entière--cf. plus haut, INT(-0#) ou FIX (-0!) donnant -1 dans la révision 5.27. Elle agit sur les routines $INT et $DINT dans la seconde partie du fichier mathématique (les commentaires ne sont pas en capitales) : https://github.com/microsoft/GW-BASIC/b ... /MATH2.ASM Vendredi 6 novembre 2020 Microsoft avait reconnu le bug de RESUME NEXT avec le compilateur BASIC pour MS-DOS (Q21323, RESUME NEXT enchaînant sur ELSE) : https://www.pcorner.com/list/OS2/BUG110.ZIP/INFO/ Cependant, les interpréteurs BASIC Microsoft ont tous un problème analogue. Si une erreur se produit juste après ELSE, RESUME NEXT enchaîne après l'instruction qui suit THEN (BLUE - BASIC Language User Essay, chapitre 9, p.142) : http://read.pudn.com/downloads173/ebook ... lueBas.pdf Ouvrage qu'on retrouve ici, accompagné d'astuces et programmes : http://www.antonis.de/qbebooks/index.htm#englische Dimanche 15 novembre 2020 Un bug se trouve à l'étiquette SIN30 des routines trigonométriques du premier GW-BASIC : https://github.com/microsoft/GW-BASIC/b ... /MATH2.ASM L'information vient du lien suivant : https://www.os2museum.com/wp/well-hello/ On retrouve cette erreur dans BASIC-86 5.27 (offset 4C96h) alors qu'elle est absente de la version 5.28 (offset 4D80h). Pour que la longueur de la partie "initialisation" puisse varier, voici depuis le 21 juin de nouveaux fichiers (dernière mise-à-jour le 12/2/2021). Aparté sur le compilateur 5.36 : les exécutables non autonomes produits par le compilateur nécessitent BASRUN.EXE (run-time). Ils sont plus petits mais il y a un risque que ce dernier soit directement exécuté par un curieux. D'autres versions afficheraient un message avant de quitter, celle-ci planterait aussitôt. Pour éviter cela, on peut rendre BASRUN.EXE fictivement gourmand en mémoire par l'intermédiaire d'une astuce rencontrée dans les exécutables au format NE : http://www.os2museum.com/wp/multitaskin ... ent-117516 Il s'agit de rendre la valeur MINALLOC de l'en-tête MZ prohibitive (nombre minimal de paragraphes requis impossible à satisfaire). Cela est sans conséquence pour le programme BASIC nécessitant son chargement. En outre, la somme de contrôle est déjà incorrect (mot 7C22h à l'offset 12h au lieu de 7C20h). Le lendemain L'astuce ne fonctionne qu'à partir de DOS 2. Avec DOS 1, le code chargeant les exécutables se trouve dans COMMAND.COM comme sous PC-DOS 2. Mais l'en-tête considéré est très simplifié (entre crochets ce qui est ignoré) :
Le surlendemain Patch contre l'exécution en invite de commande de BASRUN.EXE :
Pas de souci pour tout programme BASIC nécessitant ce fichier RUN-TIME. Preuve à l'appui avec l'utilitaire SID de DR DOS : http://www.delorie.com/djgpp/doc/rbinter/it/94/15.html Mercredi 16 décembre 2020 Une réédition d'un bon ouvrage sur la compilation BASIC (plus les fichiers de la disquette du livre original) : http://ethanwiner.com/BTU_BOOK.PDF http://ethanwiner.com/BTU_DISK.ZIP Sont relatées les optimisations, l'arithmétique pas forcément signée (sauf option /d du compilateur), etc. Samedi 2 janvier 2021 Le compilateur BASCOM peut planter à cause de sa programmation non structurée. Lorsqu'il rencontre une instruction FOR, il commence la vérification par la dernière limite puis le pas (BC.EXE de QuickBASIC effectuerait l'opération en même temps). Supposant que l'indice soit entier, une première limite non comprise dans [-32768,32767] alors que le restant est correcte provoquera un message pointant la fin de ligne :
Moins grave est la mauvaise conversion des tabulations en espaces lors du listing. La logique lors de la rencontre d'une tabulation est (position+7)/8 :
Surlendemain du nouvel an Le compilateur 5.36 pouvait être livré pour l'ACT Apricot. On reconnaît le disque à la présence de fichiers GSX*.* et au fait que BASRUN.EXE n'est plus de l'année 1983 (version 5.35). La vieille version de LINK incluse peut créer des EXE défectueux. Prenons les programmes de test des patches 3 et 4 pour IBM 1.0 et compilons-les avec l'option /O (autonome) : http://ftpmirror.your.org/pub/misc/dos/ ... ASCOM1.TXT Après liage, analysons le nombre d'octets de la dernière page dans l'en-tête EXE : 146h au lieu de 140h pour le test 4, mais surtout 6 au lieu de 0 pour le test 3. Or 0 équivalant à 512 octets, le nombre de pages indiqué a dû être incrémenté. D'où le message du DOS qui constate que la dernière page n'existe pas : Erreur dans le fichier EXE (Error in EXE file)). La solution est d'utiliser la version 2.45 pour DOS 1 (LINK.V1 du Pascal Microsoft 3.2). Mardi 5 janvier 2021 Le chargeur EXE de BASIC 5.36 est défectueux (cf. déroulement de SID plus haut). Il ne sait pas que zéro octet dans la dernière page est en fait un reste de division signifiant 512, c'est-à-dire, le modulo 512 de la taille du fichier exécutable. D'où la nécessité de modifier les deux bibliothèques fournies. Les bibliothèques IBM 2.00 corrigeait le problème de façon plus classique (instruction CMP) :
TailleEXE = Word[4]*512 - (-Word[2] AND 511) en octets. Le surlendemain Merci Big Monstro de la remontée. J'ai consacré du temps pour apporter de la stabilité à ces vieux logiciels Microsoft. Après test, j'ai vu que le chargeur EXE de BASRUN.LIB ne sert qu'à charger BASRUN.EXE ! C'est ce dernier qui recopie l'exécutable appelé par CHAIN ou RUN. Donc, modification de cette run-time, calcul du nouveau et inutilisé checksum (imite LINK) puis modification décrite précédement ; BASRUN.EXE ne devant pas être lancé depuis l'invite de commande. Dimanche 17 janvier 2021 Désirez-vous tester la démo GSX du compilateur 5.36 qui se trouve sur la disquette d'Apricot ? http://actapricot.org/disks/aprid5ks.htm#apr00036.dsk Il faudra se munir des gestionnaires GSX accompagnés des sources pour DOS, de leur documentation, des outils de DRI pour assembler ces derniers et d'un assembleur Microsoft : http://www.seasip.info/Cpm/software/gsx86.html http://www.bitsavers.org/pdf/digitalRes ... _Jul83.pdf http://www.retroarchive.org/cpm/lang/TOOLS86.ZIP http://actapricot.org/disks/aprid5ks.htm#apr00191.dsk Une précision sur les routines assembleur. Il reste une alternative à CALL : la fonction USR. Contrairement à l'interpréteur, son argument est ignoré et son résultat un entier. De ce fait, la valeur renvoyée l'est directement par le registre BX qui contient au départ l'adresse de la routine. De plus, si on insère USRx(arg) dans une formule dont les opérandes viennent d'être utilisés, le compilateur aura gardé les valeurs dans DX, CX puis AX avant d'user de la pile via BP. C'est pourquoi il est préférable que la routine sauve tous les registres sauf ES et, bien sûr, FLAGS. Enfin, CALL de l'interpréteur devient CALL ABSOLUTE et, contrairement au compilateur IBM, l'emploi de BLOAD n'est plus possible. Dimanche 31 janvier 2021 Le compilateur produit le même bug que l'interpréteur à propos de FILES : la lettre Z n'est pas reconnue (cf. note du 2 février 2018). BASRUN.EXE et BASCOM.LIB sont à modifier en conséquence. viewtopic.php?f=2&t=6868 Vendredi 12 février 2021 Il faut penser au futur. MSBASIC accepte les années 78 à 99 (XXème siècle) et 00 à 77 (XXIème siècle). La plupart des machines refusant 1978 et 1979, la fonction DOS correspondante renverra une erreur. À l'instar de GW-BASIC, le compilateur accepte aussi les années 2078 à 2099. Il suffit de le vérifier au label DATE2 du fichier GWSTS.ASM :
Or nous avons DATE2: CMP AX,2078D dans l'interpréteur pour MS-DOS. Nous devons donc modifier l'octet à l'offset 4296h dans le fichier PATCH (voir plus haut). Samedi 20 février 2021 Le compilateur MS-DOS, à l'inverse de la version IBM 1.0, risque de planter lorsqu'il rencontre un fichier dit binaire alors qu'une disquette est présente dans le lecteur B:. En effet, sachant qu'il n'y a aucun enregistrement à écrire, il saute le changement de DTA et l'écriture d'enregistrements consécutifs. Or, c'est lors de cette dernière opération que le FCB à fermer est pointé. Vu que le guide Peter Norton explique qu'un nombre d'enregistrement nul est accepté, on raccourcit ce saut (JCXZ) pour corriger le problème. De même, les caractères en ASCII étendu placés ailleurs que dans les chaînes posent problème. Alors que l'inspection des caractères ASCII 7 bits ne comporte qu'une entrée dans la version IBM 2.0 (CS:531Ch) pour deux appels différents, il existe une entrée pour la vérification d'initiale après le signe égal et une autre avant pour le message d'erreur mais qui annule le bit de poids fort. Cette dernière risque donc de planter l'affichage de ^SN voire du message ^UC qui est incorrecte. Si on inverse l'attribution des entrées, le souci disparaît. Procédure de correction : Mise à jour du complément à un des sommes de contrôle des bibliothèques. Ici, il s'agit du dernier octet des enregistrements A0h qui ont été modifiés. |
| Page 1 sur 1 | Fuseau horaire sur UTC+02:00 |
| Développé par phpBB® Forum Software © phpBB Limited Traduction française officielle © Qiaeru |
|