Screen5-12 converter (1) Genic Clubguide, 00-00-00 DE MACHINETAALVERSIE: S C R E E N 5 / 1 2 S U P E R I M P O S E =============================================== Voor ClubGuide #9 maakte ik het programma "SUPIMPOS.M2P", dat een SCREEN 5 plaatje over een SCREEN 12 plaatje heenzette, met als resultaat een SCREEN 11 plaatje. Deze versie was in BASIC, en daarom erg traag. Alleen met behulp van de KUN compiler (versie 2.0, anders wordt SCREEN 10 niet ondersteund!), was de snelheid tot een zeer acceptabel niveau op te voeren. Ik kondigde toen al aan dat ik misschien een machinetaalversie zou maken, en die staat op deze ClubGuide Special #2. Om uit te kunnen leggen hoe de conversie werkt, is het eerst noodzakelijk om de schermopslag in de desbetreffende screenmodes te weten. Vandaar dat ik daar maar mee begin. SCREEN 5 In SCREEN 5 kunnen er maximaal 16 kleuren tegelijk op het scherm worden getoond. In een byte kunnen dus twee pixels opgeslagen worden, en wel op deze manier: MSB 7 6 5 4 3 2 1 0 LSB CL3 CL2 CL1 CL0 CR3 CR2 CR1 CR0 Hierboven ziet u een byte van het VRAM in SCREEN 5, in binaire notatie. CL staat voor Color Links, en CR voor Color Rechts. Voor beiden zijn 4 bits beschikbaar, wat inderdaad leidt tot maximaal 16 verschillende kleuren. De kleuren van de pixels (0,0) en (1,0) staan op adres 0 van het VRAM, de kleuren van de pixels (2,0) en (3,0) staan op adres 1, ..., de kleuren van de pixels (0,1) en (1,1) staan op adres 128, ..., de kleuren van de pixels (254,211) en (255,211) staan op adres 27135. Iedere regel neemt 128 bytes in beslag, wat het totaal per scherm brengt op 128*212 = 27136 bytes. SCREEN 12 Om meer dan 256 kleuren tegelijk op het scherm te kunnen zetten terwijl er toch maar 8 bits per pixel beschikbaar zijn, hebben de mensen van Yamaha (de makers van de V9958 videochip, toegepast in MSX2+ en MSX turbo R) het YJK systeem bedacht. Er zijn 4096 basiskleuren, die elk in 32 helderheden kunnen voorkomen. Dit zou een totaal van 131072 kleuren opleveren, maar omdat een aantal kleuren hetzelfde zijn blijven er 'maar' 19268 over. Vier pixels naast elkaar hebben steeds dezelfde basiskleur, dit wordt vastgelegd in de zogenaamde J en K waardes. Deze waardes worden opgeslagen in de drie minst significante bits van elke byte. Drie bits maal vier bytes maakt een totaal van twaalf bits om de basiskleur aan te geven. In twaalf bits kun je de getallen 0 t/m 4095 opslaan, de 4096 basiskleuren. De overige vijf bits van elke byte worden gebruikt voor het opslaan van de Y waarden. In vijf bits past een getal van 0 t/m 31, de 32 helderheden. In schema ziet dat er als volgt uit: MSB 7 6 5 4 3 2 1 0 LSB --------Y1--------- ----KL---- 1e pixel --------Y2--------- ----KH---- 2e pixel --------Y3--------- ----JL---- 3e pixel --------Y4--------- ----JH---- 4e pixel Net als bij SCREEN 5 staat de informatie over de pixels weer van linksboven naar rechtsonder, regel voor regel in het VRAM. Per pixel is een byte nodig, een regel vergt dus 256 bytes en het hele scherm 212*256 = 54272 bytes. SCREEN 10/11 SCREEN 10 en 11 zijn voor de V9958 precies hetzelfde. Er is alleen een verschil in de manier waarop BASIC ze behandelt. In SCREEN 10 mogen alleen de kleuren 0 t/m 15 worden gebruikt, BASIC behandelt SCREEN 10 voor de gebruiker net zoals SCREEN 5. SCREEN 11 wordt net zo behandeld als SCREEN 8 en 12, dus kleurnummers 0 t/m 255. Ik zal in het vervolg SCREEN 11 typen, maar daarvoor kunt u net zo goed SCREEN 10 lezen. In SCREEN 11 kan behalve de YJK mode ook het oude 16 uit 512 kleuren palet worden gebruikt. Hiervoor moeten we wel de helft van de helderheden inleveren, zodat er 4096 basiskleuren, 16 helderheden en 16 (uit 512) paletkleuren zijn. Het aantal verschillende combinaties van basiskleuren en helderheden is 65536, maar doordat er weer een aantal hetzelfde zijn blijven er 12499 over, en dat is toch ook niet niks! De drie minst significante bits van iedere byte bevatten weer de J en K waardes, voor de helderheid (Y) zijn de bovenste vier bits gereserveerd. De paletkleur wordt in diezelfde vier bits opgeslagen. Hoe weet de VDP nu of er een paletkleur of een helderheid bedoeld wordt? Dat wordt aangegeven met het overgebleven bit, dat ook wel het A bit wordt genoemd. Dit is bit 3. In schema ziet dit er als volgt uit: MSB 7 6 5 4 3 2 1 0 LSB --------Y1----- -A- ----KL---- 1e pixel --------Y2----- -A- ----KH---- 2e pixel --------Y3----- -A- ----JL---- 3e pixel --------Y4----- -A- ----JH---- 4e pixel Als A=1 dan wordt de Y-waarde als paletnummer opgevat en wordt de J/K waarde genegeerd. Als A=0 wordt de Y-waarde als helderheid opgevat. In vier pixels mogen beiden door elkaar gebruikt worden, de J/K waarde van een pixel in de paletkleur telt wel mee voor de pixels die wel in de YJK mode zitten! De verdeling van de pixels over het VRAM is hetzelfde als bij SCREEN 12. Nu we de basiskennis hebben gehad, kunnen we overgaan tot de kern van de zaak. HOE WERKT HET SUPERIMPOSEN Stel je hebt een SCREEN 12 plaatje en je wilt daar een tekst overheen zetten. Je maakt de tekst in SCREEN 5 en je BSAVEt dat plaatje. Op de plaatsen waar paletnummer 0 of 1 voorkomt in het SCREEN 5 plaatje, komt het SCREEN 12 plaatje tevoorschijn. Daarna start je het programma "IMPOSE.M2P" op, dat op deze ClubGuide Special #2 staat. Het programma geeft voor de rest zelf ruim voldoende tekst en uitleg. Hoe gaat het superimposen nu in z'n werk? Het SCREEN 5 plaatje wordt in PAGE 0 ingeladen en het SCREEN 12 in PAGE 1. Vervolgens wordt het SCREEN 12 plaatje omgezet naar een SCREEN 11 plaatje. Daarna begint de conversie. Eerst leest de computer een pixel van het SCREEN 5 plaatje. Is het paletnummer gelijk aan 0 of 1, dan wordt gewoon de pixel van het SCREEN 12 plaatje overgenomen. Is dat niet het geval, dan wordt het A bit gezet en wordt het paletnummer over de Y-waarde heengezet. Aan de J of K waarde wordt niets veranderd, anders worden de omliggende pixels die wel in de YJK mode staan be‹nvloed. Op deze manier wordt het hele scherm afgewerkt. Hieronder zal ik de machinetaal source bespreken die dit proces tot stand brengt. MACHINETAAL SOURCE Hieronder heb ik de volledige source gezet, die u ook op de disk kunt vinden onder de naam "IMPOSE.ASC". Dit is een ASCII file, gemaakt met WB-ASS2. Ik zal de source regelmatig onderbreken voor extra commentaar. ; Superimpose in Machine Taal ; Sc5 + Sc12 wordt samen Sc11 ; Door Stefan Boer, 16 november 1991 ; (C) SteveSoft 1991 ; Voor ClubGuide Special #2 ; Released (C) Stichting GENIC 1991 ORG &HD000 ; startadres In register IX wordt het VRAM adres in het SCREEN 5 plaatje bijgehouden, in register IY het VRAM adres in het SCREEN 12 plaatje. In register B wordt bijgehouden hoeveel lijnen er nog moeten worden afgewerkt. ; Startwaardes registers LD IX,0 ; adres sc5/page 0 LD IY,0 ; adres sc12/page 1 LD B,212 ; het scherm heeft 212 regels ; Hoofdlus LUS: PUSH BC ; bewaar register B Register B is in de hoofdlus ook nog voor andere dingen nodig, daarom wordt hij hier gePUSHed. Vervolgens worden een regel van het SCREEN 5 plaatje en een regel van het SCREEN 12 plaatje naar het RAM gekopieerd. Dit is veel sneller dan elke byte apart lezen. Omdat de instruktie LD HL,IX niet bestaat gebruik ik het truukje PUSH IX/POP HL. ; Kopieer regel screen 5 naar RAM PUSH IX ; IX bevat sc5 adres POP HL ; HL=IX LD A,0 ; PAGE 0 LD BC,128 ; 256 pixels = 128 bytes LD DE,BUF1 ; RAM doeladres CALL VRMRAM ; kopieer een regel sc5 naar ; RAM ; Kopieer regel screen 12 naar RAM PUSH IY ; IY bevat sc12 adres POP HL ; HL=IY LD A,1 ; PAGE 1 LD BC,256 ; 256 pixels = 256 bytes LD DE,BUF2 ; RAM doeladres CALL VRMRAM ; kopieer een regel sc12 naar ; RAM Het schrijven hoeft niet in ‚‚n keer te gebeuren, dat kost ten eerste 256 bytes extra RAM, en is bovendien langzamer. Wel worden de bytes rechtstreeks naar de VDP geschreven. Eerst wordt het startadres ingesteld, daarna kunnen de bytes gewoon naar Port #0 (I/O adres &H98) worden geschreven. De VDP hoogt automatisch het adres op. ; Zet de VDP klaar voor het schrijven naar screen 11 PUSH IY ; sc12 adres POP HL ; HL=IY LD A,1 ; PAGE 1 CALL STWRIT ; stel VDP in voor VRAM ; schrijven vanaf HL In het HL register wordt de positie in de SCREEN 5 buffer bijgehouden, in DE de positie in de SCREEN 12 buffer. B wordt nu weer gebruikt om te zorgen dat de lus precies het juiste aantal malen wordt doorlopen. ; Begin met de conversie LD HL,BUF1 ; HL sc5 buffer LD DE,BUF2 ; DE sc12 buffer LD B,128 ; sc5 buffer bevat 128 bytes Van beide pixels wordt gekeken of ze 0 of 1 zijn, anders wordt de Y-waarde vervangen door het paletnummer. Ik gebruik JP omdat die instruktie sneller is dan JR. (Bij de R800 zijn ze wel even snel, maar ik ga er (nog) niet van uit dat de meerderheid van de Special lezers in het bezit is van deze snelheidsduivel.) ; Eerst de linker pixel van screen 5 CNV_1: LD A,(HL) ; A=twee pixels sc5 AND &HF0 ; eerst linker pixel CP 0 ; transparant? JP Z,CNV_2 ; ja, handhaaf dan YJK CP &H10 ; zwart? JP Z,CNV_2 ; ja, handhaaf dan YJK LD C,A ; bewaar in C LD A,(DE) ; A=een pixel sc12 AND &H07 ; bewaar alleen JK-bits SET 3,A ; zet het A-bit OR C ; voeg Sc5-kleur toe JP CNV_3 ; De sc5 pixel was kleur 0 of 1, dus gewoon de sc12 ; pixel behouden CNV_2: LD A,(DE) ; A=een pixel sc12 ; Dit is voor beide gevallen gelijk CNV_3: OUT (&H98),A ; Schrijf de pixel naar het ; VRAM ; ... en dan de rechter pixel van screen 5 INC DE ; volgende pixel sc12 LD A,(HL) ; zelfde byte sc5 nog een keer AND &H0F ; nu de rechter pixel CP 0 ; transparant? JP Z,CNV_4 ; ja, handhaaf dan YJK CP 1 ; zwart? JP Z,CNV_4 ; ja, handhaaf dan YJK RLCA ; verplaats het RLCA ; kleurnummer naar RLCA ; de bovenste RLCA ; vier bits LD C,A ; en bewaar in C LD A,(DE) ; een pixel sc12 AND &H07 ; bewaar alleen JK-bits SET 3,A ; zet het A-bit OR C ; voeg de sc5 kleur toe JP CNV_5 ; De sc5 pixel was kleur 0 of 1, verander niets aan sc12 ; byte CNV_4: LD A,(DE) ; een pixel sc12 ; Dit is voor beide gevallen hetzelfde CNV_5: OUT (&H98),A ; schrijf de byte naar VRAM (Nvdr. Deze tekst was te lang voor de layout van ClubGuide Special. Daarom hebben we de tekst in twee delen op de Special gezet. Dit was het eerste deel, het tweede deel kunt u in het menu vinden.) |