|
DataMuseum.dkPresents historical artifacts from the history of: Bogika Butler |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Bogika Butler Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 19840 (0x4d80) Types: TextFile Names: »EXTBESKR«
└─⟦832e7e234⟧ Bits:30003263 Butler systemdiskette └─⟦832e7e234⟧ Bits:30004286 Butler systemdiskette └─ ⟦this⟧ »EXTBESKR« └─⟦ccbc2d84d⟧ Bits:30004597 Boot 60k CP/M (Butler) └─ ⟦this⟧ »EXTBESKR« └─⟦d823d3189⟧ Bits:30004365 Butler CP/M 2.2 systemdiskette fra LFU └─ ⟦this⟧ »EXTBESKR«
Et assemblerprogram, der definerer extensions, skal begynde med NAME('<navn>') hvor <navn> er programmets navn. Derefter skal indholdet af filen EXTDEFS.MAC komme. Derefter specifikationer for de extensions, der er defineret i filen. Disse skal følge lige efter hinanden. Koden for dem kommer efter den sidste af dem. De ser hver sådan ud: EXTENSION <navn>Æ,<lokalt navn>Å <grænsefladeangivelse> ENDEXT <navn>Æ,<lokalt navn>Å Her skal angives samme <navn> og evt. <lokalt navn> begge steder. I den sidste specifikation skal ordet ENDEXT erstattes med ENDALLEXT. <navn> er det navn, extension'en skal kaldes ved i COMAL-programmer, excl. eventuelt $-tegn. <lokalt navn> er det navn, extension'en har i assemblerfilen. Hvis det ikke er angivet, bruges <navn> i stedet. Angivelse af <lokalt navn> kan være nyttig, hvis flere extensions har navne, der falder sammen på de første 5 tegn eller indeholder underscore eller falder sammen med Z80 opcodes. <grænsefladeangivelse> er forskellige for funktioner, sætninger og operatorer. For funktioner: FUNCTION <returtype> <liste af parametre> hvor <returtype> (funktionens type) er INT, REAL eller STR . For sætninger: STATEMENT <liste af parametre> <liste af parametre> er nul eller flere linier, hvor hver linie specificerer een parameter på følgende måde: PARAMETER Æ<dimension>,Å<type> Hvis <dimension>, udelades, har man angivet en værdioverført parameter. Ellers referenceoverføres parameteren, og <dimension> angiver parameterens dimensionalitet. 0 = simpel variabel, 1=vektor osv. Her kan angives ANYDIM for <dimension> . Det betyder at den aktuelle parameter kan have en hvilkensomhelst dimension og at den referenceoverføres. Det er da op til extension'en at finde ud af hvilken dimensionalitet, parameteren har, og gøre derefter. <type> angiver parameterens type. Her kan angives INT, REAL, STR med den oplagte betydning. Desuden kan angives ANYTYPE eller INTREAL. ANYTYPE betyder at den aktuelle parameter kan have en hvilkensomhelst type (altså INT, REAL eller STR), og INTREAL betyder at den aktuelle parameter kan have type INT eller REAL. Der gør sig nogle særlige forhold gældende i disse to tilfælde vedrørende den måde, hvorpå parameteren overføres til extension'en - se nedenfor. For operatorer er <grænsefladeangivelsen> enten OPERATOR <returtype>,<venstre operands type>,<højre operands type>,<prioritet> eller OPERATOR <returtype>,<operandens type>,<prioritet> hvor det første benyttes for dyadiske operatorer og det andet benyttes for monadiske operatorer. <returtype> er som for funktioner enten INT, REAL eller STR . <venstre operands type>, <højre operands type> og <operandens type> kan være INT, REAL, STR, ANYTYPE eller INTREAL med samme betydning som ovenfor beskrevet ved funktioner og sætninger. Parametre til operatorer kan kun være værdioverførte. <prioritet> angiver hvilken prioritet i beregningen, operatoren skal have i forhold til andre operatorer, herunder standardoperatorer. Det angives som navnet på en standardoperator, hvor det navn, som også benyttes ved kald af matematikpakken, skal bruges. Operatoren vil da få samme prioritet som denne standardoperator. Følgende navne kan bruges: POWER, TIMES, SLASH, DIV, MOD, PLUS, MINUS, CHS, LEQ, LSS, GEQ, GTR, EQL, NEQ, IN, B.NOT, B.AND, B.OR Efter linien med ENDALLEXT ....... kommer koden for de extensions, der er specificeret. Hver rutine begynder med en label, som er det navn (eller lokalt navn), der er angivet i den tilsvarende EXTENSION linie. Når rutinen starter, er alle registre, som benyttes af COMAL, gemt og kan benyttes frit. Parametrene ligger på en stak, som udpeges af IX og som vokser nedad ligesom SP-stakken. Den sidste parameter ligger øverst. For referenceoverførte parametre ligger et såkaldt referenceelement for parameteren på stakken. Det beskrives nedenfor. Bemærk at hvis den formelle parameter er af type ANYTYPE eller REALINT, må extension'en selv finde ud af hvad typen på den aktuelle parameter er, og indrette sig derefter. Typen fremgår af referenceelementet, se beskrivelsen nedenfor. For værdioverførte parametre ligger værdien på stakken. Hvordan værdien er struktureret, beskrives nedenfor. Hvis den formelle parameter er af type ANYTYPE eller REALINT, er der stakket endnu en ekstra byte ovenpå værdien, og denne byte angiver værdiens type på følgende måde: For ANYTYPE kan byten have værdien INT, REAL eller STR, svarende til den aktuelle parameters type. For INTREAL vil en aktuel parameter af type REAL altid blive konverteret (med afrunding) til INT før extension'en kaldes, men den ekstra byte vil angive om konverteringen gav anledning til overløb (tallet for stort). Hvis dette var tilfældet, vil byten være <>0 ; ellers er den =0. Hvis den aktuelle parameter er af type INT, vil byten være =0. I tilfælde af overløb vil der stadig ligge et heltal på stakken lige under den omtalte byte, men dets værdi er uinteressant. Desuden indeholder A- hhv. B-registeret den kørende COMAL-versions versionsnummer hhv. underversionsnummer. For version 2.0 er under- versionsnummeret 0, og versionsnummeret er 8+DB+OV , hvor DB=0 for 7-ciffer-udgaven og DB=2 for 13-cifferudgaven, mens OV=0 for den hele udgave og OV=1 for overlayudgaven. Inden rutinen returnerer, skal alle parametrene afstakkes fra IX-stakken. Hvis rutinen svarer til en funktion eller en operator, skal returværdien stakkes på IX-stakken inden returhoppet. Hvis der returneres med C-bitten sat (se nedenfor), er det dog ikke nødvendigt at afstakke parametre eller stakke nogen returværdi. Der returneres v.hj.a. RET. Der skal ikke pilles ved SP-stakkens højde, men den kan godt benyttes, da der er ca. 100 bytes fri plads. Afhængigt af indholdet af AF-registret vil COMAL afgive en fejlmelding når rutinen har returneret. Der er mulighed for at få både fatale fejlmeldinger og ikke-fatale fejlmeldinger. Hvis Z-bitten er sat, vil der ikke blive givet nogen fejlmelding. Ellers vil der blive givet fejlmeldingen med det nummer, der ligger i A-registret, dog således at der skal fratrækkes 50 fra numre, der er større en 200. Hvis C-bitten er sat, vil fejlmeldingen være fatal; ellers vil den være ikke-fatal, dvs. den vil ikke komme hvis man kører med TRAP ERR-, men i stedet kan man få fejlnummeret v.hj.a. ERR() . Struktur af parametre ===================== Nedenfor gennemgås den måde, hvorpå parametre, dvs. værdier og referenceelementer, repræsenteres af COMAL: Heltal repræsenteres som maskinen gør det. Bitmønsteret 8000H betyder "udefineret" og vil ikke blive leveret som parameter. Det bør ej heller returneres som returværdi eller tildeles nogen parameter. Hvis en referenceoverført parameter har denne værdi, betyder det at variablen aldrig er blevet tildelt nogen værdi. Dette bør checkes først hvis værdien benyttes. Dette gøres implicit af matematikpakkens funktion LDVAL. Reelle tal fylder 4 bytes for 7-cifferversionen og 8 bytes for 13-cifferversionen. Første byte = 80H og sidste byte lig 00H betyder "udefineret". Bemærkningerne ovenfor gælder også her. Strenge består af to dele: først 2 bytes (et heltal) der fortæller hvor lang strengen er, og dernæst, i rækkefølge mod højere adresser, det således angivne antal bytes, som hver indeholder et tegn, således at den byte, der følger lige efter længden, indeholder det første tegn, den næste det andet tegn osv. Referenceelementer angiver variable af alle slags, både simple variable, herunder strengvariable, arrays og delstrenge. Formatet for referencelementer for delstrenge er specielt og beskrives senere. Alle andre referenceelementer fylder 4 bytes og består af to pointere: først en pointer til en beskrivelse af variablen og derefter en pointer til variablens dataområde. Variabelbeskrivelsen er af variabel størrelse og vokser mod lavere adresser (NB!) . For simple variable består den af en byte med værdi -INT, -REAL eller -STR, svarende til de tre typer. Hvis det er -STR, følges denne byte af strengvariablens maksimale længde (et heltal i 2 bytes). For arrays er der først et antal index-felter, svarende til antallet af indices. Hvert indexfelt består af det følgende: antal indexfelter efter dette (1 byte) lav grænse for dette index (heltal 2 bytes) høj grænse for dette index (heltal 2 bytes) størrelse af hver delarrays eller elements data (heltal 2 bytes) Eksempel: variabelbeskrivelsen for en array dimensioneret med DIM A$(-2:5, 1:10) OF 20 er 1 (1 byte) -2 (2 bytes) 5 (2 bytes) 220 (2 bytes) 0 (1 byte) 1 (2 bytes) 10 (2 bytes) 22 (2 bytes) (2 for aktuel længde + 20 til selve tegnene) -STR (1 byte) 20 (2 bytes) Referenceelementer for delstrenge begynder også med en pointer til en variabelbeskrivelse, der i dette tilfælde er en enkelt byte med værdien enten -STR-1 eller -STR-2 Derefter følger en pointer til datafeltet for den strengvariabel, delstrengen er en del af. Efter denne følger den maksimale (dimensionerede) længde for den pågældende strengvariabel, 2. index (til-værdi), og 1. index (fra-værdi), som er anvendt ved specifikationen af delstrengen. Eksempler på 2. og 1. index : ved A$(8:17) er 2.index = 17 og 1.index = 8. Ved A$(10) er både 2.index og 1.index = 10. Alle tre værdier er heltal (2 bytes). Datafeltet for en simple variabel er struktureret som en værdi, se ovenfor. Datafeltet for en array er blot en række simple datafelter efter hinanden, et for hvert af elementerne. For strengarrays er der afsat plads til at hvert element kan vokse til sin maksimale længde. Matematikpakken =============== I EXTDEFS.MAC er defineret alt, hvad der skal bruges for at man kan benytte matematikpakken. Man kalder matematikpakken ved at benytte makroen EXPR hvorefter følger kommandoer til matematikpakken. Der afsluttes med EXPREND Kommandoerne udføres en efter en i den rækkefølge de står. De tager (for det meste) deres argumenter fra IX-stakken og gemmer deres resultater på denne stak. Man kan opfatte kommandoerne som et program til en stakorienteret maskine. Kommandoerne er i virkeligheden makroer, som er defineret i EXTDEFS.MAC . Hver makro expanderer til en eller flere bytes med parametre til kaldet af matematikpakken, som fortolker disse parametre og opererer på IX-stakken. Man kan benytte følgende kommandoer: De følgende kommandoer svarer til COMALs standardfunktioner, men alle kommandoer kræver argumenter af en bestemt type og leverer et resultat af en bestemt type, som angivet. Hvor der er angivet INTREAL, betyder dette, at argumentet skal være af heltalstype, men at det er i orden, hvis dette er fremkommet ved at kald af REALINT umiddelbart før kommandoen. navn argument(ers) type resultats type ATN REAL REAL COS REAL REAL SIN REAL REAL TAN REAL REAL LOG REAL REAL EXP REAL REAL SQR REAL REAL ESC - INT ERR - INT EOD - INT EOF REALINT INT LEN ref. elem. INT (ref.elem. skal være streng) ORD STR INT IVAL STR INT VAL STR REAL INT REAL REAL FRAC REAL REAL TRUNC REAL INT ROUND REAL INT POS STR, STR INT BVAL STR INT CHR REALINT STR STR REAL STR (svarer begge til STR$, men I.STR INT STR taget af reelt tal hhv. heltal) ERRTEXT REALINT STR SGN REAL INT (svarer begge til SGN, men I.SGN INT INT taget af reelt tal hhv. heltal) ABS REAL REAL (svarer begge til ABS, men I.ABS INT INT taget af reelt tal hhv. heltal) RND0 - REAL (RND uden parametre) RND2 REALINT, REALINT INT (RND med 2 parametre) SPC REALINT STR PEEK REAL INT INP REALINT INT BSTR REALINT STR VARPTR ref.elem. REAL FREEST - INT (FREESTORE) Diverse konverteringer: CONV konverterer det øverste stakelement fra INT til REAL. CONV1 konverterer det næstøverste stakelement fra INT til REAL. Det forudsættes at det øverste stakelement er af type REAL. REALINT konverterer det øverste stakelement fra REAL til INT med afrunding. Hvis det tallet er udenfor heltalsområdet, bliver det øverste stakelement udefineret, men der sættes desuden et særligt overløbsflag, som de standardfunktioner, der ovenfor er angivet REALINT ved, reagerer passende på. RLBL konverterer det øverste stakelement fra REAL til INT således at hvis tallet er <> 0 bliver resultatet 1, ellers 0. Benyttes i forbindelse med de boolske operatorer. RLBL1 konverterer det næstøverste stakelement fra REAL til INT på samme måde som RLBL. Det forudsættes at det øverste stakelement er af type INT. COMALs standardoperatorer har følgende navne i denne sammenhæng: navn COMALs navn argument(er)s resultats type type CHS - (monadisk) REAL REAL POWER ^ ) TIMES * ) SLASH / ) DIV DIV )->REAL, REAL REAL MOD MOD ) PLUS + ) MINUS - (dyadisk) ) LEQ <= ) LSS < ) GEQ >= )->REAL, REAL INT GTR > ) (værdi 0 eller 1) EQL = ) NEQ <> ) I.CHS - INT INT I.TIMES * ) I.DIV DIV ) I.MOD MOD )->INT, INT INT I.PLUS + ) I.MINUS - ) I.LEQ <= ) I.LSS < ) I.GEQ >= )->INT, INT INT I.GTR > ) (værdi 0 eller 1) I.EQL = ) I.NEQ <> ) S.PLUS + STR, STR STR S.LEQ <= ) S.LSS < ) S.GEQ >= )->STR, STR INT S.GTR > ) (værdi 0 eller 1) S.EQL = ) S.NEQ <> ) IN IN STR, STR ) B.AND AND INT, INT )->INT B.OR OR INT, INT ) (værdi 0 eller 1) B.NOT NOT INT ) Herudover er der følgende kommandoer: INX forventer et tal og dernæst et referenceelement for en array eller en strengvariabel på stakkens top. Foretager indicering, dvs. afstakker disse to og stakker i stedet et referenceelement for det valgte element i den angivne array eller den angivne delstreng. Tallet kan være et heltal eller et reelt tal. I det sidste tilfælde konverteres tallet automatisk til heltal med afrunding. Tallets type (INT eller REAL) skal angives efter INX f.eks. sådan: INX REAL LDVAL forventer et referenceelement på stakkens top. Afstakker dette og stakker i stedet værdien af den tilsvarende variabel. Kan også bruges efter INX. Det checkes at variabelen ikke er "udefineret", dvs. har den specielle værdi, der betyder, at der ikke er blevet tildelt nogen værdi til den. STVAL forventer et referenceelement og dernæst en værdi på stakkens top. Begge afstakkes og værdien gemmes i den variabel, der er angivet af referenceelementet. Værdiens type og typen af den variabel, der angives af referenceelementet, skal stemme overens. Kan benyttes efter INX. LOAD forventer en adresse (2 bytes) på stakkens top. Afstakker denne og stakker i stedet den værdi/det referenceelement, der ligger på den adresse. Det skal angives, hvilken type, værdien har, eller at det er et referenceelement. Dette gøres på samme linie efter LOAD, f.eks. således: LOAD INT STORE forventer en adresse (2 bytes) og dernæst en værdi eller et referenceelement på stakkens top. Begge afstakkes og værdien/referencelementet gemmes på den angivne adresse. Det skal, ligesom ved LOAD, angives hvilken type, værdien har, eller at det er et reference- element. Dette gøres ligesom ved LOAD, f.eks.: STORE REF INTCON stakker et heltal eller en adresse (2 bytes) på stakken. Heltallet/adressen skal angives på den samme linie efter INTCON. f.eks. således: INTCON 47 STRCON stakker en strengværdi på stakken. Strengværdien skal angives på den samme linie efter STRCON, f.eks. således: STRCON 'Strengen skal i enkelt anførselstegn' UROUND forventer et reelt tal på stakken. Dette afstakkes, konverteres til et fortegnsløst heltal i området 0 til 65535 og stakkes. SYSVAR stakker værdien af en af systemvariablene som et heltal. Det skal angives hvilken af systemvariablene, man er interesseret i; dette gøres på samme linie efter SYSVAR, f.eks. således: SYSVAR PAGEWI Systemvariablenes navne er lidt forkortede her: COMALs navn Her kaldes den ZONE ZONE INDENTION INDENT PAGEWIDTH PAGEWI PAGELENGTH PAGELE KEYWORDLOWER KWLOWER IDENTIFIERLOWER IDLOWER TRUE stakker et heltal 1 FALSE stakker et heltal 0 Der er naturligvis mulighed for at der opstår fejl ved brug af matematikpakken: overløb, indexfejl, forskellige funktioner får argumenter, der er ude af definitionsområdet osv. Der skelnes mellem fatale og ikke-fatale fejl. Fejl, der er fatale under normal COMAL-afvikling, der fatale her; fejl, der ikke er fatale under normal COMAL-afvikling, dvs. kan slås fra v.hj.a. TRAP ERR-, er ikke fatale her. Hvis en ikke-fatal fejl opstår, gemmes dens fejlnummer blot og der fortsættes med udførelse af kommandoer. Fejlnummeret vil da stå i A-registret, når der vendes tilbage til extension'en efter ENDEXPR, og carry-bitten vil være 0, mens Z=1. Hvis der opstår en fatal fejl, vil resten af kommandoerne blive sprunget over, IX sættes tilbage til dens værdi ved indgangen til matematikpakken, der vendes tilbage til extension'en efter ENDEXPR med fejlnummeret i A-registret, carry=1 og Z=1. Hvis der ikke opstår nogen fejl overhovedet, er A=0 og Z=0 når der vendes tilbage til extension'en efter ENDEXPR. Ønsker man således at checke om der opstår en fejl ved udførelsen af en bestemt kommando, kan man blot indføje ENDEXPR JP NZ,FEJLBEHANDLING EXPR efter denne kommando. Bemærk, at disse konventioner for indholdet af A, CY, Z svarer til konventionerne for rapportering af fejl tilbage til det kaldende COMAL-program. Format for .EXT -filer ====================== Den fil, der læses op af COMAL når man bruger EXTENSION-kommandoen, skal have et bestemt format. Dette er et særlig simpelt relokerbart format. Assemblerprogrammet, hvis form er beskrevet i den første afsnit, kan oversættes af Microsofts M80 makroassembler til eet relokerbart format. Andre assemblere benytter andre relokerbare formater (og nogle af dem vil også kræve at definitioner i EXTDEFS.MAC omskrives). COMALen definerer sit eget relokerbare format, som er som følger: Filen starter med et heltal på 2 bytes, som fortæller hvor meget kode, filen indeholder, talt i bytes. Dette er ikke det samme som filens længde, da filen udover koden indeholder information om, hvilke dele af koden, der skal relokeres. Resten af filen består af et antal blokke med samme format. Hver blok består af 9 bytes, hvoraf de 8 indeholder kode, og den niende indeholder relokeringsinformation for de 8 bytes. Hvis det tal, filen starter med, er L, vil der være (L + 7) DIV 8 blokke. Hvis L ikke er et multiplum af 8, er der overskydende plads i den sidste blok. Denne overskydende plads indeholder blot noget nonsens. Koden, som er indeholdt i blokkene, udgør logisk een lang følge af kodebytes. Koden for to blokke efter hinanden vil altså ligge lige efter hinanden når filen er blevet læst op af COMALen. Byten med relokeringsinformation indeholder een bit for hver af de 8 kodebytes, således at bit 0 svarer til den første byte, osv. op til bit 7, der svarer til den ottende og sidste kodebyte. Hvis en sådan bit er 1, betyder det, at den adresse, som ligger i den pågældende byte og den foregående, skal relokeres. Hvis bitten er 0, skal de to byte ikke relokeres. Programmet CONVERT kan lave en relokerbar fil i Microsoft format om til den tilsvarende fil i COMALs format. Benytter man en assembler, der bruger et andet format, må man selv lave et program, der kan lave den relokerbare fil om til COMALs format. «eof»