LEX 'BASICLEX' * (c) Copyright PPC Paris 1986 ID #E1 MSG 0 POLL 0 t EQU 90 ENTRY BLSTs CHAR #D ENTRY PBLSTs CHAR #D ENTRY RENUMe CHAR #D KEY 'BLIST' TOKEN t KEY 'PBLIST' TOKEN 1+t KEY 'RENUMREM' TOKEN 2+t colprt EQU 19 indentation de PBLIST len"= EQU 62 ARGERR EQU #0BF19 BASCHA EQU #07741 BASCHK EQU #0773E BSERR EQU #0939A CK"ON" EQU #076AD CKINFO EQU #18542 COMCK EQU #036CD CPL#10 EQU #07887 CSLW5 EQU #0ED3D CSRW5 EQU #0ED2C CURREN EQU #2F56C CURRL EQU #2F7E8 CURRST EQU #2F55D D0=PCA EQU #09B37 DISPt EQU #00000 EOLCK EQU #02A7E EOLXCK EQU #05405 FINDF+ EQU #09F63 FINDL EQU #0FFE4 FINDL0 EQU #0FFFD FSPECe EQU #02F02 FSPECp EQU #03CC5 FSPECx EQU #09F2D FUNCR0 EQU #2F89B GETPR1 EQU #06BFB GETPRO EQU #06BEE GETSTC EQU #07726 IVPARe EQU #02E3F LDCM10 EQU #04F6F LDCSPC EQU #2F6C1 LISTDC EQU #05839 MFERR EQU #09393 MLFFLG EQU #2F870 NTOKNL EQU #048E6 NXTSTM EQU #08A48 OUT3TK EQU #02D15 OUTBS EQU #2F58F PCADDR EQU #2F679 POLL EQU #12337 PRINTt EQU #00001 PRPSND EQU #06B17 PRSC00 EQU #07B93 RENSUB EQU #1A753 RESPTR EQU #03172 S-R0-2 EQU #2F87B S-R1-1 EQU #2F886 SEND20 EQU #17DFA SENDEL EQU #17DC1 SENDWD EQU #17E15 STMTD1 EQU #2F896 STMTR0 EQU #2F871 STSAVE EQU #2F6BE eFACCS EQU #0003C ILLEGAL ACCESS eFSPEC EQU #0003A INVALID FILESPC eSTMNF EQU #0001E STATMENT NOT FOUND fBASIC EQU #0E214 lEOL EQU #00002 oBSsod EQU #00011 oFLENh EQU #00020 oFLSTr EQU #00031 oFTYPh EQU #00010 pLIST EQU #0000C t! EQU #000FC tCOMMA EQU #000F1 tDATA EQU #000C6 tDEF EQU #000B9 tEND EQU #000DA tENDDF EQU #000BA tENDSB EQU #000C2 tLBLST EQU #000F6 tLINE# EQU #0000F tREM EQU #000E6 tSUB EQU #000C1 ENDTXT STITLE Listing StructurÅ ************************************************* ************************************************* * Nom : BLIST / PBLIST ; Type : Statment * * But : Lister un programme BASIC au format de * JPCLISTE, c.È.d. en sautant une ligne / * tracant des "=" avant chaque label, * SUB, DEF FN, DATA ... ou aprÉs chaque * END DEF, END SUB, END ALL. Ces derniers * seront pris en compte quelle que soit * leur position sur la ligne. * * Syntaxe: identique È LIST * * BLIST [] [,dÅbut [,fin]] * * EntrÅe : * P= 0 * D0 past tBLIST * * UtilisÅ : * R0-R3,S0-S11,STMTR0,STMTR1,STSAVE,FUNCR0, * FUNCR1 + tous les registres. * * Stack levels : 8 * * Auteur : Jean-Pierre BONDU 05/86 ************************************************* ************************************************* REL(5) BLSTDC REL(5) BLSTP PBLSTs LC(2) (PRINTt)*16+#F A=0 X lÉve 'notre' S0 A=A+1 X * GONC LIST05 B.E.T. REL(5) BLSTDC REL(5) BLSTP BLSTs LC(2) (DISPt)*16+#F A=0 X baisse 'notre' S0 LIST05 D1=(5) MLFFLG DAT1=C B D1=D1+ 11 D1 @ S-R0-2 DAT1=A X sauve nos drapeaux D1=(4) CURRST C=DAT1 A D1=C D1 @ DÅbut fichier A=DAT0 B GOSBVL EOLXCK paramÉtres suivent ? GOC LIST50 non LC(2) tCOMMA ?A=C B GOYES LIST50 LIST10 GOSBVL FSPECx spÅcificateur valide ? GOC bserr non LIST20 GOSBVL FINDF+ cherche le fichier GOC LSTEXT pas trouvÅ ? LIST50 D1=D1+ (oFTYPh)-1 A=DAT1 A FILE TYPE ASR A D1=D1- (oFTYPh)-1 GOSBVL BASCHA BASIC FILE ? GOC bserr no GOSUB PARMXQ LIST60 GOSBVL GETPR1 TEST FILE PROTECTION GOC bserr "File Protect" LIST65 D1=D1+ (oFLENh)-(oFTYPh) A=DAT1 A GOSUB GETST1 C=D A D1=(5) S-R1-1 DAT1=C A GOSUB LNARGS D0=(5) S-R0-2 C=DAT0 X D0=(4) STSAVE DAT0=C X GOC LIST76 Cy vient de LNARGS GOTO LIST80 bserr GOVLNG BSERR LSTEXT ?ST=1 6 GOYES bserr GOSBVL POLL CON(2) pLIST pPOLL2 GOC bserr Handled and errored ? ?XM=0 Handled Okay ? GOYES Nxtstm * Not handled - Give correct error D=D+1 S D=D+D S external device GOC fspcer ?A=0 W No file name specified ? GOYES fspcer LC(2) eFACCS Mferr GOTO mferr fspcer LC(2) eFSPEC GOC Mferr B.E.T. Nxtstm GOTO nxtstm GETST1 CD1EX D0=C C=C+A A D=C A D0=D0+ (oBSsod)-(lEOL) GOVLNG BASCHK * * D1 @ Line To Print * LIST76 GOSUB ST<>RM rÅtablit 'nos' drapeaux ST=0 3 baisse Multi line FN flag JPL05 GOSUB READtk A[B]= token * * Traduit Ligne 2010 * LC(2) tDATA ?A=C B DATA ? GOYES JPL10 oui ST=0 7 GONC JPL20 B.E.T. * * Traite une ligne de DATA * JPL10 ST=1 9 ?ST=0 7 GOYES dat1 dat1 ST=1 7 GONC JPL20 7 Åtait levÅ ?ST#0 6 GOYES JPL20 6 Åtait levÅ ST=1 8 * * Traduit Ligne 2020 * JPL20 ?ST=0 9 GOYES JPL22 9 est baissÅ ?ST#0 7 GOYES JPL22 7 est levÅ ST=1 8 * Ajuste S9 sur S7 JPL22 ST=0 9 ?ST=0 7 GOYES JPL30 on ne change rien ST=1 9 * * Traduit Ligne 2030 * JPL30 LC(2) tLBLST ?A#C B GOYES JPL32 ST=1 6 ST=1 8 GONC JPL40 B.E.T. JPL32 ST=0 6 LC(2) tDEF ?A#C B GOYES JPL40 * * Une User FN est tokenisÅe comme suit : * tDEF <5 nibbles field> tFN tVAR ... * tFN = 00 => FN multiligne * Il faut que DEF FN, SUB, LABEL, DATA soient en * dÅbut de ligne par contre END DEF, END SUB, END * ALL sont repÅrÅs quelle que soit leur position. * Cette recherche est assurÅe par SRCtk. * ST=1 8 ST=0 3 Multi line FN flag * S3 = 1 : FN monoligne (DEF FNx(..)= ...) * S3 = 0 : FN multiligne (DEF FNx(..) @ ...) D1=D1+ 13 D1 @ tFN C=DAT1 B D1=D1- 13 ?C=0 B FN multiligne ? GOYES JPL40 ST=1 3 FN monoligne * Il reste È vÅrifier que la FN n'est pas une * 'fausse' monoligne (i.e. qu'un END DEF n'est * pas sur la mÁme ligne.) Cela sera ÅffectuÅ par * JPL60. * * Traduit Ligne 2040 * JPL40 D0=(5) STMTD1 CD1EX D1 en STMTD1 DAT0=C A CD1EX LC(2) tSUB ?A=C B GOYES PRT"= ?ST=0 8 GOYES JPL50 * * IMPRIME 62 '=' * PRT"= ST=0 8 GOSUB ST<>RM Sauve 'nos' drapeaux GOSBVL CKINFO GOSBVL SENDEL saute une ligne C=0 A GOSUB SENDSP effectue indentation GOSUB D10@BS C=0 A LC(2) len"= B=C B compteur A=C A A[A]= longueur buffer B=B-1 B B[B]= compteur LCASC '=' loop1 DAT0=C B D0=D0+ 2 B=B-1 B GONC loop1 ST=1 4 GOSBVL SENDWD Affiche le buffer de * longueur A[A], D1 @ dÅbut GOSBVL SENDEL SEND End of Line * * Restore D1 en dÅbut de ligne * GOSUB RCALD1 GOSUB ST<>RM rÅtablit 'nos' drapeaux * * Traduit Ligne 2050 * JPL50 ST=0 4 ST=0 2 LC(2) tREM ?A=C B GOYES JPL52 LC(2) t! ?A#C B GOYES JPL55 ST=1 2 JPL52 ST=1 4 signale ligne de REM JPL55 GOSUB ST<>RM sauve 'nos' drapeaux GOSBVL LDCM10 dÅcompile GOSUB SETPOS effectue tabulation GOSUB ST<>RM rÅtablit 'nos' drapeaux GOSUB D10@BS D1 @ ligne dÅcompilÅe * Maintenant il faut modifier le No de ligne * si c'est une ligne de REM. ?ST=0 4 ligne REM ? GOYES JPL60 non * ================================================ * FORMATE UNE LIGNE DE REM : * - Remplace le No de ligne par des espaces * - Supprime le symbole "!" * - Rajoute '-' si 1er ligne de REM * EntrÅe: * D1 & D0 @ dÅbut No ligne (OUTBS) * B[A] = longueur ligne en octets * ( NE PAS Y TOUCHER ! ) * S5=0 => 1er ligne de REM * S4=1 => ligne de REMarque * 0 => <> ligne de REMarque * S2=1 => ... de type "! " * 0 => ... de type "REM " * ================================================ LCASC ' ' loop3 A=DAT0 B A[B]=chifrre du No ligne ?A=C B fin No ligne ? GOYES JPL57 oui DAT0=C B efface chiffre D0=D0+ 2 GONC loop3 B.E.T. * * Traduit ligne 2140 * JPL57 D0=D0+ 2 D0 @ "! " ou "REM " A=0 W P= 7 DAT0=A 4 efface "! " (ou "RE") ?ST=1 2 commence par "! " ? GOYES suit DAT0=A WP efface "REM " suit P= 0 D0=D0- 4 D0 @ fin No ligne ?ST=0 5 1er ligne REM ? GOYES JPL58 oui: Carry Set JPL58 ST=1 5 GONC JPL59 <> 1er ligne REM D0=D0+ 8 AD0EX D0=A D0=D0- 8 CD1EX A=A-C A longeur du No de ligne ASRB en octets. ?B<=A A ligne de REM vide ? GOYES JPL59 LCASC '-' DAT0=C B JPL59 GOTO Next * * Imprime une ligne <> REM * Traduit ligne 2060 * JPL60 ST=0 5 GOSUB RCALD1 ?ST=1 3 1 line User FN ? GOYES JPL62 LC(2) tEND ?A=C B GOYES JPL62 LC(2) tENDDF GOSUB SRCtk GOC JPL62 LC(2) tENDSB GOSUB SRCtk GONC Next JPL62 ST=1 8 Next GOSUB ST<>RM sauve 'nos' drapeaux GOSBVL PRPSND affiche Output Buffer D1=C D1 @ NEXT LINE LIST80 A=0 A A=DAT1 4 READ IN LINE# C=R3 LAST LINE TO DISPLAY ?A>C A DONE LISTING ? GOYES nxtstm * * CHECK FOR ATTN KEY DOWN & ANY SERVICE REQUESTS * CD1EX GOSBVL CK"ON" D1=C GONC nxtstm ATTN KEY DOWN GOTO LIST76 nxtstm GOVLNG NXTSTM ************************************************** * SOUS ROUTINES * ************************************************** LNARGS D0=D0+ (lEOL) -- LiNe ARGumentS -- CD0EX HP71B : #06B62 D1=C A=R1 B=A A A=0 A GOSBVL FINDL0 RTNC ?ST=1 0 GOYES nxtstm ?ST=1 10 GOYES nxtstm RTNCC RCALD1 D1=(5) STMTD1 -- ReCALl D1 -- C=DAT1 A D1=C D1 @ ligne compilÅe READtk D1=D1+ 6 skip over LINE# & tLEN A=DAT1 B A[B]= token du premier mot D1=D1- 6 RTN RETURN Carry Clear * * Echange STSAVE avec STatus * ST<>RM D0=(5) STSAVE -- STatus <> RaM -- C=DAT0 X CSTEX DAT0=C X RTN D10@BS D0=(5) OUTBS C=DAT0 A D0=C D1=C RTN * Sortie: C[A] = D0 = D1 = Output Buffer Start * ================================================ * -> SRCtk <- * Recherche sur une ligne compilÅe un token * * EntrÅe : * P=0 * C[B]= token recherchÅ * SRCtk : D1 @ No ligne * SRCtk+ : D0 @ Stmt lenght * * Sortie : * D1 = D1 en entrÅe * B[A]=B[A] " * CARRY SET => trouvÅ, D0 @ token * CARRY CLR => pas trouvÅ * ================================================ SRCtk CD1EX -- SeaRCh token -- D0=C D0=D0+ 4 CD1EX SRCtk+ BCEX A B[B]= token recherchÅ RSTK=C sauve B[A] dans RSTK cont C=0 A C=DAT0 B D=C A D[A]= longeur du Statment D0=D0+ 2 A=DAT0 B lit token ?A=B B token recherchÅ ? GOYES rtn CD0EX C=C+D A CD0EX D0=D0- 2 D0 @ tEOL ou t@ C=DAT0 B D0=D0+ 2 ?C#0 P Not EOL ? GOYES cont rtn C=RSTK B=C A RTN * ================================================ * -> SETPOS <- * Positionne le curseur oË commmencera * l'impression de la ligne en fonction de * la longueur du No de ligne. * * EntrÅe : = sortie de LDCM10 * (OUTBS) @ DC Line * B[A]= LEN(OUTBS) * STSAVE contient 'nos' drapeaux * * Sortie : = sortie de SENDSP * B[A]= LEN(OUTBS) * POSition du curseur a ÅtÅ Åcrite dans STMTR0. * ================================================ SETPOS GOSUB D10@BS C @ BS D1=(5) LDCSPC A=DAT1 A A @ espace A=A-C A ASRB B A[0]= LEN(#line) octets LC(2) 4 longueur MAX d'1 ligne# C=C-A B offset pour TAB * ================================================ * -> SENDSP <- * Envoie (colprt+offset) espaces au pÅriphÅrique * de sortie (DISPLAY ou PRINTER). * * EntrÅe : * C[B]= offset * B[A]= quelconque * STSAVE contient 'nos' drapeaux * * Sortie : * B[A]= B[A] en entrÅe * ================================================ SENDSP A=C B D1=(5) STSAVE charge 'nos' drapeaux A=DAT1 XS 0 È 3 en A[XS] * S0=0 => offset = 0 (BLIST) * S0=1 => offset = colprt (PBLIST) C=R3 GOSBVL CSLW5 C=B A GOSBVL CSLW5 C=0 A C=C+1 XS A=A&C XS ?A=0 XS S0 baissÅ ? GOYES TAB10 oui LC(2) colprt TAB10 C=0 XS C=C+A B #espaces total È envoyer R3=C GOSBVL CKINFO D1=(5) (STMTR0)+6 C=DAT1 A D1=C C=0 A C=DAT1 B A=R3 B=C A D1=D1+ 2 C=DAT1 B lit WIDTH ?C#0 B GOYES TAB20 C=C+1 XS TAB20 ?AWIDTH ? GOYES TAB30 A=A-C A GONC TAB20 B.E.T. TAB30 A=A-B A R3=A GONC TAB40 A=A+B A R3=A GOSBVL SENDEL TAB40 LCASC ' ' C=8 espaces D1=(5) FUNCR0 DAT1=C W TAB50 LC(5) FUNCR0 D=C A adresse C=0 A LC(1) 8 C=8 A=R3 A=A-C A GOC TAB60 R3=A A=C A GOSBVL SEND20 GOTO TAB50 TAB60 A=A+C A GOSBVL SEND20 C=R3 RESTORE B[A] GOSBVL CSRW5 B=C A GOSBVL CSRW5 R3=C RTN PARMXQ ST=0 9 HP71B : #06B87 C=0 A C=C+1 A R1=C Parm 1 = 00001 par dÅfaut LCHEX 9999 R3=C Parm 2 = 09999 par dÅfaut ST=0 10 PRMXQ0 A=DAT0 B LC(2) tCOMMA ?A#C B pas de paramÉtres ? RTNYES D0=D0+ 1 A=DAT0 A ASR A D0=D0+ 5 R1=A ?ST=1 9 GOYES PRMXQ1 ST=1 10 A=0 A R3=A PRMXQ1 A=DAT0 B ?A#C B RTNYES ST=0 10 D0=D0+ 2 A=DAT0 4 R3=A ?ST=1 9 RTNYES C=R1 ?C>A A parm1 > parm 2 ? GOYES invarg oui RTN invarg GOVLNG ARGERR STITLE RenumÅrotation des Remarques ************************************************* ************************************************* * Nom : RENUMREM ; Type : Statment * * But : RenumÅroter un programme BASIC sans * que les lignes de REM viennent * perturber cette numÅrotation (dans * la mesure du possible). * * Syntaxe: identique È RENUMBER * * Note: RENUMREM 100 , 10 , 200 , 500 * -v- -v- -v- -v- * registres -> R0 R1 @R2 R3 ************************************************* ************************************************* REL(5) RNUMDC REL(5) RNUMP RENUMe CD0EX R0=C GOSUB CHKPSF GOSUB GETSTe GOSBVL PRSC00 REN005 ST=1 1 ST=1 2 GOSBVL RENSUB GOC REN010 D1=(5) PCADDR C=R2 DAT1=C A GOSUB UPDCRL LC(2) eSTMNF "Statement Not Found" GOTO mferr REN010 A=R0 D0=A GOSUB LINE#1 R2=A C=0 A C=C+1 A CSL A R0=C R1=C CSL A CSL A CSL A R3=C GOSUB GETLN# GOC REN100 R0=A GOSUB GETLN# GOC REN100 R1=A GOSUB GETLN# GOC REN100 C=A A AD0EX R2=A GOSBVL FINDL ?ST=0 0 GOYES REN020 GOTO nxtstm REN020 CD1EX CR2EX D0=C GOSUB GETLN# GOC REN100 SETDEC P= 3 A=A+1 WP P= 0 SETHEX GOC REN100 C=A A GOSBVL FINDL A=0 A A=DAT1 4 ?ST=1 0 GOYES REN100 R3=A REN100 GOSUB LINE#1 CD1EX A=R2 ?A=C A GOYES REN105 D0=A D0=D0- 4 GOSBVL CPL#10 C=0 A C=DAT1 4 A=R0 ?A>C A GOYES REN105 GOTO invarg REN105 D1=(5) CURREN C=DAT1 A D=C A C=R2 D1=C C=0 A C=DAT1 4 D0=C C=R0 RSTK=C REN110 C=R2 D1=C A=R1 B=A A REN120 CD1EX ?C>=D A GOYES ren170 D1=C A=0 A A=DAT1 4 C=R3 ?A>=C A GOYES ren170 A=R0 ?A-----non------- * ----------- | * |oui | * ------------ | * |ECRIRE Anc| | * ------------REN145 | * | | * ----------- ---------- * |Anc=Anc+1| |Anc=Nv+1| * ----------- ---------- * | | * --------- | * < Anc>NV ?>--non-- | * --------- | | * |<--------------------- * ----------- | * |Nv=Nv+Inc|REN | * -----------150 | * |<----------- * | * ######### * #REN 155# * ######### FIN ************************************************** ************************************************** * --------------------- * ----- ECRIRE Nv ----- * --------------------- REN140 DAT1=A 4 LINE# = Nv GOSUB READtk A[B]= token LC(2) t! ?A=C B Ligne REM ? GOYES REN145 oui LC(2) tREM ?A=C B Ligne REM ? GOYES REN145 oui A=R0 non: Anc = Nv+1 C=RSTK C=A A SETDEC C=C+1 A RSTK=C GOTO REN150 * --------------------- * ----- ECRIRE Anc ---- * --------------------- REN145 C=RSTK C=Anc DAT1=C 4 Line# = Anc SETDEC C=C+1 A Anc = Anc+1 RSTK=C Sauvegarde Anc * * On est toujours en DEC * A=R0 A=Nv P= 3 ?C<=A WP Anc <= Nv ? GOYES REN155 oui alors FIN * * Entree: A=Nv ; B=Inc ; DEC * REN150 A=A+B A Nv = Nv+Inc R0=A Sauve Nv * * FIN: on remet tout en ordre pour REN160 * REN155 SETHEX P= 0 D1=D1+ 4 D1 @ tLEN C=0 A REN160 C=DAT1 B AD1EX A=A+C A D1=A A=DAT1 B D1=D1+ 2 ?A#0 P GOYES REN160 GOTO REN120 REN170 C=RSTK ST=1 1 ST=0 2 GOSBVL RENSUB GOTO nxtstm GETLN# A=DAT0 B D0=D0+ 2 LC(2) tCOMMA ?A#C B RTNYES A=0 A A=DAT0 4 D0=D0+ 4 RTNCC LINE#1 D1=(5) CURREN C=DAT1 A D=C A D1=D1- 15 A=DAT1 A C=0 A LC(2) oFLSTr A=A+C A D1=A RTN CHKPSF GOSUB GETSTe GOSBVL GETPRO GOC mferr ?SB=0 RTNYES GONC mferr GETSTe GOSBVL GETSTC RTNNC mferr GOVLNG MFERR UPDCRL D1=(5) CURRST C=DAT1 A D1=C D1=D1+ (oFTYPh)-1 A=DAT1 A ASR A LC(5) fBASIC ?A#C A GOYES UPDCR1 GOSBVL D0=PCA GOSBVL CPL#10 C=DAT1 A GONC UPDCR3 UPDCR1 C=0 A UPDCR3 D0=(5) CURRL DAT0=C 4 RTNCC ************************************************** *************** ROUTINES D'ANALYSE *************** ************************************************** * [] [,line#1 [,line#2]] * TrÉs inspirÅ de LISTP (#03B92 / HP71B) BLSTP GOSUB eolck+ GOC NAMEP7 pas de paramÉtre : fin GOSBVL FSPECp spÅcificateur OK ? GONC LSTP12 oui * ILLEGAL FILE SPEC ?ST=0 7 GOYES LSTP20 RNMP65 GOVLNG FSPECe LSTP12 GOSBVL COMCK GOC LSTP20 NAMEP7 GOVLNG RESPTR LSTP20 GOSUB LSTP40 GOSBVL COMCK GONC NAMEP7 ST=1 9 LSTP40 GOSBVL NTOKNL LC(2) tLINE# ?A#C B GOYES LSTPE LC(2) tCOMMA A=C B GOVLNG OUT3TK LSTPE GOVLNG IVPARe INVALID (MISSING PARM) eolck+ GOSBVL EOLCK fin de commande ? RTNC oui : Cy=1 GONC NAMEP7 Cy=0 & RESPTR (B.E.T.) RNUMP GOSUB eolck+ GOC NAMEP7 ST=0 9 GOSUB LSTP20 ?ST=1 9 GOYES LSTP12 LSTPDN RTNCC ************************************************** ************ ROUTINES DE DECOMPILATION *********** ************************************************** RNUMDC BLSTDC GOVLNG LISTDC END