Een eerste kennismaking. De talstelsels. Plaats de cartridge en zet de computer aan. Na een ogenblik verschijnt het volgende: WBASS2 Assembler/Monitor enz. Het pijltje geeft aan dat de assembler nu geladen is, en wacht tot u een commando intypt. Aan het pijltje en de knipperende cursor kunt u zien dat u niet in BASIC bent, maar in de assembler. Deze assembler kent 3 talstelsels: hexadecimaal, decimaal en binair. Daarnaast kunnen waarden ook als ascii-teken tussen dubbele aanhalingstekens voorgesteld worden. Met het commando ? kunt u getallen naar andere talstelsels laten omrekenen. Typ bijvoorbeeld in: ? "A" en druk Er verschijnt: =A &H41 65 &B01000001 U ziet direct achter het =-teken het ascii-teken, daarachter resp. de hexadecimale, de decimale en de binaire voorstelling van de waarde. Ook rekenkundige uitdrukkingen worden verstaan: ? 3*4096+&H1A Probeer eens: ? 3*4+5 geeft 12+5=17 ? 5+3*4 geeft 8*4 =32 ! Zo kunt u zonder haakjes toch alle kanten op door de volgorde van de termen om te draaien. De assembler kan optellen (+), aftrekken (-), vermenigvuldigen (*), delen (/), rest berekenen (MOD), machtsverheffen (^) en daarnaast de logische bewerkingen AND, OR en XOR. Inleiding: het stap voor stap leren gebruiken. De assembler bestaat uit een aantal delen: EDITOR : intypen en veranderen van listings MONITOR : bekijken en wijzigen geheugen ASSEMBLER : vertalen van de ingetypte listing naar machinecode DISASSEMBLER : reeds bestaande machinecode-programma's weer terugvertalen naar een leesbare listing. TESTER : uitproberen van programma's en registers bekijken. Daarnaast zijn er nog tal van mogelijkheden aanwezig om iets naar disk te schrijven of iets in te laden. We doorlopen nu stap voor stap het schrijven van een programmaatje in assemblertaal. Typ in (het pijltje hoeft u natuurlijk niet in te typen): >EDIT en geef Er verschijnt dan een nu nog leeg scherm. Onderaan leest u af op welke regel de cursor staat. De cursor zelf staat bovenin en kan met de cursorbesturingstoetsen vrijelijk door de tekst worden bewogen. Na het invoeren van een regel MOET u op drukken, anders komt de regel niet in het geheugen. Letters invoegen en wissen gebeurt net als in BASIC: INS schakelt de invoegmode in en uit, DEL wist het teken onder de cursor, BS wist het teken links naast de cursor. Typ om de editor te proberen het volgende programmaatje eens in: ORG &HC000 LD HL,TEKST PRINT: LD A,(HL) INC HL AND A RET Z CALL CHPUT JR PRINT TEKST: DEFB "Dit is WBASS2",13,10,0 END U hoeft niet zelf de tekst in de goede kolommen te typen. De assembler deelt de tekst in als zij weer op het scherm gezet wordt. Evenmin is het noodzakelijk dat u hoofdletters gebruikt. Dit assemblerprogrammaatje is nu geschreven in source (bron) vorm. Dat wil zeggen, dat het alleen de listing is, het programma moet nog vertaald worden. Het is bedoeld om een regel tekst op het scherm te zetten. De eerste opdracht zorgt ervoor dat ons programma bij het assembleren (het vertalen) op adres &HC000 begint. Het programma begint met het registerpaar HL op het adres van de tekst te zetten. Dan begint er een lus, waarin steeds één letterteken wordt opgehaald. De combinatie AND A en RET Z zorgt ervoor dat als dit teken de waarde 0 heeft, de routine wordt verlaten. Is dit niet het geval, dan wordt het teken afgedrukt, en wordt de lus herhaald. De laatste opdracht DEFB is weer een opdracht aan de assembler, om waarden en/of tekst in het programma op te nemen. Om de editor te verlaten en weer terug te keren naar de commando-mode (te zien aan het pijltje) drukt u op CTRL-C. Deze toets breekt elke handeling af. Druk op CLR-HOME om het scherm schoon te maken. In ons programmaatje bevinden zich een aantal labels, dat zijn de woorden die in de eerste kolom van de listing en ook achter Z-80 instructies voorkomen. Labels zijn variabelen, die aangeven waar een bepaald programmadeel (routine) zit. Elk machinetaal programma bevat zulke labels. Labels mogen ook in rekenkundige uitdrukkingen gebruikt worden. Typ nu in (in de commando-mode): >LAB U ziet verschijnen: TEKST PRINT CHPUT De labels hebben nog geen waarde. Die krijgen ze pas tijdens het assembleren. We zullen het programma gaan assembleren. Typ in: >ASM Druk dan nog 5 maal op . Hiermee beantwoordt u een vijftal vragen over hoe het assembleren moet verlopen. Hierover komt later meer. Het programma wordt nu geassembleerd. Op het scherm verschijnt het programma in machinecode, en daarnaast onze listing: &H00 ORG &HC000 &HC000 &HC000 210CC0 LD HL,TEKST &HC003 7E PRINT: LD A,(HL) &HC004 23 INC HL &HC005 A7 AND A &HC006 C8 RET Z Label CHPUT niet gedef. in 8 adr. &HC008 &HC007 CD0000 CALL CHPUT &HC00A 18F7 JR PRINT &HC00C &HC00C 44697420 TEKST: DEFB "Dit is WBASS2",13,10,0 &HC010 69732057 &HC014 42415353 &HC018 320D0A00 &HC01C Begin: &HC000 Einde: &HC01B > We zien vóór regel 8 een foutmelding. Wat is er nu aan de hand? De assembler probeerde in regel 8 de waarde van het label CHPUT vast te stellen, maar CHPUT staat nergens in de eerste kolom van de listing en heeft dus geen waarde. Terecht meldt de assembler dus dat dat label niet gedefiniëerd is. Met het commando LAB kunt u de label-tabel weer zien. Er verschijnt: TEKST &HC00C PRINT &HC003 CHPUT U ziet: CHPUT heeft inderdaad geen waarde. Maar de routine CHPUT is ook geen onderdeel van ons programma, CHPUT is een programma in het ROM van de computer. We moeten de waarde van CHPUT dus op een speciale manier declareren. Typ in: EDIT om naar de editor te gaan. Ga naar de eerste regel en druk dan op CTRL-I. De tekst op het scherm schuift een regel naar beneden, en de cursor staat op een lege regel. Typ op deze regel in: CHPUT: EQU &HA2 en geef Hiermee geeft u de assembler tijdens het assembleren te kennen dat hij voor CHPUT de waarde &HA2 moet invullen. &HA2 is het adres van de printroutine in de ROM. Verlaat nu de editor weer en typ ASM. Druk bij de 5 vragen weer steeds op . Als het goed is verschijnt nu de complete listing weer, zonder foutmelding. Het programma is geassembleerd en staat nu vanaf adres &HC000 in het geheugen. Typ in: >PEEK &HC000 en Met dit commando kunt u het geheugen lezen. Er verschijnt: =! &H21 33 &B00100001 Dat is inderdaad de opcode van de eerste instructie uit ons programma. Met de monitor kunnen we het hele programma zien. Typ het volgende commando: MON &HC000 In beeld verschijnt nu een tabel, waarin de geheugeninhoud vanaf &HC000 hexadecimaal af te lezen is. De eerste waarde op elke regel is het adres. Dan volgen de kolommen waarin de waarden staan in de 8 geheugenplaatsen vanaf het adres. Geheel rechts staat de ascii-representatie van de waarden. Zo kunt u snel zien wat voor tekst er in het geheugen staat. U ziet: C000 21 0C C0 7E 23 A7 C8 CD enz. C008 A2 00 .. .... In de ascii-kolom kunt u duidelijk de tekst "Dit is WBASS2" zien staan. Linksboven staat de curcor. Met de cursortoetsen kunt u deze over het scherm bewegen, net als bij de editor. De cursor beweegt zich dan door het hexadecimale gedeelte van de tabel. Beweeg de cursor een paar regels naar beneden, zodat u uit het programmaatje bent (bv. op &HC030). U kunt nu hexadecimale waarden intypen om zo de geheugeninhoud te veranderen. De cursor gaat automatisch naar de volgende kolom, u moet geen spatie tikken. Verander ons programmaatje nog niet! We zullen de tekst in de ascii-kolom eens veranderen. "Dit is WBASS2" veranderen we in "Hallo, hoe gaat het ermee?". Nu zouden we bij elke letter de hexadecimale waarde moeten opzoeken. Gelukkig is dat niet nodig. Druk op om weer naar het hexadecimale deel te gaan. Typ dan: 0D0A00. De 00 dient om het teksteinde te markeren. Verlaat nu de monitor door op CTRL-C te drukken en typ in: GO &HC000 Het programma wordt nu gestart. Als er niets fout gegaan is verschijnt: Hallo, hoe gaat het ermee? Er is nog een manier om een machinetaalprogramma in het geheugen weer terug te zien. Dat is de disassembler. Deze, de naam zegt het al, doet precies het tegenovergestelde van het assembleren. De machinecode in het geheugen wordt weer naar leesbare assemblertaal omgezet. Het disassembleren wordt gestart door het volgende commando in te typen: DIS &HC000 Het volgende komt in beeld: &HC000 210CC0 LD HL,&HC00C &HC003 7E LD A,(HL) &HC004 23 INC HL &HC005 A7 AND A &HC006 C8 RET Z &HC007 CDA200 CALL &HA2 &HC00A 18F7 JR &HC003 &HC00C 48 LD C,B &HC00D 61 LD H,B ... Wat zien we nu? De laatste 2 instructies hebben we nooit ingetypt. Klopt. De tekst "Hallo, hoe gaat het ermee" begon op &HC00C. De disassembler weet natuurlijk niet dat we tekst bedoelen. Hij interpreteert alles als Z-80 instructies. De tekst in de editor kunt u opslaan op schijf met: SAVE "TESTPROG.ASS" De listing wordt dan in een intern gebruikt, kort code formaat weggeschreven. Als er op schijf al een file was met dezelfde naam, wordt die eerst van naam veranderd in TESTPROG.BAK (van BAcKup), zodat u niet gemakkelijk een tijdsintensief stuk programmeerwerk kunt verknoeien. Om de listing weg te schrijven in het ASCII-formaat, zoals dat door veel tekstverwerkers ondersteund wordt, typt u: SAVE/A "TESTPROG.ASC" (Bij dit ASCII-saven wordt GEEN backup gemaakt.) Inladen van de listing kan met: LOAD "TESTPROG.ASS" Ook ASCII-listings kunnen zo weer ingeladen worden. De machinecode in het geheugen kan ook opgeslagen worden. Omdat we de tekst hebben veranderd is het eindadres van &HC01B in &HC028 veranderd. Typ om de mcode op te slaan: BSAVE "TESTPROG.BIN",&HC000,&HC028 Deze instructie komt geheel overeen met de gelijkluidende BASIC-instructie. Met: BLOAD "TESTPROG.BIN" kan zowel onder BASIC als onder de assembler het programma weer ingeladen worden. In feite bent u nu in staat met deze assembler een programma te schrijven. Commando-bespreking. Op de nu volgende bladzijden volgt een volledig overzicht van alle commando's, hun mogelijkheden en voorbeelden. Deze commando's worden aan de assembler gegeven in de commando-mode, dus wanneer aan het begin van elke regel een pijltje (>) gezet wordt. Als er in de operand (alles wat ná het commando komt) waarden ingevuld moeten worden, mogen die waarden komplete rekenkundige uitdrukkingen zijn, waarin ook labels mogen voorkomen. Die moeten natuurlijk wel gedefinieerd zijn, door het programma waarin ze voorkomen te assembleren. Operanden die in deze beschrijving tussen [] staan, mogen worden weggelaten. Alle uitvoer die de assembler produceert in reactie op een commando kan ook geprint worden door achter het commando /P te plaatsen. Bijvoorbeeld: INFO wordt INFO/P PAGE wordt PAGE/P HUNT/B wordt HUNT/P/B of HUNT/B/P. De assembler-commando's. ASM Syntax: ASM ["FILENAAM.EXT"] Werking: Assembleert de listing die in de editor staat. Indien een filenaam werd opgegeven wordt die file eerst van schijf in de editor geladen. (Een eventuele oude listing in de editor is dan verloren.) Na intypen van het commando ASM worden u vijf vragen gesteld die u met J of N kunt beantwoorden. Indien u alleen op drukt, blijft de vraag onveranderd. De assembler onthoudt de door u gegeven antwoorden, zodat u niet steeds opnieuw de door u gewenste antwoorden in hoeft te vullen. 1. "Listing afdrukken? (J/N)" Als u hier Ja invult wordt de listing met hex-code kolom tijdens het assembleren op het scherm getoond. 2. "Ascii listing naar disk? (J/N)" Als u deze vraag bevestigend beantwoordt wordt de listing, zoals hij bij 1. op het scherm komt, naar disk geschreven. Zo kunt u de listing bijvoorbeeld in een tekstverwerker laden o.i.d. 3. "Mcode in geheugen zetten? (J/N)" Als u Ja geeft, worden de machinetaal-bytes tijdens het assembleren meteen in het geheugen gezet, zodat u het programma daarna direct kunt proberen. LET OP! dat u hierbij de assembler, die ook in het geheugen staat (&H4000 tot &H7600), niet overschrijft. Ook mag u de tekst in de editor niet overschrijven. De beschikbare geheugenruimte boven &H8000, waar ook de tekst van de editor staat, kunt u te weten komen met de INFO-instructie (zie aldaar). Als u een computer met Memory-Mapper bezit, kunt u natuurlijk de RAM zo schakelen dat u helemaal geen last heeft van de assembler of de tekst (Zie de PAGE-instructie en het hoofdstuk over Het Geheugen). 4. "Mcode naar disk? (J/N)" Als u hier met J antwoordt, wordt de machinecode naar disk geschreven. De programma-file die zo ontstaat is wel geschikt om onder MSX-DOS te werken echter niet als BLOAD-file onder BASIC. BLOAD-files kunt u met de assembler echter wel maken, door de mcode uit het geheugen zelf te saven (zie het BSAVE-commando). 5. "Relocatie-tabel maken? (J/N)" Als u hier Ja geeft, maakt de assembler een tabel aan, waarin wordt vermeld, op welke adressen in uw machinetaalprogramma 16 bits adressen staan, die naar een plaats elders in uw programma verwijzen. Wanneer u een programma wilt schrijven dat zichzelf op verschillende plaatsen kan neerzetten (bijvoorbeeld vlak onder de geheugengrens) maakt u gebruik van deze tabel. Als het programma namelijk in het geheugen verschuift moeten alle JP, CALL, en 16 bits LD instructies die naar een label van uw programma verwijzen, worden gecorrigeerd. Met het volgende voorbeeld wordt het vast duidelijker (enige machinetaalkennis is al wel nodig). We gaan uit van het programmaatje uit de inleiding. CHPUT: EQU &HA2 ORG &HC000 LD HL,TEKST PRINT: LD A,(HL) INC HL AND A RET Z CALL CHPUT JR PRINT TEKST: DEFB "Dit is WBASS2",13,10,0 END In dit programma bevindt zich één adres dat bij verschuiven moet worden verbeterd nl. TEKST. Als we die programma van &HC000 naar bijv. &HC100 verschuiven, blijft de waarde TEKST toch op &HC00C staan i.p.v. &HC10C. Het label CHPUT mag echter niet worden veranderd, want die maakt geen deel uit van ons programma. Die moet gewoon op &HA2 blijven staan, anders werkt het programma niet. Het label PRINT is wel een onderdeel van ons programma, zodat ook die waarde zou met &H100 verhoogd moeten worden, echter de instructie JR PRINT is een relatieve sprong zonder 16 bits adres. Dus als het programma verschuift, blijft de instructie JR het gewoon doen. Zou er echter gestaan hebben JP PRINT, dan zou hier de waarde van PRINT wél met &H100 verhoogd moeten worden om naar de goede plaats te springen. In de tabel die de assembler maakt, bevindt zich dus 1 adres, namelijk het adres waar de waarde TEKST, die moet worden verbeterd, zich bevindt. Dit adres is &HC001. Wanneer we het programma nu willen verschuiven van &HC000 naar &HC100, moeten we vlak voor het verschuiven de 16 bits waarde die op &HC001 staat ophalen, vermeerderen met de te schuiven afstand (&H100), en weer terug zetten. Bij een groter programma zijn er natuurlijk veel meer adressen die moeten worden veranderd. De machinetaalroutine die het verschuiven doet, bestaat dus uit een lus die steeds een adres uit de relocatie-tabel haalt en de 16 bits waarde die zich op dat adres en het volgende in het geheugen bevindt vermeerdert met de te schuiven afstand. Daarna wordt het programma verschoven. De assembler maakt de tabel altijd aan in het geheugen vanaf adres 0. Men moet er dus voor zorgen dat het geheugen zó geschakeld is, dat op adres 0 RAM geheugen staat (Zie Het geheugen). Als eind-merk plaatst de assembler het adres &HFFFF in de tabel. Na assembleren meldt de assembler het eindadres van de tabel, zodat u hem meteen kunt saven. We zullen nu het programmaatje nu zó in elkaar zetten, dat het op adres &H8800 onder basic wordt ingeladen, zichzelf vervolgens verplaatst tot vlak onder de Stack-Pointer, en daarna wordt uitgevoerd. De werkwijze: 1. Verander de ORG &HC000 in: ORG &H8800. 2. Assembleer dit programma nu: >ASM Mcode in geheugen zetten: Ja Relocatietabel maken : Ja (de rest niet nodig) Het mcode programma komt nu in het geheugen op &H8800 (natuurlijk mag de editor-tekst niet worden overschreven, zie de instructie INFO). De assembler geeft nu aan tot en met welke geheugenplaats de tabel loopt. (In ons geval bevat de tabel slechts 1 adres nl. &H8801.) We zien ook dat ons programma loopt tot &H881B. 3. Maak nu de editor schoon met SCR en typ het volgende programma in (alles achter een ; is uitleg, die u niet hoeft over te typen): BEGIN: EQU &H8800 ;beginadres en EINDE: EQU &H881B+1 ;eindadres van ;het te verschuiven programma. ;Schuifroutine netjes laten aansluiten: ORG EINDE ;Nu bepalen waar het prog. naar toe moet START: LD HL,-256 ADD HL,SP ;HL=SP-256 LD DE,EINDE-BEGIN ;lengte prog. AND A ;carry = 0 SBC HL,DE ;HL is het adres waar het naar toe moet. PUSH HL ;bewaar LD DE,BEGIN SBC HL,DE ;HL is nu de schuif-afstand (nodig voor tabel) EX DE,HL ;afstand in DE ;Nu de tabel doorlopen LD IY,TABEL LUS: LD L,(IY+0) LD H,(IY+1) ;Is het &HFFFF ? LD A,L AND H CP 255 JR Z,KLAAR ;ja, dan klaar ;Verhoog nu het adres op HL en HL+1 met de ;te verschuiven afstand (in DE). LD A,(HL) ADD A,E ;lage deel LD (HL),A INC HL LD A,(HL) ;hoge deel ADC A,D ;ADC voor evt.carry LD (HL),A ;dat is gedaan, nu het volgende adres. INC IY INC IY JR LUS KLAAR: ;De adressen zijn gecorrigeerd. ;Nu het programma nog verschuiven. POP HL ;doeladres LD BC,EINDE-BEGIN ;lengte ADD HL,BC EX DE,HL LD HL,EINDE DEC HL DEC DE LDDR ;schuifopdracht. INC DE EX DE,HL JP (HL) ;spring ernaartoe. TABEL: ;hier komt straks de tabel END ;einde 4. Schrijf deze routine weg op schijf, want u kunt hem zeker vaker gebruiken. U hoeft dan alleen de labels BEGIN en EINDE aan te passen of de routine die het doeladres bepaalt. Assembleer nu het programma: >ASM Mcode in geheugen zetten: Ja Relocatietabel maken : Nee! De schuifroutine staat nu netjes achter ons programma aan in het geheugen. 5. Geef nu de instructie: >MOVE 0,L 4,TABEL Hiermee geeft u de assembler opdracht 4 geheugenplaatsen vanaf adres 0 te verplaatsen naar het adres dat door het label TABEL wordt aangegeven. In het geheugen staat nu: &H8800 t/m &H881B: ons programma &H881C t/m &H8859: de schuifroutine START &H885A t/m &H885D: de tabel 6. Schrijf dit geheel weg met het commando: >BSAVE "TESTPROG.BIN",&H8800,&885D,START Het complete programma staat nu op disk. Als u nu naar BASIC gaat met: >BASIC en dan BLOAD "TESTPROG.BIN",R geeft, verschijnt als het goed is: Dit is WBASS2! Vlak voordat de tekst verscheen heeft het programma zich verschoven naar een of ander adres ergens onder de Stack-Pointer. Natuurlijk kunt u hiervoor in de plaats denken wat u wilt: Het programma kan ook neergezet worden waar maar RAM is, of zelfs waar de gebruiker het wil, bv. bij basic/hybride spellen in de Play-buffer, of onder de SP. Mogelijkheden te over! DIS Syntax: DIS [beginadres[,eindadres]] DIS/D "FILENAAM.EXT",beginadres,eindadres Werking: Disassembleert een geheugendeel. Bij DIS/D wordt op disk een Ascii-file aangemaakt, waarin de disassembly wordt geschreven, vandaar dat hier direct moet worden opgegeven van waar tot waar. Opm: Als geen adres wordt opgegeven gaat de disassembler verder waar hij gestopt was. Tijdens het disassembleren zijn de volgende toetsfuncties van kracht: uitvoer per regel, uitvoer per scherm (20 r.), doorscrollen, of /C afbreken. Deze toetsen gelden overigens voor alle uitvoer op scherm of printer, ook bij andere commando's. Geheugen commando's. POKE Syntax: POKE adres,8 bit waarde POKE/V adres,8 bit waarde POKE/D adres,16 bit waarde Werking: Plaatst de waarde op het aangegeven adres. Bij POKE/V gaat de waarde naar het video-geheugen Bij POKE/D wordt het lage deel van de waarde op (adres) geplaatst, en het hoge deel op (adres+1) Voorbeeld: POKE &HF3DB,1 om de toetsklik aan te zetten. PEEK Syntax: PEEK adres PEEK/V adres PEEK/D adres Werking: Geeft de waarde van het aangegeven adres. Bij PEEK/V uit het video-geheugen. Bij PEEK/D wordt de 16 bit waarde opgehaald, het lage deel uit (adres), het hoge deel uit (adres+1). Voorbeeld: PEEK/D &HFC4A om de bovengrens van het BASIC-geheugen te vinden. FILL Syntax: FILL beginadres,eindadres,8 bit waarde FILL/V beginadres,eindadres,8 bit waarde Werking: Vult het geheugen van beginadres tot en met eindadres met de aangegeven waarde. Bij FILL/V wordt het video-geheugen gevuld. Opm: In plaats van kan ook worden gegeven: . Bijvoorbeeld: FILL 100,120,0 wordt FILL 100,L 21,0 Dit geldt voor alle functies waar verplicht een begin-, en eindadres opgegeven moeten worden. Voorbeeld: FILL &HC000,&HC100,0 MOVE Syntax: MOVE beginadres,eindadres,doeladres MOVE/V beginadres,eindadres,doeladres MOVE/M beginadres,eindadres,doeladres Werking: Kopieert geheugen van beginadres tot en met eindadres naar doeladres. Bij MOVE/V van Main-RAM naar Video-RAM Bij MOVE/M van Video-RAM naar Main-RAM Opm: zie opm. bij FILL Voorbeeld: MOVE/M 2048,L 2048,&HC000 om de karakterset uit het Video-RAM naar het Main-RAM adres &HC000 te kopiëren. COMPARE Syntax: COMPARE beginadres,eindadres,ander adres Werking: Vergelijkt het geheugenblok van beginadres tot en met eindadres met het blok dat begint op ander adres. Als er verschil wordt gevonden wordt gemeld het byte uit het eerste blok, waar voor het eerst verschil optrad. Opm: zie opm. bij FILL Voorbeeld: COMPARE &H1BBF,L 2048,&HC000 om te kijken of vanaf &HC000 dezelfde karakterset staat als in het ROM (Zie voorbeeld bij MOVE). HUNT Syntax: HUNT stringuitdrukking HUNT/B beginadres,stringuitdrukking Werking: Zoekt de aangegeven string op in het geheugen, en meldt de plaats waar hij gevonden is. CTRL/C breekt af, elke andere toets laat de assembler verder zoeken. Bij HUNT/B kan men zelf opgeven waar het zoeken moet beginnen. Anders begint het op adres 0. Opm: In de stringuitdrukking mogen zowel 8 bit getallen voorkomen, als stukken tekst tussen "". Voorbeelden: "ver. 2.2",13,10,"$" of &HC3,&HA7,&H55 of 27,"3",18,27,"M",15,27,"S",0 of "Dit is een langere string",13,10,0 of "Z"+1 Deze laatste resulteert in één 8 bit waarde: 92! Voorbeeld: HUNT "NEXT" om in de BASIC-interpreter de foutmeldingentabel op te sporen. Dit commando is ook heel handig om bijvoobeeld uit te vinden waarvandaan een bepaalde subroutine wordt aangeroepen. HUNT/B &H4000,&HCD,&H0C,&H00 zoekt vanaf &H4000 naar de combinatie CD 0C 00. MON Syntax: MON [adres] MON/D "FILENAAM.ASC",beginadres,eindadres Werking: Maakt een hexadecimale afbeelding van het geheugen. Op elke regel staan de hexadecimale waarden van 8 of 16 adressen. (Dit is instelbaar, zie de SET- instructie.) Geheel links staat het adres waarop die waarden beginnen, geheel rechts staat de ascii representatie van de waarden, zodat tekst eenvoudig is te ontcijferen. Bij MON/D wordt op schijf een Ascii-file aangemaakt, waarin de monitor-uitdraai wordt geschreven, vandaar dat beginadres en eindadres verplicht moeten worden opgegeven. Bij uitvoer naar het scherm wordt niet zoals bij DIS een scrollende lijst gemaakt, maar wordt een veld van 16 regels getoond. De cursor bevindt zich linksboven in het veld. Onderaan staat het cursor-adres. Met de cursortoetsen kan de cursor op elk gewenst adres worden geplaatst; men loopt zo door het geheugen als bij een tekstverwerker door de tekst. De geheugeninhoud kan gewijzigd worden door hexadecimale waarden in te typen terwijl de cursor op het gewenste adres staat. Na elk getal gaat de cursor direct naar het volgende adres. Naast de cursortoetsen zijn de volgende toetsen van kracht: het teken dat hierna wordt getypt verschijnt niet op het scherm, maar de cursor springt naar de eerstvolgende plaats waar dit teken in de regel voorkomt. /C stop met editor. Deze toetscommando's werken niet alleen in de editor maar overal in het programma waar invoer gevraagd wordt. De volgende toetsen hebben slechts betrekking op de editor zelf. plaatst de cursor op regel 1 van de tekst. Een tweede keer drukken zet de cursor op de laatste regel van de tekst. /I voegt voor de regel waarin de cursor staat een lege regel toe. Nodig om tekstgedeelten te kunnen toevoegen. /D verwijdert de regel waarin de cursor staat. /A plaatst op de regel een blok-begin- merk (<). /Z plaatst op de regel een blok-eind- merk (>). /T haalt de bloktekens weer weg. /W wist het gemerkte blok en haalt de merktekens weg. /V verplaatst het gemerkte blok en de merktekens naar de regel waar op dat moment de cursor staat. /K kopieert het gemerkte blok naar de plaats waar op dat moment de cursor staat. De merktekens worden ook gekopieerd. In de meeste gevallen zult u die weer met CTRL/T weghalen. /P print het gemerkte blok op uit op de printer. Blokmerktekens blijven gewoon op de regel staan waar ze toegevoegd zijn. Bij verschuiven van de tekst door bijvoorbeeld wissen van een regel voorin de tekst, schuiven de merktekens netjes mee. Gemerkte blokken blijven ook bewaard bij saven en schaden het assembleren niet. Het is mogelijk, ná het merken van een blok, de editor te verlaten met CTRL/C en dit blok te saven met de SAVE/B- instructie (zie verderop). LOAD Syntax: LOAD "FILENAAM.EXT" Werking: Laad de aangegeven file in de editor. De listing die al eventueel in de editor zat, gaat hierbij verloren. Zowel ASCII-listings als listings in code formaat kunnen met die commando worden geladen. Voorbeeld: LOAD "TESTPROG.ASS" MERGE Syntax: MERGE "FILENAAM.EXT" Werking: Voegt de aangegeven file toe aan de listing die al in de editor zat. Opm: De toe te voegen file MOET in ASCII-formaat zijn weggeschreven (zie SAVE)! Voorbeeld: MERGE "SUBROUT.ASC" SAVE Syntax: SAVE "FILENAAM.EXT" SAVE/A "FILENAAM.EXT" SAVE/B "FILENAAM.EXT" Werking: Slaat de listing in de editor op op disk. Bij SAVE/A wordt de listing in ASCII-formaat wegge- schreven. Bij SAVE/B wordt een deel van de listing, namelijk een gedefiniëerd blok (zie De editor) in ASCII weggeschreven. Voorbeeeld: SAVE "TESTPROG.ASS" SCR Syntax: SCR Werking: Wist de tekst in de editor en stelt het aantal regels op 0. INFO Syntax: INFO Werking: Toont informatie over het geheugen- gebruik door de editor. Getoond worden: - Het begin en het eind van de gehele tekstbuffer, - De plaats waar de tekst in de buffer eindigt, - Het aantal tekens vrije ruimte, - Het aantal regels waaruit de tekst in de editor bestaat. LAB Syntax: LAB ["LABEL"] LAB/G ["LABEL"] LAB/C ["LABEL"] Werking: Toont de labels die in het geheugen staan met hun waarden. LAB/G toont alleen de zgn. globals, LAB/C toont alleen de constante labels (Zie het hoofdstuk over De assembler-directives). Achter het commando mag eventueel een label uitdrukking geplaatst worden, om een geselecteerde lijst te maken. Net als bij DIR worden hier de "jokers" * en ? gebruikt. De uitdrukking mag maximaal 6 letters lang zijn, en moet tussen "" staan. N.B. Dit is het enige commando waarbij het label tussen aanhalingstekens staat! Opm: De waarden van de labels worden bepaald tijdens het assembleren van de listing in de editor. Bij het saven (niet ASCII) van de listing worden de waarden meegesaved. Voorbeeld: LAB "OUT*" om alle labels die met OUT beginnen te vinden. LAB "LOOP?" om alle labels die met LOOP beginnen en maximaal 5 letters hebben te vinden. LAB/C om alle constanten op het scherm te krijgen. FIND Syntax: FIND label FIND/D label Werking: FIND zoekt in de tekst vanaf de plaats waar de cursor stond bij het verlaten van de editor, naar de eerstvolgende plaats waar het label voorkomt. FIND/D zoekt (vanaf regel 1) de plaats op waar het label geDefinieerd wordt, dus in de eerste kolom van de listing staat. Zo kan men dus snel naar een bepaald programmadeel springen zonder het regelnummer te hoeven onthouden. Als het label wordt gevonden springt WBASS2 automatisch naar de editor en zet de cursor op de regel waar het gevonden label staat. Is het label niet gevonden, dan meldt WBASS2 niets. De test-commando's. GO Syntax: GO adres Werking: Roept de machinetaalroutine die begint op aan. Pas op! Bij een fout adres leidt dit commando gemakkelijk tot een vastloper van de computer. Opm: De assembler onthoudt steeds de Z-80 registers (zie REG). Voorbeeld: GO &HC0 om een BEEPje te horen. REG Syntax: REG REG register [,waarde] REG/X REG/S REG/G Werking: REG toont de waarde van alle registers. REG geeft de waarde van het gegeven register ter verandering. Voer de nieuwe waarde in of druk op indien u de registerinhoud ongewijzigd wilt laten. Als achter REG meteen een waarde geeft, wordt die waarde direct aan het register gegeven. REG/X voert een EXX instructie uit. De registers BC, DE, HL en AF worden met hun alternatieven ver- wisseld. REG/S bewaart de actuele registerwaarden in een apart buffertje. REG/G haalt de bewaarde registerwaarden weer op. Handig om een routine die de registers verandert steeds weer aan te roepen met de goede register- inhoud. Opm: Als register wordt geaccepteerd: A,B,C,D,E,F,H,L,BC,DE,HL,SP (pas wel op!),AF,IX,IY. Voorbeeld: REG A,0 om de accu op 0 te zetten. REG HL,&HF55E om HL aan het begin van de ASCII- biffer te zetten. REG B om de waarde van register B te zien en eventueel te veranderen (druk daarna op ). Commando's voor de Z-80 output poorten. OUT Syntax: OUT poortnummer,waarde Werking: Stuurt een 8 bit waarde naar de aangegeven poort. Voorbeeld: OUT &H90,65 IN Syntax: IN poortnummer Werking: Toont op het scherm de waarde die gelezen wordt uit de aangegeven poort. Voorbeeld: IN &HA8 Speciale disk commando's. DIR Syntax: DIR ["FILENAAM.EXT"] DIR/W ["FILENAAM.EXT"] Werking: Toont de filenamen van de files die op de schijf staan. Geeft de filenaam, de grootte, de datum en tijd van wegschrijven. Bij DIR/W worden, net als onder MSX-DOS alleen de filenamen getoond, en naast elkaar op het scherm gezet. Wildcards (* en ?) zijn toegestaan. Opm: De uitvoer kunt u met regel voor regel laten verlopen, terwijl de steeds een heel scherm verder gaat, en de cursortoets-naar-beneden de uitvoer laat doorscrollen over het scherm. Voorbeeld: DIR "A:*.ASS" om te zien wat voor assembler-listings op de schijf in drive A staan. TYPE Syntax: TYPE "FILENAAM.EXT" Werking: Toont de inhoud van de aangegeven file op het scherm. De file moet wel een ASCII-file zijn, anders krijgt u aleen maar onzin op het scherm. Opm: Zie opm bij DIR. Voorbeeld: TYPE "TESTPROG.ASC" Algemene besturingscommando's. WIDTH Syntax: WIDTH waarde Werking: Stelt de schermbreedte in. Opm: mag niet kleiner zijn dan 38, en als u een MSX-2 gebruikt niet groter dan 80, en voor MSX-1 niet groter dan 40. Voorbeeld: WIDTH 40 BASIC Syntax: BASIC Werking: Verlaat de assembler en gaat naar BASIC. Opm: Weer naar de assembler kan met: CALL ASSEMBLER PRT Syntax: PRT stringuitdrukking Werking: Voert de stringuitdrukking uit naar het scherm. Of naar de printer, want zo is het mogelijk bijvoorbeeld vóór het afdrukken van een labeltabel de printer op Condensed te zetten. Opm: Zie opm. bij HUNT voor de stringuitdrukking. Voorbeeld: PRT/P 27,"3",18,27,"S",0,15,27,"M" om de Star NL-10 op condensed en elite en superscript en regelafstand 18/216 inch te zetten. (Heel kleine lettertjes dus). ? (vraagteken) Syntax: ? waarde Werking: Toont de waarde of de uitkomst van de rekenkundige uitdrukking in achtereenvolgens ascii-code, hexadecimale, decimale en binaire waarde. Handig om even snel hexadecimaal naar decimaal te vertalen of een rekensommetje te doen enz. (Zie Een eerste kennismaking.) Voorbeeld: ? &H41 geeft: =A &H41 65 &H01000001 SET Syntax: SET SET/optie,specificatie Werking: SET toont de verschillende bijzondere instellingen die betrekking hebben op het functioneren van WBASS2. Getoond worden de volgende instellingen: W Printerbreedte K Aantal kolommen monitor H Formaat hexadecimale getallen B Formaat binaire getallen E Eindadres tekstbuffer D Default diskdrive S Wel of niet saven met BAcKup G Wel of geen grafische tekens R Wel of geen DEFB en DEFW bij RST in disassembly A Hexadecimale/decimale adresuitvoer Deze instellingen kunnen worden gewijzigd door de ken-letter van de te wijzigen instelling achter de SET-opdracht op te nemen achter een slash (/). De zo ontstane instructies worden nu alle besproken: SET/W Syntax: SET/W waarde Werking: is het aantal tekens per regel dat op de printer afgedrukt kan worden. Bij het uitprinten van bijv. label-tabellen wordt hiermee rekening gehouden t.a.v. het aantal labels dat op een regel past. Voorbeeld: SET/W 136 is een handig commando als de printer op Condensed is gezet. SET/K Syntax: SET/K waarde Werking: Stelt het aantal adressen per regel in dat de monitor vertoont. kan 8 OF 16 bedragen. In het eerste geval beslaat het schermveld van 16 regels 128 bytes, in het tweede geval 256 bytes. Op een MSX-1 computer is het echter niet mogelijk op het scherm 16 kolommen te vertonen i.v.m. de beperkte schermbreedte; hier blijven het er dus 8, naar de printer of naar disk kan het echter wel met 16 kolommen. Voorbeeld: SET/K 16 SET/H Syntax: SET/H v/a,"string" Werking: Dit kommando is bedoeld om het formaat van hexadecimale getallen geheel conform uw eigen wensen in te stellen. Hoe het hex-kenmerk eruit ziet (bijv. $, &, &H, H) kan bepaald worden én of het kenmerk vóór of achter het getal komt. V/A staat voor Voor/Achter, de string bevat het hex- kenmerk. Voorbeeld: SET/H V,"&H" om &H vóór de hexadecimale getallen te zetten: 256 wordt: &H0100 SET/H A,"H" om een H achter de hex-getallen te zetten: 256 wordt: 0100H Mocht het getal nu met een letter beginnen, bijv. A342H, zou bij invoeren een dergelijk getal als een label worden aangemerkt. U moet dan nog een 0 aan het getal laten voorafgaan, dus: 0A342H. Dit commando is zeer handig in het geval dat u een oude Ascii listing voor een andere assembler in WBASS2 wilt laden. Even het hex-formaat dienovereenkomstig instellen en dan de listing laden. SET/B Syntax: SET/B v/a,"string" Werking: Geheel overeenkomstig SET/H, maar nu voor binaire getallen. SET/E Syntax: SET/E adres Werking: Stelt het eindadres in tot waar de tekstbuffer maximaal mag lopen. De tekstbuffer begint op &H8200 en loopt door tot bijv. &HD900 (hangt af van het aantal drives). U kunt dit commando gebruiken om een deel van het geheugen, bijvoorbeeld vanaf &HC000 te vrijwaren voor de editor, zodat het niet wordt overschreven als de listing groeit. Natuurlijk hebt u dan minder tekstruimte. Voorbeeld: SET/E &HBFFF om het geheugen vanaf &HC000 vrij te houden. SET/D Syntax: SET/D drivenaam Werking: Stelt de zgn. Default drive in. Als u in disk- commando's geen drive aangeeft kiest de computer de hier ingestelde drive. Voorbeeld: SET/D B SET/S Syntax: SET/S j/n Werking: Stelt in of bij het saven van een listing uit de editor, eerst een eventueel bestaande listing met dezelfde naam wordt gebackupd naar een .BAK file, zodat u niet een programma kwijt raakt als u per ongeluk een ander programma wegschrijft onder de zelfde naam. staat voor Ja of Nee. Voorbeeld: SET/S J om de backup functie in te schakelen, SET/S N om deze functie uit te schakelen (uw diskettes lopen dan niet zo snel vol). SET/G Syntax: SET/G j/n Werking: Stelt in of er grafische tekens in de ascii-kolom van de monitor mogen optreden. Geeft u hier Nee, dan worden eventuele grafiche tekens (code > 127) afgeknot door er 128 van af te trekken. (Op de meeste printers kunnen grafische tekens de boel in de war sturen.) Voorbeeld: SET/G J om de grafische tekens toe te laten. SET/R Syntax: SET/R j/n Werking: Dit zeer bijzondere commando stelt in of er bij het disassembleren speciale interpretaties worden gedaan t.a.v. sommige RST-opdrachten. RST &H30 is namelijk, voor de kenners een "inter-slot call", en wordt in programma's gevolgd door een slot-attribuut en een adres. Als nu deze functie ingeschakeld is, worden deze data direct achter een RST niet gedisassembleerd, maar netjes getoond in de goede vorm: RST &H30 ADC A,E LD C,L LD B,B wat de meeste gewone disassemblers zouden produceren, wordt heel netjes: RST &H30 DEFB &H8B DEFW &H404D Ook de RST &H8, die in basic routines altijd 1 byte achter zich aan heeft, wordt geïnterpreteerd: RST &H8 DEFB &H2C Als de functie uitgeschakeld is, gebeurt dit alles natuurlijk niet. Voorbeeld: SET/R J om deze functie in te schakelen. SET/A Syntax: SET/A d/h Werking: Stelt in of adresuitvoer die WBASS2 produceert (bijvoorbeeld bij disassembleren, bij de INFO- instructie, en op tal van plaatsen meer) in decimale of in hexadecimale vorm gebeurt, afhankelijk van uw eigen voorkeur. staat voor Decimaal/Hexadecimaal. Voorbeeld: SET/A H om WBASS2 in de hexadecimale mode te zetten. Dit houdt natuurlijk niet in dat WBASS2 nu geen decimale getallen meer herkent. De Assembler-directives. De assembler-directives zijn instructies die voorkomen in de assembler-listings die bedoeld zijn voor de assembler tijdens het assembleren. Deze instructies worden dus NIET in de commando-mode ingetypt, maar in de listing! In de inleiding kwamen we er al enkele tegen: ORG, DEFB enz. Alle directives (ook wel pseudo-instructies genoemd) worden nu besproken. ORG Syntax: ORG adres Werking: Geeft aan op welk adres het programma begint. Meestal staat deze instructie dus vooraan in de listing. ORG mag echter ook midden in een programma voorkomen, bij assembleren naar het geheugen gaat het programma dan inderdaad verder op het nieuwe adres, bij assembleren naar disk echter loopt het programma gewoon door. Hiermee is een speciale truuk mogelijk gemaakt (zie het hoofdstuk Special Features). Natuurlijk mag ook een label zijn, dat dan echter wel vóór de ORG instructie gedefinieerd moet worden. Opm: Pas op met de volgende constructie: START: ORG &HC000 ... .. Het lijkt alsof START nu de waarde &HC000 krijgt, maar het startadres achter ORG gaat pas in op de VOLGENDE REGEL. Het wordt dus: ORG &HC000 START: ... .. END Syntax: END Werking: Geeft aan dat het assembleren kan stoppen. Aan het eind van een listing mag END worden weggelaten. Bij het schrijven van een programma kan het echter handig zijn een reeds geschreven deel nog niet te assembleren, men plaatse dan een END vlak voor dit deel. EQU Syntax: label: EQU waarde Werking: Kent een toe aan een label. Handig om niet steeds bijv. te moeten opzoeken welke ascii-code de toets