R800 [2/2] Stefan Boer, 01-09-94 VERMENIGVULDIGEN Echt super zijn de vermenigvuldigingsinstructies van de R800. De instructie MULUB (MULtiply Bytes) vermenigvuldigt A met B, C, D of E en zet het 16 bits antwoord in HL. Dit gaat razendsnel, deze instructie gebruikt slechts 14 klokpulsen (1.96 micro- seconde). De instructie MULUW (MULtiply Words) vermenigvuldigt HL met BC of SP (zal in de praktijk meestal BC zijn), en zet het antwoord in DE en HL, waarbij de hoogste bits in DE terecht komen. Deze instructie duurt slechts 5.03 microseconde (36 klokpulsen)! Deze twee instructies zijn ontzettend krachtig en maken zeer snelle "realtime calculated" animaties mogelijk, bijvoorbeeld vectorgraphics. Ook voor fractals is dit erg handig, die kunnen nu veel en veel sneller worden berekend. Een leuke vergelijking met de Z80 is dat de MULUW HL,BC instructie op de R800 net zolang duurt als een CALL instructie op de Z80!! Bij de Z80 moet voor vermenigvuldigen een aparte routine worden geschreven, en als je die met een CALL aanroept is de R800 in de tussentijd al klaar met de complete vermenigvuldiging. U begrijpt wel dat de R800 als het om vermenigvuldigen gaat veel meer dan acht maal sneller is, ik denk wel honderd maal sneller. Bovendien spaart het een hoop programmeertijd, want berekeningen kunnen een stuk makkelijker worden geprogrammeerd. Onderstaand voorbeeld is een routine die HL=A*B uitrekent. Op de R800 is een instructie daarvoor voldoende: MULUB A,B. Deze instructie is sneller dan een CALL instructie bij de Z80! Bij de Z80 zou je dan ongeveer zo'n routine krijgen: ; MULUB A,B voor de Z80 ; Door Stefan Boer ; Voor Sunrise Special #1 ; Werking: HL=A*B ; In: A,B ; Uit: HL ; Gebruikt: DE ; Methode: Herhaald optellen MULUB: LD HL,0 LD E,A LD D,0 ; LD DE,A XOR A CP B RET Z ; B=0, dan antwoord 0 MULTI: ADD HL,DE DJNZ MULTI ; tel B maal DE bij HL op RET U kunt zien dat dit heel wat meer bytes en tijd in beslag neemt, de CALL MULUB duurt op de Z80 al langer dan de MULUB A,B instructie op de R800. R ASSEMBLER Nu denkt u misschien dat u een nieuwe assembler nodig heeft als u software voor de R800 wilt ontwikkelen. Dit is zeker niet het geval! Alle bestaande Z80 assemblers kunnen gewoon worden gebruikt. Dit is ook de reden waarom er nog geen speciale R800 assembler op de markt is gebracht. Het zou trouwens ook verwarrend zijn voor een programmeur die de Z80 assemblertaal al beheerst, om de nieuwe mnemonics voor de R800 te leren. "En de nieuwe instructies dan?" hoor ik u denken. Nu, die kunt u gewoon met DEFB instructies simuleren! Alleen de disassembler zal hier een beetje van in de war raken, maar dat is toch niet zo'n ramp? Ik zal nu voor alle nieuwe instructies uitleggen hoe ze met een gewone Z80 assembler (zoals WB-ASS2) kunnen worden gebruikt. INDEXREGISTERS Bij de indexregisters IX en IY is het ontzettend makkelijk. Het is u vast al wel eens opgevallen, dat de opcodes hetzelfde zijn als die voor de instructies voor HL, behalve dan dat er een extra code voor staat. Die code is &HDD voor IX en &HFD voor IY. Een voorbeeld: Mnemonic: Opcode: LD HL,&H1BBF 21 BF 1B LD IX,&H1BBF DD 21 BF 1B LD IY,&H1BBF FD 21 BF 1B U kunt voor alle instructies met IXL, IXH, IYL en IYH de assembler op een heel eenvoudige manier voor de gek houden. Voor IXL en IYL zet u een L en voor IYH en IXH een H. Door er een DEFB &HDD voor te zetten wordt de L resp. H voor de R800 IXL resp. IXH, met een &HFD hetzelfde voor IY. Voorbeelden: DEFB &HDD LD A,L ; LD A,IXL DEFB &HFD LD L,H ; LD IYL,IYH DEFB &HDD LD H,B ; LD IXH,B Zoals u ziet is de instructie LD IXH,IYL niet mogelijk, u kunt immers niet de code voor IX n de code voor IY voor een instructie plaatsen. Maar verder is alles mogelijk, zie de instructietabellen in de Sunrise Times. IN F"9c; Voor deze instructie kunt u gewoon DEFB &HED,&H70 invullen. U kunt dat het beste zo in de assemblerlisting zetten: DEFB &HED,&H70 ; IN F,(C) Zo kunt u goed zien dat het geen data bytes zijn maar eigenlijk gewoon een opcode. Door een foutje in die assemblers zullen sommige assemblers dit overigens disassembleren als IN (HL),(C). Dit is een niet bestaande instructie, maar het komt omdat IN F,(C) voor de R800 gewoon een speciaal geval is van IN r,(C). Bij andere instructies (bijvoorbeeld LD A,(HL)) wordt (HL) weergegeven door dezelfde bits als F bij de IN F,(C) instructie, vandaar de fout. MULUB EN MULUW Voor deze instructies kunt u de instructietabellen van de R800 die in de Sunrise Times staan afgedrukt gebruiken. U kunt de opcodes aan de hand daarvan samenstellen (zie het stukje over opcodes samenstellen), en ze met DEFB instructies in de code opnemen. Bijvoorbeeld: DEFB &HED,&B11000001 ; MULUB A,B Ook hier is het weer aan te raden om bij het commentaar de R800 mnemonic in te vullen, zo houdt u uw assemblerlistings leesbaar. SCHAKELEN Nu zit ik wel een lang artikel over de R800 te schrijven, maar als u niet weet hoe u deze wonderprocessor moet selecteren heeft u daar nog niet veel aan. In het MAIN ROM van de MSX turbo R zitten vier nieuwe BIOS routines, waarvan er twee voor het schakelen tussen de Z80 en de R800 zijn bedoeld. Dat zijn: CHGCPU &H0180 Selecteer CPU Invoer: A register MSB 7 6 5 4 3 2 1 0 LSB LED 0 0 0 0 0 X X LED=1: led wordt bestuurd LED=0: led wordt niet bestuurd XX=00: Z80 XX=01: R800 ROM XX=10: R800 DRAM Gebruikt: AF GETCPU &H0183 Bepaal huidige CPU Invoer: - Uitvoer: A register 0: Z80 1: R800 ROM 2: R800 DRAM Over LED is wegens foutieve publikaties in andere Nederlandse MSX bladen een misverstand ontstaan. Dit bit bestuurt niet het led (1=aan, 0=uit), maar bepaalt of de status van het led (aan of uit) door de gekozen CPU moet worden beinvloed! Stel u zit in R800 mode en het lampje brandt. Doet u nu LD A,0 en daarna CALL CHGCPU, dan zal de Z80 uitgaan, maar het lampje blijft branden. Bit 7 van register A (LED) is immers 0, en dus zal het led niet door de gekozen CPU (Z80, normaal gesproken moet het lampje dus uit!) worden benvloed. Andersom kan ook, als u in Z80 mode zit (lampje uit) en u selecteert de R800 mode door een CALL &H180 te geven terwijl het A register de waarde 1 bevat (R800), dan zal de R800 wel aangaan, maar het lampje niet! Bij "normaal" gebruik van deze BIOS routine, waarbij de stand van het lampje in overeenkomst is met de actieve processor (aan=R800, uit=Z80), dient u dus een van de volgende drie waardes te gebruiken: &H80 Z80 &H81 R800 ROM &H82 R800 DRAM U kunt met GETCPU opvragen welke processor er op dat ogenblik actief is. U kunt op de volgende manier dus het lampje in de goede stand zetten: CALL &H183 ; welke CPU actief? SET 7,A ; LED besturen aan CALL &H180 ; CPU zelfde, LED besturen DRAM Ik heb het in bovenstaande tekst vrolijk over DRAM, zonder uit te leggen wat dat nou eigenlijk inhoudt. De DRAM mode is een slimme truuk, die ook door andere moderne computers wordt gebruikt. In feite is het niet de R800 die voor de DRAM mode zorgt, maar de S1990. Bij de Z80 maakt het niet uit of er RAM of ROM wordt gelezen, dit gaat beiden even snel. Omdat er in de turbo R dezelfde ROMs worden gebruikt als in een MSX1/2/2+, moeten die op een langzame snelheid worden gelezen. Telkens als de R800 ROM moet lezen, schakelt hij even terug naar een langzamere snelheid. Vandaar dat op een R800 het lezen van RAM sneller is dan ROM, want in de turbo R wordt "snel" RAM gebruikt, zodat terugschakelen niet nodig is. Vooral in BASIC wordt er continu uit de ROM gelezen. De BASIC zelf staat immers op ROM! De R800 ROM mode is daarom in BASIC helemaal niet zo snel, omdat er telkens wordt teruggeschakeld naar een lagere snelheid. De oplossing is de DRAM mode. ROM IN RAM Bij het opstarten van de computer wordt de 64 kB meest gebruikte ROM naar de bovenste 64 kB van het RAM gekopieerd. De turbo R heeft dan dus 64 kB minder werkgeheugen over. De ROM die gekopieerd wordt is: MAXPGE-3: MAIN ROM 0000-3FFF MAXPGE-2: MAIN ROM 4000-7FFF MAXPGE-1: SUB ROM MAXPGE : KANJI ROM Voor MAXPGE moet u het hoogste memorymapper segment invullen. De FS-A1ST heeft bijvoorbeeld 256 kB, dat zijn 16 memorymapper segmenten van 16 kB. Daar het nummeren bij 0 begint, is MAXPGE dus gelijk aan 15. De SUB ROM staat dus in memorymapper segment 14. Als de DRAM mode wordt geselecteerd komt de S1990 in actie. Wordt nu een van de hierboven genoemde ROMs gelezen door de R800, dan zorgt de S1990 ervoor dat niet de ROM maar de RAM (waarin het ROM is gekopieerd) wordt gelezen. De R800 hoeft dan niet te wachten op het langzame ROM, en werkt een stuk sneller. De S1990 zorgt ervoor dat er niet in de DRAM kan worden geschreven (zo heet de tot ROM verklaarde RAM), en zorgt er tevens voor dat het RAM dat voor de DRAM wordt gebruikt niet meer te gebruiken is. Probeert u er toch iets uit te lezen, dan zal dat altijd de waarde &HFF opleveren. ROM MODE EN DRAM MODE Er zijn dus twee verschillende R800 standen. Bij de R800 ROM mode gaat het net als bij de Z80 mode, er wordt gewoon ROM gelezen. Vandaar de naam ROM mode. Deze mode is vooral onder BASIC langzaam, omdat daar veel ROM wordt gelezen. Onder machinetaal springt de computer ook 60 keer per seconde naar ROM, voor de interrupt routine op &H38. Ook als het machinetaalprogramma de BIOS gebruikt zal er naar het ROM worden gesprongen. Daarom heeft het selecteren van de DRAM mode ook bij machinetaal zin, al is heeft het minder effect dan bij BASIC. De R800 ROM mode heeft als belangrijkste voordeel dat het volledige RAM geheugen vrij is als werkgeheugen. De DRAM mode is sneller, maar kost wel 64 kB geheugen. U kunt dus zelf per situatie beslissen of u de ROM mode of de DRAM mode wilt gebruiken. IN ROM POKEN U kunt bij de turbo R als het ware in het ROM POKEn. Dit gaat als volgt: - Selecteer de R800 ROM mode (of Z80 mode) In de bovenste 64 kB van de memorymapper staat nu een kopie van de ROM, waar u net zoveel in kunt knoeien als u wilt. Als u klaar bent - Selecteert u de R800 DRAM mode Nu wordt het RAM waar u zojuist in hebt geknoeid gebruikt voor de DRAM, en dus hebt u als het ware in de ROM gePOKEt! PAS OP Je zou misschien denken dat het ROM elke keer dat de DRAM wordt geselecteerd in het RAM wordt gekopieerd. Dat is niet zo, anders zou bovenstaande truuk ook niet werken. De reden hiervoor is dat het kopi ren van 64 kB toch wel even tijd kost, en op die manier zou de CHGCPU routine veel te langzaam worden. Het ROM wordt alleen bij een reset in het RAM gekopieerd, en hiermee dient terdege rekening gehouden te worden! Als u de DRAM mode selecteert terwijl het RAM dat voor de DRAM mode wordt gebruikt verminkt is, kan dit onverwachte gevolgen hebben! DISKGEBRUIK EN R800 Het aansturen van de diskdrive gaat niet goed onder R800 stand. De diskcontroller kan bij zo'n hoge snelheid de processor blijkbaar niet bijhouden. Tenminste, bij het saven. Het laden onder R800 stand gaat prima, maar bij saven kan er van alles mis gaan. Het gaat niet altijd fout, maar vaak treedt er een Disk I/O error op of er wordt gewoon niets gesaved. Bij MSX-DOS2.31/MSX Disk BASIC 2.01 is daar rekening mee gehouden. Bij elke diskactie wordt de R800 stiekem uitgezet. Ik schrijf "stiekem", omdat het lampje niet wordt uitgezet. Dat blijft branden, omdat de R800 wordt uitgezet door LD A,0 CALL &H180 ; R800 uit, lampje niet En u hebt aan het begin van het artikel al geleerd dat het lampje dan niet uitgaat. Hierdoor wordt behalve het saven ook het laden vertraagd, wat eigenlijk niet nodig is. De ontwikkelaars van de turbo R hebben dit in de MSX- DOS2.31/Disk BASIC 2.01 ROMs ingebouwd, omdat dat normaal gesproken onder R800 stand wordt gedraaid. DOS MODE Onder DOS1 mode (MSX-DOS1.11/Disk BASIC 1.0) wordt dit niet gedaan. Die stand is tenslotte bedoeld voor het uitvoeren van MSX1/2/2+ programma's, en die werken toch onder Z80 stand. Toch zullen programmeurs vaak MSX turbo R software voor DOS1 mode ontwikkelen, omdat de geheugenhuishouding van DOS2 nogal irritant is. De R800 wordt dan dus aangezet onder DOS1 mode, terwijl de diskROM daar geen rekening mee houdt. In het technical databook van de turbo R staat dan ook dat als een programmeur toch de combinatie DOS1/R800 gebruikt, hij bij elke diskactie de R800 uit moet zetten. De programmeur van Seed of Dragon heeft zich daar netjes aan gehouden; elke keer als het disklampje gaat branden zie je bij dat spel het R800 lampje uitgaan. Hoewel dit niet in het technical databook staat, kan de R800 bij het laden rustig aan blijven staan. Alleen bij saven zijn er problemen. Onder R800 stand gaat het laden zelfs aanmerkelijk sneller! MicroCabin wist dit blijkbaar ook, want bij bijvoorbeeld Fray wordt de R800 alleen uitgezet als er wordt gesaved. Conclusie: ZET DE R800 ALTIJD UIT ALS ER IN DOS] MODE NAAR DISK WORDT GESCHREVEN Nogmaals: bij laden kunt u de R800 rustig aan laten staan. PAGE MODE ACCESS Bij het bekijken van een artikel over de R800 in een Japans blad kwam ik de term "DRAM page access" tegen, en ik had eerst geen flauw idee wat dat was. Later kwam ik er wel achter. Wanneer van het adres in de externe databus de high-byte niet verandert, zal de R800 de high-byte van het adres niet opnieuw op de adresbus plaatsen (lijkt heel logisch, maar de Z80 kent deze truuk niet!) Een "page" is in de processorwereld een stukje geheugen van 256 bytes, dat op een 256-byte grens begint, dus &H??00 - &H??FF. Verwar dit niet met de bij MSX bekende term "page", een stuk geheugen van 16 kB. Het hierboven beschreven truukje dat de R800 gebruikt heet "Page mode access" en verhoogt de snelheid nog eens met ongeveer een factor twee. De programmeur kan met "paged DRAM access" maximaal van deze truuk gebruik maken. Paged DRAM access betekent dat alle geheugentoegang van een routine (dus ook de routine zelf) in dezelfde page staat (bijvoorbeeld &HD000-&HD0FF). Dit is wel zeer beperkt, want met alle geheugentoegang bedoel ik dan dus echt ALLE geheugentoegang, inclusief stack, variabelen en constanten. Het uitzetten van de interrupts is in verband met die stack dan ook ten zeerste aan te raden. Maar deze moeite wordt wel beloond met een ultra-snelle routine! We begrijpen nu ook beter hoe het komt dat een LD A,B instruktie op de R800 tien keer zo snel is dan op de Z80, terwijl een LD A,(HL) maar 5,3 keer zo snel is. Bij het uitvoeren van een instructie hoort namelijk ook het ophalen van de opcode uit het geheugen. Omdat bij een LD A,B instructie de externe adresbus niet wordt gewijzigd, hoeft bij het ophalen van de volgende opcode (meestal) alleen de low-byte van de externe adresbus te worden veranderd. Bij de LD A,(HL) instructie is de externe adresbus wel veranderd, zodat zowel de low- als de high-byte van het PC register (Program Counter) naar de externe adresbus moeten worden verplaatst. TOT SLOT Tot slot wil ik Alex Wulms nog bedanken voor zijn medewerking, een gedeelte van de informatie in dit artikel is van hem afkomstig. De overige informatie heb ik zelf uitgevonden of komt uit Japanse bladen. De R800 is (inclusief toetsenbord, diskdrive, kast en een zooitje chips onder de naam FS-A1GT) te koop bij MSX Club Gouda voor f1795,-. Verplicht voor elke MSX'er die bij de tijd wil blijven (maar nu nog een antieke MSX2 heeft)! Stefan Boer |