Skip to content

Latest commit

 

History

History
304 lines (252 loc) · 12.2 KB

msx2_blink_besturing.md

File metadata and controls

304 lines (252 loc) · 12.2 KB
                M S X 2   B L I N K   B E S T U R I N G


      Een van de nieuwe mogelijkheden van de MSX2 video chip is de
      zogenaamde   BLINK.  Voor   screen  0   is  dit   een  extra
      mogelijkheid om  delen van  het scherm  van een  3e en/of 4e
      kleur  te voorzien.  Ook in  andere screen modes is de blink
      uitstekend te  gebruiken. Maar  in dit  artikel beperk ik me
      tot screen 0 mode 80.

      In  de  VDP  cursus  #7  is  hier  ook al  het een  en ander
      geschreven. In dit artikel zal ik proberen de mogelijkheden,
      en  vooral het  gebruik van de blink te beschrijven, met -in
      assembly geschreven- routines.


                         B A S I S   A D R E S

      Elke  positie  op het  scherm kan  in de  blink mode  worden
      gezet. Voor  elke positie  is 1  bit gereserveerd.  Als deze
      hoog  is,  is  de blink  geactiveerd. Deze  informatie wordt
      bewaard  in de  Blink tabel.  Het start adres van deze tabel
      wordt gespecifeerd  door het  zetten van  de 8  hoge bits in
      register  #3 en  #10 (A9-A16). De 9 laagste bits zijn altijd
      "1" waardoor de tabel altijd om de 512 bytes ligt. Een blink
      tabel is 512 bytes lang, dus kunnen er 512*8 posities op het
      scherm worden aangezet (1 bit per karakter).

         MSB  b7  b6  b5  b4  b3  b2  b1  b0  LSB
      r#3     A13 A12 A11 A10 A9  1   1   1
      r#10    0   0   0   0   0   A16 A15 A14

      Formules:
               VRAM adr = r#3 and &hF8 * 64
                   r#3  = VRAM adr / 64 and &h00F8 or &h07

      Hierbij laat ik r#10 gewoon nul, omdat in de praktijk de
      blink tabel nooit zo hoog in het VRAM zal worden gezet.

      Stel we willen de Blink tabel laten beginnen op VRAM adres
      &h0E00, dan zullen de register als volgt moeten worden gezet:

      r#3     &h3F    (&h0E00/64 or 7)
      r#10    &h00

      standaard  zijn   deze  registers  gevuld  met  de  volgende
      waarden:
      r#3     &h27   (VRAM adr: &h0800)
      r#10    &h00

      In  Assembly zal  een dergelijke  berekening voor  het basis
      adres er als volgt
      uitzien:

      ; Set Blink Base address.
      ; In:  H(L), VRAM adr. L, not necessary.
      BLNBAD: XOR A                   ; Hoogste bits:0
              LD      (BLN_BA),A
              LD A,H
              AND     &HFE
              LD      (BLN_BA+1),A
              RLCA
              RLCA
              AND     &HF8
              OR      &H07
              DI
              OUT     (&H99),A
              LD      A,3 OR &H80     ; r#3
              OUT     (&H99),A
              EI
              RET
      BLN_BA  DW      &H0800          ; (standaard)

      Omdat het adres altijd in stappen van 512 bytes gaan, zullen
      de 8  laagste bits  in ieder  geval "0" zijn. Vandaar dat de
      routine begind met het nul maken van de laagste bits.
      Het  VRAM  adres  wordt  bewaard,  zodat  deze  later is  te
      gebruiken bij het beschrijven van deze tabel.


                  K L E U R   E N   T I J D S D U U R

      De kleuren van de blink worden gezet in r#7. Waarbij de
      hoogste 4 bits de kleur van de karakters is, en de laatste 4
      bits de kleur van de blink achtergrond.

         MSB  b7  b6  b5  b4  b3  b2  b1  b0  LSB
      r#7     FC3 FC2 FC1 FC0 BC3 BC2 BC1 BC0

      N.B.    FC0-FC3: Foreground Colour
              BC0-BC3: Background Colour

      voorbeeld:
      We willen de karakters waar de blink mode aan staat, geel
      maken, en de achtergrond daarvan rood. Dan wordt r#7 als
      volgt:
      r#7, &hA6       (A=geel, 6=rood)

      Voor de tijd dat de blink mode aan/uit staat, moeten we r#12
      gebruiken. De 4 hoogste bits bevatten de tijd dat de kleuren
      (r#3) worden geactiveerd, de 4 laagste is de tijd dat de
      originele karakter kleuren weer worden geactiveerd.

         MSB  b7  b6  b5  b4  b3  b2  b1  b0  LSB
      r#12    BC3 BC2 BC1 BC0 CC3 CC2 CC1 CC0

      N.B.    BC0-BC3: Blink Colour
              CC0-CC3: Charakter Colour

      De  tijd wordt aangegeven in "vertical scans", dus elke 1/50
      (of 1/60) seconde.

      Met deze  4 genoemde  registers is  de initialisatie  van de
      blink  verklaard.  Alles  wat  we  nu  nog  moeten  doen  is
      daadwerkelijk de scherm posities aan of uit zetten.


                      S C H E R M   P O S I T I E

      De posities van de blink worden als volg berekend:
      (uitgaand van een width 80 scherm)

      [basis adres] + (Yx10) + (X/8)

      Omdat  er per  bit wordt gerekend, wordt de X gedeeld door 8
      (8  bits).  Omdat  er  maximaal 80  karakters op  een scherm
      kunnen, worden  er dus  10 bytes  gebruikt voor  een Y  lijn
      (80/8).

      Voordat we de blink gaan gebruiken, doen we er goed aan om
      eerst de hele blink tabel leeg te maken. Een soortgelijke
      routine:

      ; Clear Blink table.
      BLNCLR: LD      HL,(BLN_BA)        ; basis adres
              LD      C,0                ; laagste 64k.
              LD      DE,512             ; totaal aantal bytes
              XOR     A                  ; vul met nul
              JP      FILVRM             ; een "Vul VRAM" routine

      De "FILVRM" routine in dit voorbeeld heeft de volgende
      data nodig:
      HL/C, VRAM adres        C bepaalt welk VRAM blok (64k.)
      DE, lengte
      A, vuldata

      Natuurlijk kunt u uw eigen routine ook gebruiken.

      Nu komt eigenlijk het moeilijkste, een routine maken die een
      blink  positie aan  of uit zet. Hierbij moet het VRAM adres,
      en  het   start  bit   worden  berekend.   Dit  laatste   is
      noodzakelijk omdat immers per bit wordt gerekend. Ook is het
      belangrijk,  dat de  bits die al aan/uit stonden onveranderd
      te laten!

      De volgende routine zal het VRAM start adres berekenen:

      ; Calculate Blink VRAM adr.
      ; In:  H, pos-X.  L, pos-Y
      ; Out: HL, VRAM adr.
      C_BLAD: LD      A,H
              RRCA            ; X/8
              RRCA
              RRCA
              AND     &HF8
              LD      H,A
              LD A,L          ; Yx10 (Yx2 + Yx8)
              RLCA
              AND     &H3F
              LD      L,A     ; L=Yx2
              RLCA            ; Yx4 (+Yx4 = Yx8)
              RLCA
              ADD     A,H     ; (Ax8) + (Ax2)
              ADD     A,L     ; + X
              LD      L,A
              LD      A,(BLN_BA+1)    ; basis adres
              LD      H,A
              LD      (BLN_AD),HL     ; bewaar VRAM adres
              RET

      BLN_AD  DW      &H0800

      Deze routine  is uiters  snel qua  berekening, maar  heeft 1
      beperking,  dat er  maar 256  VRAM adressen  (2048 posities)
      kunnen worden  berekent Hierdoor  is het start adres bekend,
      nu nog het start bit.

      Door  gebruik  te  gaan  maken  van  een  vermenig vuldigins
      routine, is dit wel mogelijk maar dat gaat dan wel ten koste
      van  de snelheid.  Voor dergelijke rekenroutine verwijs ik u
      naar de Z80 REKEN cursus van Alex van der Wal (special #5).
      Een  blink  adres  berekening  routine  gebruik  makend  van
      vermenig vuldiging:

      ; calc Blink VRAM-adres.
      ; In:  HL, XXYY (blink pos.)
      C_BLAD: LD    A,H
              AND   &HF8
              RRCA
              RRCA
              RRCA                  ; /8
              PUSH  AF
              LD    A,L             ; Y*10
              LD    DE,10
              CALL  HL=ADE          ; Uit: HL= A x DE
              POP   AF
              LD    C,A
              LD    B,0
              ADD   HL,BC
              LD    BC,(BLN_BA)
              ADD   HL,BC
              LD    (BLN_AD),HL
              RET

      A  bevat nu een bit waarmee moet worden gestart. Stel nu dat
      we als  X positie 5 nemen. Het start bit (in reg. A) zal dan
      als volgt zijn: (uitgaand dat X de waarde 0-79 kan hebben)

      A, &b00000100   ; 5e bit van links is hoog.

      Met  deze start  gegevens kunnen  we nu  een scherm  positie
      voorzien  van  de blink  mode. De  volgende routine  zal een
      (aantal) posities aan (kunnen) zetten:

      ; Set blink position ON.
      ; In:  H, pos-X. L, pos-Y. B, total positions
      BLNON:  PUSH    BC
              LD      A,H
              PUSH    AF
              CALL    C_BLAD          ; VRAM adres
              POP     AF
              CALL    C_STBT          ; start bit
              POP     BC
              LD      E,A
      BLON.1  LD      C,0             ; laagste 64k.
              CALL    SR_VRM          ; Zet VDP in lees mode.
              IN      A,(&H98)        ; Lees oude blink bits.
              PUSH    AF
              CALL    SW_VRM          ; Zet VDP in schrijf mode.
              POP     AF
      BLON.0  OR      E
              RRC     E               ; Schuif bit
              JR      NC,BLON.2       ; Laagste bit gehad?
              OUT     (&H98),A        ; ja, schrijf Blink
              INC     HL              : volgende 8 posities.
              DJNZ    BNON.1
              RET
      BLON.2  DJNZ    BLON.0
              OUT     (&H98),A
              RET

      De routines  "SR_VRM" en  "SW_VRM" zorgen er voor dat de VDP
      in  lees of schrijf mode wordt gezet. Natuurlijk kunt u hier
      ook uw eigen routines gebruiken.
      De "OR  E" instructie zorgt ervoor dat de desbetrefende bits
      worden gezet, zodra het laatste bit gedaan is (b0), wordt de
      volgende VRAM positie (8 bits) gebruikt.

      Een routine die of een (of meer) blink positie(s) zet:

      ; Reset Blink position.
      ; In:  H, pos-X. L, pos-Y. B, total pos.
      BLNOFF: PUSH    BC
              LD      A,H
              PUSH    AF
              CALL    C_BLAD          ; VRAM adres
              POP     AF
              CALL    C_STBT          ; start bit
              POP     BC
              CPL                     ; draai bits om
              LD      E,A
      BLOF.1  LD      C,0             ; laagste 64k.
              CALL    SR_VRM          ; Zet VDP in lees mode.
              IN      A,(&H98)        ; Lees oude blink bits.
              PUSH    AF
              CALL    SW_VRM          ; Zet VDP in schrijf mode.
              POP     AF
      BLOF.0  AND     E               ; zet 1 bit uit.
              RRC     E               ; Schuif bit
              JR      C,BLOF.2        ; Laagste bit gehad?
              OUT     (&H98),A        ; ja, schrijf Blink
              INC     HL              : volgende 8 posities.
              DJNZ    BNOF.1
              RET
      BLOF.2  DJNZ    BLOF.0
              OUT     (&H98),A
              RET

      Deze  routine is  feitelijk het  zelfe als  "BLNON", maar nu
      wordt  de  instructie "AND  E" gebruikt  om de  bits uit  te
      zetten.
      Met deze  2 laatst  genoemde routines is het natuurlijk heel
      makelijk  om een  routine te  maken die  een Blok aan of uit
      zet, waarbij  bijvoorbeeld "B"  het aantal  X posities is en
      "C"  het  aantal  Y  posities.  Hierbij  kan  gebruik worden
      gemaakt van het VRAM adres wat opgeslagen staat in "BLN_AD".
      Nu  hoeft het  adres, en  het start  bit maar  1 keer worden
      berekend. Het  VRAM adres van de volgende Y posities ligt 10
      hoger.

      Met  deze routines  en uitleg  moet het  mogelijkzijn om  de
      Blink voledig te benutten in screen 0.

                                             R�man van der Meulen