home *** CD-ROM | disk | FTP | other *** search
/ Pokey's Magazine 9 & 10 / Pokeys_Magazine_09__10_1991_06___nl_Side_B.atr / crxmei2.txt < prev    next >
Text File  |  2023-02-26  |  16KB  |  1 lines

  1. Juni/juli 1991¢¢Bijgaand de voorbeeldprogramma's :¢FSCROLL.SRC¢VBI.SRC¢CRMEI.SRC¢Deze programma's zijn in ascii formaat op diskette gezet en moeten worden geladen met ENTER#D:fname.ext¢¢Deze aflevering van CODERUNNER bestaat uit twee delen.¢A) Omgaan met de MAC65¢B) Het programmeren in machinetaal.¢¢In A komen redactionele zaken aan de orde m.b.t. de door ons gebruikte assembler.¢In B komen opdrachten en het gebruik van opdrachten in machinetaal aan de orde.¢¢A)¢Omgaan met de MAC65.¢¢> LABELS¢¢In een assembler kun je een zgn. 'BRONCODE' schrijven.¢Dat betekent dat je een machinetaalopdrachten er symbolisch in kunt schrijven.¢Machinetaal bestaat uit getallen die opdrachten zijn voor de CPU. Deze getallen worden op een rijtje ergens in het geheugen gezet en door de CPU (Central Processor Unit) gelezen en uitgevoerd. In een assembler vervang je die getallen door symbolen. De assembler maakt dan van die symbolen getallen en zet deze in je geheugen of op diskette in de vorm van een programma dat je direct vanuit DOS kunt runnen.¢Machinetaalprogramma's kom je wel eens tegen in een basiclisting als een rijtje getallen.¢Bijvoorbeeld :¢Data 104,104,133,204,104,133,203 etc.¢Hexadecimaal zie je die getallen op je beeldscherm verschijnen als je programma assembleert.¢Bijvoorbeeld :¢A938¢8D02D3¢A930¢Decimaal zou dit in een basic data regel zijn :¢Data 196,56,141,2,211,169,48¢Ook worden deze getallen weleens in een 'string' gezet in basic. De waarde van het ascii tekentje vertegenwoordigt dan het getal.¢In een assembler vervangen we die getallen gemakshalve door symbolen.¢A9 noemen we LDA¢8D noemen we STA¢A938 wordt dan LDA #$38¢Wordt het getal uit een adres gehaald dan is LDA hetzelfde als A5. Dus : LDA $38 is A538¢Nog een voorbeeld : DEX, verlaag register X met 1, wordt gevormd door het getal CA.¢Het is dus heel goed mogelijk om machinetaal te produceren door het achter elkaar neerzetten van getallen.¢Dat wordt in de praktijk alleen ontzettend lastig als je naar een ander stukje in je programma moet springen. ¢Een onschuldig voorbeeld :¢LDA #$38      ¢STA $3000¢LDA $3800¢STA $5000¢DEX¢BEQ $0600¢Een voorwaardelijke spronginstructie als BEQ wordt vaak gebruikt in een machinetaalprogramma. Met deze instructie telt de cpu het aantal bytes dat voor- of achterwaarts geprongen moet worden.¢De getallen in het geheugen van bovenstaand voorbeeld zien er zo uit :¢A9 38¢8D 00 30¢AD 00 38¢8D 00 50¢CA¢F0 F2¢Waarbij de 'opcode' F0 staat voor BEQ en F2 voor het aantal te springen bytes terug. Dat kan niet zul je zeggen. F2 is decimaal 242 en de sprong naar $0600 is veel korter dan 242 bytes. Precies, de juiste sprong wordt dan ook bepaald door het aantal te springen bytes van 255 af te trekken. 255 - 242 = 13. Tel maar boven, vanaf F2 naar A9 zijn er 13 bytes.¢Je kunt je wel voorstellen dat in een programma met veel van dit soort instructies, en dat is altijd het geval, je als programmeur veel rekenwerk moet verrichten. Vergis je een keer en het programma loopt vast. Voor een klein programma'tje ben je dan al uren bezig.¢Een assembler berekent dit soort dingen voor je.¢We kunnen een bepaald adres een 'label' geven in een assembler.¢Bijvoorbeeld :¢                *=$0600¢START¢                LDA #$38¢Het label 'START' representeert hier het adres $0600¢Als we naar dat adres willen springen in ons programma hoeven we alleen die naam maar op te geven :¢                BEQ START                                                                          ¢De assembler stopt dan het juiste spronggetal in het geheugen.¢Een label kan iedere naam hebben die we maar kunnen verzinnen.¢Het is maar een aanduidingspunt.¢¢We kunnen een label ook op andere manieren getallen laten vertegenwoordigen.¢Bijvoorbeeld :¢10 STARTADRES = $0600¢20            * = STARTADRES¢Hier verlenen we met een '=' tekentje aan het label STARTADRES de waarde $0600 op regel 10.¢Daarna duiden we het echte startadres aan met behulp van dit label.¢Later in het programma kunnnen we dit steeds weer gebruiken zoals bij BEQ STARTADRES, JMP STARTADRES etc.¢We kunnen er ook aardig mee rommelen. Het aangeven van een ander adres in ons programma bijvoorbeeld.¢Je kunt gerust zetten : ¢200 * = STARTADRES + 500¢De assembler bepaalt dit adres dan door 500 op te tellen bij $0600.¢Als je een adres wilt bepalen ergens in je listing is het ook mogelijk om te zetten :¢PLAATS = *¢Waarbij plaats natuurlijk een willekeurig verzonnen naampje is. Je had ook kunnen zetten AARDAPPEL, SPACE, KLOK of noem maar op.¢In dit 'label' wordt dan het daar geldende adres gezet.¢Voorbeeld :¢10             * = $0600¢20 START      ¢30             LDA #10¢40             LDX #20¢50             LDY #30¢60             INX¢70 KLOK = *¢80             INY¢Etc.¢¢Zoals je boven ergens gezien hebt bergt de computer getallen anders op dan je zou verwachten.¢De instructie STA $3000 wordt in het geheugen gezet als :¢8D 00 30¢Het getal $3000 wordt gezet in twee bytes. Maar dit gebeurt omgekeerd. Het lage deel van het getal gaat in de eerste byte en het hoge deel gaat in de tweede byte.¢STA $5EFE wordt dan ook 8D FE 5E.¢We noemen de byte waarin het lage deel van het getal komt de 'low-byte' en de andere de 'high-byte'.¢Samen vormt het getal twee bytes wat wordt aangeduid met de term 'word'.¢In een assembler kunnen we de low- of highbyte gemakkelijk plaatsen of uitlezen.¢10            * = $0600¢20 DPLINIT¢30            LDA #<DPL¢40            STA $230¢50            LDA #>DPL¢60            STA $231¢of :¢              LDA #DPL&255¢              LDA #DPL/256¢¢Als we onze dislpaylist het label DPL hebben gegeven en we moeten de 'lowbyte' van het displaylist adres in $230 zetten en de highbyte in $231 dan kun je dat op de bovenstaande manieren doen.¢Bij regel 30 betekent '< ' de lowbyte van het adres bij het label en ' > ' de highbyte.¢In de Editor Assembler kun je alleen de tweede optie gebruiken nl. &255 voor de lowbyte en /256 voor de highbyte.¢¢Wat meer assemblertips :¢Als je een vraagtekentje typt met daarachter een getal zet de MAC65 decimaal om in hexadecimaal en omgekeerd.¢Dus : ? 1536¢geeft $0600¢en ? $0600¢geeft 1536¢¢Ook is het mogelijk om je regelnummers aan te passen.¢Zet dan REN10,10, alle regels worden dan opnieuw genummerd, beginnend met regel 10 en oplopend in stappen van 10.¢Of natuurlijk REN200,50 of wat je maar wilt.¢Met de opdracht 'FIND' kun je in de listing zoeken.¢FIND/START/ geeft ¢20 START  LDA #$38¢het eerst voorkomende woord START in de listing.¢FIND/START/,A¢geeft ¢10 START       LDA #$38¢70             BEQ START¢Zo kun je ook dingen veranderen met de opdracht REP (replace).¢REP/START/BEGIN/,A¢verandert alle woorden START in BEGIN.¢REP/START/BEGIN/,Q¢laat steeds een vraagtekentje zien bij alle voorkomende woorden start in de listing. Als je dan Y typt wordt de verandering aangebracht, return laat de dingen zoals ze zijn.¢Tot zover de assembler.¢¢B)¢Het programmeren in machinetaal.¢¢> De scroll, finescroll en de vbi.¢¢Eerst een paar nieuwe instructies :¢BPL en BMI¢Dit zijn voorwaardelijke branch instrukties.¢We hebben BEQ en BNE al behandeld.¢BPL en BMI zijn soortgelijke instrukties.¢Wat achtergonden :¢Een onderdeel van de CPU is het zgn. 'STATUSREGISTER'. We hebben al kennis gemaakt met een paar andere registers van de CPU :¢De accumulator, het X indexregister en het Y indexregister.¢Het 'processor statusregister' heeft 8 bits. Deze bits representeren de status van een zgn. flag.¢Van rechts naar links :¢¢CARRY¢ZERO¢IRQ DISABLE¢DECIMAL MODE¢BRK COMMAND¢NOT USED¢OVERFLOW¢NEGATIVE¢¢[N][V][ ][B][D][I][Z][C]¢ 0  0  0  0  0  0  1  0¢¢De instructies BNE en BEQ reageren op de Z (zero) flag.¢Is deze gezet (boven weergegeven) dan bestaat de data dus uit een nul. Een wordt met de opdracht BEQ gebrancht.¢Bij de opdracht BNE dan natuurlijk juist niet.¢De instructies BPL en BMI reageren echter op de NEGATIVE flag.¢Is data negatief (minder dan 0) dan wordt deze flag gezet.¢Zolang data niet negatief is brancht men met BPL en als het wel negatief is met BMI.¢¢[N][V][ ][B][D][I][Z][C]¢ 1  0  0  0  0  0  0  0¢¢Bijvoorbeeld :¢Spring als de inhoud van de accumulator positief is.¢LDA $3000¢CMP #0¢BPL BEST¢Spring zolang de inhoud van het X register positief is.¢DEX¢CPX #0¢BPL BEST¢Spring zodra de inhoud van X negatief wordt.¢DEX¢CPX #0¢BMI BEST¢¢In de praktijk is het verschil dus dat bij BEQ en BNE wordt gesprongen zodra een getal nul of niet nul is.¢Bij BMI en BPL wordt pas gesprongen als een getal minder dan nul is of zolang het nul of meer is.¢Als je van nul tot 7 moet tellen en pas moet springen als je de getallen 7 t/m 0 gehad hebt, kun je BEQ en BNE alleen gebruiken als je voor lief kunt nemen van 8 t/m 1 te tellen in je programma.¢10      LDX #8¢20 LOOP¢30      DEX¢40      BNE LOOP¢( Spring zolang NIET nul. )¢Geeft hetzelfde aantal 'loops' of 'lussen' als :¢10      LDX #7¢20 LOOP¢30      DEX¢50      BPL LOOP¢( Spring zolang NIET MINDER dan nul. )¢Zodra je bij het bovenste voorbeeld inplaats van een 8 een 7 zou zetten worden slechts 7 lussen doorgewerkt. Immers bij nul wordt gesprongen. Dat is dan een lus minder dan bij het onderste voorbeeld.¢Wanneer we dan ook precies van 0 t/m 7 of van 7 t/m 0 willen tellen en deze geatllen ook echt moeten gebruiken kunnen we alleen met BPL en BMI werken.¢BPL is een afkorting van : branch on plus.¢BMI is een afkorting van : branch on minus.¢¢Finescroll :¢¢Vorige keren zijn de displaylist behandeld en een horizontaal over het beeldscherm bewegende scroll-lijn.¢We lieten deze lijn bewegen door een adres in de displaylist met 1 te verhogen of te verlagen.¢Dit is de meest ruwe manier om een regel of regels te scrollen. We noemen dit een zgn. coarse-scroll.¢Onze computer heeft een mogelijkheid om dit proces te verfraaien. De letters worden dan niet per byte maar per bit opgeschoven. Dat gebeurt met behulp van een hardware routine.¢We moeten dan de displaylist voorzien van extra instructies en een routine getallen laten poken in bepaald adres.¢Voor een horizontale finescroll is dat adres $D404 voor een verticale $D405.¢Hoeveel bits we moeten verschuiven hangt af van de grafische mode waarin we werken.¢In het voorbeeldprogramma gebruiken we mode 1 (basic-mode) ofwel antic-mode 6. Hierbij moeten we zowel horizontaal als verticaal 8 bits verschuiven. Van 0 tot en met 7.¢Om gebruik te maken van deze mogelijkheid passen we eerst onze displaylist aan.¢Bijvoorbeeld :¢10 DPL ¢20         .BYTE $70¢30         .BYTE $46¢40         .BYTE $00,$30¢Antic mode 6 met het beeldscherm geheugen op adres $3000.¢Door de bits d4 of d5 te zetten van de instructie op regel 30 doen we een zgn. finescroll enable.¢Dat is heel gemakkelijk door er 16 of 32 bij op te tellen.¢( Bits : 00110000    128 64 -32- -16- 8 4 2 1 ).¢¢30          .BYTE $46 + 16¢werkt prima in onze assembler.¢Beide scrolls stelt men in door de getallen op te tellen.¢30          .BYTE $46 + 32 + 16¢¢Als we dat hebben gedaan moet er nog een routine gemaakt worden die 0 tot 7 (in dit geval) in de hardware adressen zet.¢Dat doen we in de volgende stappen :¢1) Reserveer een byte als teller (van 0 tm 7 of terug).¢2) Verhoog of verlaag dit adres met 1.¢3) Stop het getal uit deze byte in het hardware-adres.¢4) Herhaal deze procedure tot 0 of 7 is bereikt.¢5) Begin opnieuw.¢¢Het volgende programma'tje maakt het duidelijker :¢10        * = $0600¢20 FINESCROLL¢40       LDX SCHADUW¢45 ; laadt een getal uit onze teller.¢50       CPX #0¢55 ; vergelijk dit getal met 0.¢60       BMI OPNIEUW¢65 ; bij minder dan nul spring naar opnieuw.¢70       STX $D404¢71       STX $D405¢75 ; stop het anders in een 'finescroll-register'.¢85 ; verlaag de teller.¢90       DEC SCHADUW¢95       JMP FINESCROLL¢96 ; nog een keer.¢97 ; In het voorbeeldprogramma is een pauzelus ingelast omdat het programma anders te snel is.¢100 OPNIEUW¢110      LDX #7¢120      STX SCHADUW¢130      JMP FINESCROLL¢140 ;¢150 SCHADUW  .BYTE 7¢160 ;¢¢Als je een dergelijk programma'tje zou maken zou je zien dat de letters op je scherm een stukje opschuiven en dan weer terug springen.¢De letters worden dan ook alleen maar 8 bits over het scherm verplaatst, waarna ze weer in hun oude positie terug keren.¢Om ze echt langs te laten schrollen moeten we een finescroll combineren met een coarsescroll.¢We schuiven eerst de letters 8 bits op, passen dan het adres in de displaylist aan en beginnen opnieuw.¢Dat kan gemakkelijk door er bij 'OPNIEUW' een instructie aan toe te voegen.¢Bijvoorbeeld :¢105        INC BEELDGEHEUGEN¢¢Terwijl :¢1000 DPL¢1010        .BYTE $70¢1020        .BYTE $46+16+32¢1030 BEELDGEHEUGEN¢1040        .WORD SCR1¢¢We laten dus een 'coarse'scroll voorafgaan door een finescroll.¢Dit heeft een mooie vloeiende en niet schokkende scroll als gevolg.¢¢We kunnen dit proces verfraaien door de bovenstaande routine buiten ons normale programma te brengen.¢Even nog een ingewikkeld verhaal :¢Ons beeldscherm wordt opgebouwd in lijnen, beeldlijnen.¢In feite is een televisie of monitor niets anders dan een vorm van gezichtsbedrog.¢Sneller dan het oog kan volgen, worden er steeds nieuwe beelden opgezet net zoals bij een film.¢De opbouw van zo'n beeld gaat in lijnen. Links boven in beeld wordt een lijn naar rechts gemaakt. Dan een tweede lijn etc.¢Als het beeld klaar is in de rechteronderhoek wordt naar linksboven terug gesprongen voor een nieuw beeld.¢Als onze computer het beeld opbouwt, wordt tijdens de sprong van rechtsonder naar linksboven een onderhoudsprogramma'tje afgewerkt.¢Dit noemen wij de zgn. VBI ofwel Vertical Blank Interrupt.¢In deze VBI is ruimte voor de programmeur. We kunnen dus een programma'tje maken dat steeds wordt afgewerkt als de beeldschermopbouw opnieuw begint. Dat blijft dan gewoon doorlopen en ondertussen kun je een heel ander programma laten lopen op de normale manier.¢Snap je ?¢De computer werkt onze routine doorlopend automatisch af omdat we hem verteld hebben dat gaat om een 'onderhoudsroutine'.¢En ondertussen gaan wij gewoon door met een ander programma tegelijkertijd.¢We kunnen hiervan prima gebruik maken bij een scroll.¢De scroll loopt dan in een mooie regelmaat en gaat niet sneller of langzamer als we naar andere routines in ons programma springen. Het loopt buiten ons programma om gewoon door.¢¢Het instellen van een VBI routine is erg eenvoudig.¢Laadt het Y register met de lowbyte van het routineadres.¢Laadt het X register met de highbyte van het routineadres.¢Laadt de accumulator met een 7.¢Doe een JSR (jump subroutine) naar een hardwareroutine.¢¢100 VBIINIT¢110        LDY #<VBI¢120        LDX #>VBI¢130        LDA #7¢140        JSR $E45C¢150 VAST ¢160        JMP VAST¢Regel 150 en 160 zijn dus straks ons feitelijke programma wat niets anders doet als terug springen naar het eigen adres.¢Je kunt hier natuurlijk programmeren wat je wilt.¢170 ;¢180 VBI¢190 ; het scrollprogramma¢200   JMP $E462¢¢Beeindig de VBI routine met een JMP naar de routine op $E462.¢Zie voor de volledige uitwerking het voorbeeldprogramma.¢De daarin voorkomende instructies PHA, PLA, TAX, TXA, TAY, TYA kun je gewoon overnemen op de zelfde manier als daar gebruikt.¢Gebruik ze dan wel in dezelfde volgorde en op dezelfde plaats. Weglaten van al die instructies kan ook.¢Deze instructies worden een van de volgende keren behandeld.¢¢In het 2e voorbeeldprogramma zie je 2 horizontale lijnen scrollen. Tevens is boven in het beeld een voorbeeld gegeven van een verticale scrol.¢In het 1e voorbeeldprogramma zie je een diagonale finescroll zonder coarsescroll.¢¢Dit soort gecombineerde fine- en coarsescrolls worden in demo's en professionele spelletjes gebruikt.¢Er zijn natuurlijk nog wel andere manieren om dit soort effecten te bereiken.¢De hier getoonde manier is de 'officiele' manier.¢¢Experimenteer maar weer een beetje raak en probeer het effect van de behandelde (of niet behandelde) instructies te achterhalen.¢¢Veel plezier.¢Jack de Bruijn¢