(1)
MaisForth an507 -- Albert Nijhof
juli 2005
(HCC Forth-gg)
  1. Achtergrond

    CamelForth (1995) van Bradford J. Rodriguez stond aan de wieg van MaisForth an507 hoewel dat nu nauwelijks nog te merken is.
    De metacompiler is volledig nieuw en lijkt in niets op die van CamelForth.
    De targetcode is ingrijpend veranderd. De keuze van de Forthregisters is wel gehandhaafd. Af en toe kunt u nog assembler code uit CamelForth tegenkomen, ik heb ernaar gestreefd om die steeds te markeren met BJR.
    De assembler notatie is vernieuwd.

  2. Contact per email

    MaisForth an507 kan nog fouten bevatten. Neem contact op met ons als u vragen of opmerkingen over MaisForth an507 heeft. We zijn te bereiken via de rubriek "Mail ons" op de website van de HCC Forth-gg (http://www.forth.hccnet.nl).

  3. De files

    "an507versies.txt" Overzicht van veranderingen
    "an507extra-nl.html"   Uitleg bij de niet-standaard woorden
    "assembler.html" Overzicht van de 6809 assembler notatie
    "an507.bin" ROM image (C000-FFFF) van de MaisForth
    "meta507.f" Metacompiler
    "targ507.f" Target code
    "cras507.f" Cross assembler, door meta507.f te laden

  4. Hardware

    MaisForth an507 is een 6809 Forth voor het "maiskastje". De woorden die de hardware aanspreken zijn:

    KEY? ( -- vlag )
    KEY ( -- char )
    EMIT? ( -- vlag )
    EMIT ( char -- )
    !USART ( baudfactor -- )
    
  5. MaisForth an507 start op

    Het interne werkgebied van Forth is 000-2FF.

    000-07F Dictionary draden, Users, Find Stack
    080-0FF Terminal Input Buffer
    100-17F Data Stack, dalend
    180-1FF Return Stack, dalend
    200-27F Circulaire Buffer voor o.a. strings (tijdelijk!)
    280-2FF Compiler Stack, dalend
    
    Bij de koude start wordt de beschikbare hoeveelheid RAM vastgesteld (zie HIMEM) en op de terminal gemeld.

    Raadpleeg de file "an507extra-nl.html" voor de niet-standaard Forth woorden in deze tekst.

  6. Standaard/niet-standaard woorden (ANS)

    De standaard Forth woorden in FORTH en ONLY worden bekend verondersteld.

    De ruim 80 niet-standaard woorden van het EXTRA en ONLY vocabulary worden beschreven in de file "an507extra-nl.html".

    Interne hulpwoordjes, die voor de gemiddelde programmeur niet van belang zullen zijn, staan in het INSIDE vocabulary. Wie daar meer over wil weten, moet de target code in "targ507.f" zelf bestuderen.

  7. Nieuwe ROM image

    Hoe maak je een nieuwe ROM image bijv. na veranderingen in de target?
     

    De image is nu opgeslagen in "an507.bin".
  8. Decompileren met SEE

    De decompiler doet niets anders dan kijken of er op een adres een woord gecompileerd staat. Zo ja, dan drukt hij dat af.

    Als bijv. op D000 en op D001 beide een gecompileerd woord lijkt te staan, laat SEE beide zien, hoewel minstens een van beide een toevalstreffer moet zijn. In zo'n geval worden de namen niet recht onder elkaar afgedrukt. De lezer moet zelf de juiste lezing kiezen.

    De manier om snel de decompiler te leren lezen is: maak zelf een paar kleine woordjes en laat er SEE op los.

    >

    Alle woorden die een inline gecompileerd argument verwachten, eindigen

    op  ()  als het om een cel gaat, bijv. IF() GOTO() () 
    op  (C) als het om een byte gaat, bijv. (C)
    op  (S) als het om een string gaat, bijv. ."(S)
    
    Dit is handig bij het decompileren (SEE). De decompiler laat namelijk zien wat er in het geheugen staat en niet met welke programmatekst dat tot stand gekomen is.

    Voorbeelden:
    Het getal 1000 wordt gecompileerd als () plus een cel met 1000 erin.
    Het getal 1 wordt gecompileerd als (C) plus een byte met 1 erin.
    ." Hallo!" compileert ."(S) plus counted string "Hallo!".
    AHEAD compileert GOTO() plus een cel met het doeladres.
    enz.

    >

    Na TO() +TO() en INCR() volgt het data-adres van een Value. Dat kan een gewone Value zijn of een indirecte ROM Value.

    SEE ALLOT levert bijvoorbeeld op:

          +TO()
          0049
          EXIT
    
    Volledige lijst van RAM adressen van indirecte ROM values:
    0023 TOPVOC     0025 TOPMSG     0027 TOPPFX     0029 TOPNFA
    002B HLD        002D CONTEXT    002F CS#        0031 MSG#-2
    0033 MODE       0035 SECTION    0037 #TIMES     0039 #IB
    003B IB         003D THERE      003F HOR        0041 VER
    0043 HIMEM      0045 OK         0047 DOT?       0049 HERE
    
    Deze ROM values gedragen zich voor de programmeur als constanten. Het systeem kan hun waarde wijzigen, de programmeur kan dat alleen indirect.
  9. De metacompiler

    De metacompiler zou moeten werken op iedere standaard 32-bits Forth. (Ik heb Win32forth gebruikt.)

    Als het metacompileren begint is de metacompiler af, daar komt dus niets meer bij. Daarom kan de target image er gewoon achter komen te staan. Voor de overzichtelijkheid laat ik de target image beginnen op het eerst beschikbare adres dat in hex op 000 eindigt. De HERE tijdens het metacompileren is de gewone HERE van de host Forth.

    De metacompiler is nog wat rommelig en niet al te uitvoerig gedocumenteerd. Hier volgt een oriënterende rondleiding met enige hints:

    Tekst tussen <---- en ----> wordt door Forth overgeslagen.

    >

    De metacompiler heeft zijn eigen QUERY-INTERPRET lus die gestart wordt met :::MAIS:::
    Hij wordt verlaten met ;;;MAIS;;; of als er een fout optreedt.

    Bestudeer allereerst het woord METACOMPILING dat de kern van :::MAIS::: is.

    >

    Door TRACE en NOTRACE om een stuk programmatekst in de target code te zetten, is tot in detail te volgen wat daar bij het metacompileren gebeurt. (spatiebalk: wacht/doorgaan)

    >

    Alle woorden in de target code die bij het metacompileren tot uitvoering komen, staan in het META vocabulary. Dat zijn de echte metacompiler woorden. Om interactief tijdens het metacompileren een DROP uit te kunnen voeren moet het woord DROP dus expliciet in META opgenomen zijn. Zie META-WORDS gevolgd door de woordenlijst, bijna aan het eind van "meta507.f".

    >

    Alle woorden die bij het metacompileren zullen worden gecompileerd, worden ter plekke opgezocht in de target-image voorzover die tot dan toe opgebouwd is. Bestaat het woord nog niet, dan volgt onherroepelijk een foutmelding.
    Deze metacompiler kent geen voorwaartse referenties. De code moet dus in de natuurlijke Forth volgorde staan. Bekijk de defining words om te zien hoe het daarbij opgelost is:

    Hun DOES-deel wordt zelfstandig gedefinieerd, los van het CREATE-deel.

    DOER: ccc      high level Forth code  ;
    DOERCODE ccc   assembler code         NEXT END-CODE
    
    zijn functioneel gelijk aan
    : ccc DOES>    high level Forth code  ;
    : ccc ;CODE    assembler code         NEXT END-CODE
    

    voorbeeld met CREATE

    \ in target:
    DOERCODE DOCREATE REG X PULS  REG D PSHS  X D TFR NEXT END-CODE
    
    \ in metacompiler:
    : xCREATE   (  -- )   xHEADER MET-DOER DOCREATE ;
    
    MET-DOER zorgt ervoor dat later runtime de Doer DOCREATE opgezocht en in het cfa gezet wordt.

    Zo ook KOMPILE dat er voor zorgt dat later runtime het te compileren woord opgezocht en gecompileerd wordt, bijv in:
    : xAHEAD ( -- AHEADa 11 ) KOMPILE GOTO() HERE 0 x, HX 11 ;

    Met deze late bindingen zijn we in princiepe van de voorwaartse referenties af.

    >

    De x-woorden

    Woorden in de metacompiler beginnen vaak met een x (x: x; xIF enz.) Zij worden later en masse zonder die x in het META vocabulary herdefinieerd. Deze wat omslachtige werkwijze maakt het voor de lezer veel gemakkelijker om te metacompiler te doorgronden.
    Zo kennen de immediate woorden vier varianten, bijv. de punt-komma:
     

    (an)