Skip to content

Latest commit

 

History

History
314 lines (250 loc) · 13 KB

vdp_cursus_12.md

File metadata and controls

314 lines (250 loc) · 13 KB
             M S X 2 / 2 +   V D P   C U R S U S   ( 1 2  )
                                                            
      
      Welkom bij  het twaalfde deel van de inmiddels legendarische 
      VDP  cursus.  Ook  deze  keer  gaan we  weer een  ML routine 
      bespreken.  Dit keer  is het  een routine  om tekst  met een 
      grafische karakterset  op het  scherm te zetten in SCREEN 5. 
      De  theorie die  hiervoor nodig  is is  allemaal al  aan bod 
      geweest, dus we beginnen meteen met de source.
      
      In dit  voorbeeld gebruiken we een 6x8 karakterset, maar het 
      is  heel  eenvoudig  om  de  routine  aan  te  passen  zodat 
      karakters  van andere  formaten worden  gebruikt. Ik geef de 
      routine hier in de BASIC uitvoering, maar hij kan natuurlijk 
      ook gewoon in een puur ML programma worden gebruikt.
      
      
      ; P R T E X T . A S M 
      ; Zet tekst op scherm in SCREEN 5 met COPY (font in page 3)
      ; Aanroepen door coordinaten in te POKEn:
      ; POKE &HD003,X : POKE &HD004,Y
      ; en daarna U$=USR("tekst")
      ; Door Stefan Boer, (c) Ectry 1993
      ; VDP Cursus Sunrise Magazine #7
      
              ORG   &HD000
      
              JP    PRTEXT
      XCOOR:  DB    0
      YCOOR:  DB    0
      
      
      Dit  ziet er  misschien een  beetje vreemd  uit, maar dit is 
      gedaan om het aanroepadres en de adressen van de co�rdinaten 
      die moeten worden ingePOKEt standaard te houden.
      
      
      PRTEXT: LD    A,(DE)
              LD    B,A
              INC   DE
              LD    A,(DE)
              LD    L,A
              INC   DE
              LD    A,(DE)
              LD    D,A
              LD    E,L             ; DE=startadres, B=lengte
      
      
      Als je een ML routine vanuit BASIC aanroept met
      
              U$= USR(string)
      
      dan  staat in  het DE  register het  begin van de zogenaamde 
      "string desriptor".  Deze string descriptor bestaat uit drie 
      bytes.  De eerste  is de lengte van de twee strings, de twee 
      andere bytes  geven het  beginadres in  het geheugen  staan. 
      Hier zetten wij het beginadres in DE en de lengte in B.
      
      
              LD    A,(XCOOR)
              LD    (COPDAT+4),A    ; DX invullen
              LD    A,(YCOOR)
              LD    (COPDAT+6),A    ; DY invullen
      
      
      Hier  worden   de  ingePOKEte  co�rdinaten  in  de  copydata 
      ingevuld.
      
      
      PRINT:  PUSH  BC              ; bewaar aantal karakters
              LD    A,(DE)          ; haal teken
              INC   DE              ; DE wijst naar volgende teken
              SUB   32              ; eerste karakter is spatie
              ADD   A,A             ; A=A*2
              LD    C,A
              LD    B,0             ; LD BC,A
              LD    HL,CORTAB       ; startadres coordinatentabel
              ADD   HL,BC           ; bereken adres in tabel
      
      
      We maken  gebruik van  een co�rdinatentabel omdat de routine 
      dan  met elke  willekeurige grafische karakterset kan worden 
      gebruikt. We  trekken 32  van de ASCII code van het teken af 
      en  vermenigvuldigen dat  met twee. Vervolgens tellen we dit 
      bij het startadres van de tabel op en we hebben het adres in 
      de tabel  waar de  co�rdinaten van  het desbetreffende teken 
      staan.
      
      
              LD    A,(HL)
              LD    (COPDAT),A      ; SX invullen
              INC   HL
              LD    A,(HL)
              LD    (COPDAT+2),A    ; SY invullen
      
      
      Die  co�rdinaten worden  hier uit  de tabel gehaald en in de 
      copydata gezet.  Zoals we gewend zijn werken we weer met een 
      blokje copydata van 15 bytes. De benodigde gegevens (source, 
      destination,  etc.) kunnen  dan zonodig  door het  programma 
      worden veranderd  en het  uitvoeren van het commando door de 
      VDP is een kwestie van een simpele OTIR.
      
      
              LD    HL,COPDAT
              LD    BC,&H0F9B
      WACHT:  LD    A,2
              CALL  RDSTAT          ; lees statusregister
              BIT   0,A
              JR    NZ,WACHT
      
      
      Eerst wachten we netjes totdat de VDP klaar is door op bit 0 
      van S#2  te testen.  Doen we  dit niet,  dan kan dat vreemde 
      effecten  hebben. Zeker  als de routine op een turbo R onder 
      R800 stand  wordt gedraaid,  omdat de kans dan groter is dat 
      de  VDP nog  niet klaar  is met  het kopi�ren  van de vorige 
      letter  als  hij hier  is aangeland.  De data  voor de  OTIR 
      (HL=beginadres,  B=aantal  bytes,  C=I/O  poort)  zetten  we 
      alvast klaar.
      
      
              DI
              LD    A,32
              OUT   (&H99),A
              LD    A,17+128
              OUT   (&H99),A
              EI
              OTIR                  ; voer copy uit
      
      
      Hier schrijven we de waarde 32 naar R#17, hiermee selecteren 
      we  het startregister  voor het indirect registers schrijven 
      van de  VDP. Met  de OTIR wordt het blokje met copydata naar 
      Port  #3 gestuurd, waardoor deze bytes netjes in de commando 
      registers (32 t/m 46) terecht komen en de VDP de letter naar 
      het scherm zal kopi�ren.
      
      
              LD    A,(COPDAT+4)    ; oude DX
              ADD   A,6             ; volgende positie
              LD    (COPDAT+4),A    ; nieuwe DX invullen
      NXTKAR: POP   BC
              DJNZ  PRINT
              RET
      
      
      Hier  wordt  er 6  bij de  x co�rdinaat  opgeteld, zodat  de 
      volgende  letter  netjes naast  deze komt  te staan.  De lus 
      wordt afgesloten met een DJNZ.
      
      
      ; Statusregister lezen. In: A=register, Uit: A=data
      
      RDSTAT: DI
              OUT   (&H99),A
              LD    A,128+15
              OUT   (&H99),A        ; selecteer statusregister
              NOP                   ; geef VDP tijd om data
              NOP                   ; klaar te zetten
              IN    A,(&H99)
              EX    AF,AF
              XOR   A
              OUT   (&H99),A
              LD    A,128+15
              OUT   (&H99),A        ; selecteer S#0
              EI
              EX    AF,AF
              RET
      
      
      Dit  is  een  standaardroutine  voor  het  uitlezen  van een 
      statusregister,  dit zou  u inmiddels  zonder verdere uitleg 
      moeten kunnen begrijpen.
      
      
      COPDAT: DB    0,0,0,3         ; SX en SY (page 3)
              DB    0,0,0,0         ; DX en DY (page 0)
              DB    5,0,7,0         ; NX en NY
              DB    0,0             ; CLR en ARG
              DB    &B10010000      ; LMMM
      
      
      Dit  is het  blok met  copy data.  De pages,  grootte en het 
      commando zijn  al ingevuld,  door de routine wordt de source 
      (de letter op page 3) en de destination (waar komt de letter 
      op  page 0)  ingevuld. &B10010000  staat voor  LMMM, Logical 
      Move VRAM to VRAM.
      
      Tot  slot  de  co�rdinatentabel. Dit  ziet er  misschien een 
      beetje  lang uit, maar het is met een BASIC programmaatje in 
      een wip  aangemaakt. Deze  tabel kunt  u aanpassen voor elke 
      gewenste karakterset.
      
      
      ; Coordinaten van ASCII 32 t/m ASCII 93
      
      CORTAB: DB    0,197           ;
              DB    6,197           ; !
              DB    12,197          ; "
              DB    18,197          ; #
              DB    24,197          ; $
              DB    30,197          ; %
              DB    36,197          ; &
              DB    42,197          ; '
              DB    48,197          ; (
              DB    54,197          ; )
              DB    60,197          ; *
              DB    66,197          ; +
              DB    72,197          ; ,
              DB    78,197          ; -
              DB    84,197          ; .
              DB    90,197          ; /
              DB    96,197          ; 0
              DB    102,197         ; 1
              DB    108,197         ; 2
              DB    114,197         ; 3
              DB    120,197         ; 4
              DB    126,197         ; 5
              DB    132,197         ; 6
              DB    138,197         ; 7
              DB    144,197         ; 8
              DB    150,197         ; 9
              DB    156,197         ; :
              DB    162,197         ; ;
              DB    168,197         ; <
              DB    174,197         ; =
              DB    180,197         ; >
              DB    186,197         ; ?
              DB    192,197         ; @
              DB    0,205           ; A
              DB    6,205           ; B
              DB    12,205          ; C
              DB    18,205          ; D
              DB    24,205          ; E
              DB    30,205          ; F
              DB    36,205          ; G
              DB    42,205          ; H
              DB    48,205          ; I
              DB    54,205          ; J
              DB    60,205          ; K
              DB    66,205          ; L
              DB    72,205          ; M
              DB    78,205          ; N
              DB    84,205          ; O
              DB    90,205          ; P
              DB    96,205          ; Q
              DB    102,205         ; R
              DB    108,205         ; S
              DB    114,205         ; T
              DB    120,205         ; U
              DB    126,205         ; V
              DB    132,205         ; W
              DB    138,205         ; X
              DB    144,205         ; Y
              DB    150,205         ; Z
              DB    156,205         ; [
              DB    162,205         ; \
              DB    168,205         ; ]
      
      
                           V O O R B E E L D 
      
      Zo, dat  was de  ML routine. Niet echt moeilijk denk ik. Hij 
      staat  op de  disk onder  de naam  PRTEXT.ASC. Om het uit te 
      testen gebruiken we het volgende BASIC programma:
      
      100 ' PRTEXT voorbeeld
      110 ' Door Stefan Boer, 20/03/93
      120 ' (c) Ectry 1993
      130 ' Sunrise Magazine #7 VDP cursus
      140 '
      150 SCREEN5:COLOR15,0,0:CLS
      160 CLEAR200,&HCFFF:DEFINTA-Z:BLOAD"PRTEXT.BIN":
          DEFUSR=&HD000
      170 OPEN"GRP:"AS1:SETPAGE,3:CLS:A=32:FORI=0TO192STEP6:
          PRESET(I,197):PRINT#1,CHR$(A):A=A+1:NEXT:
          FORI=0TO168STEP6:PRESET(I,205):PRINT#1,CHR$(A):A=A+1:
          NEXT:SETPAGE,0
      180 FORI=50TO150STEP20:READT$:POKE&HD003,128-3*LEN(T$):
          POKE&HD004,I:U$=USR(T$):NEXT
      190 IFSTRIG(0)=0THEN190ELSEEND
      200 DATA "PRTEXT"
      210 DATA " "
      220 DATA "(C) ECTRY 1993"
      230 DATA " "
      240 DATA "VDP CURSUS"
      250 DATA "SUNRISE MAGAZINE #7"
      
      Dit  staat  ook  op  de disk  onder de  naam PRTEXT.BAS.  De 
      geassembleerde ML  file staat  er ook  op: PRTEXT.BIN. Samen 
      staan deze files in PRTEXT.PMA.
      
      Dit  voorbeeld   is  niet  bepaald  spectaculair,  omdat  de 
      standaardkarakterset wordt gebruikt. Wel valt het op dat dit 
      een  stuk sneller  is dan  OPEN"GRP:"AS1/PRINT#1. Het  grote 
      voordeel  hiervan  is  dat  u elk  gewenste formaat  letters 
      (zelfs  proportioneel  als  u  de routine  een klein  beetje 
      aanpast!) kunt gebruiken, ook met meerdere kleuren!
      
      
                           T E N S L O T T E 
      
      Een  beetje  korte  tekst  dit  keer,  maar dat  hoop ik  de 
      volgende keer goed te maken met een extra lange routine.
      
      Dit  is een  leuk voorbeeld  om uit te breiden, ik noemde al 
      een andere  (grotere) karakterset  of proportioneel schrift. 
      Zet  daarvoor  achter  de  co�rdinaten  in de  tabel ook  de 
      breedte van de letter, en tel dat getal op bij de oude DX.
      
      Veel plezier en tot de volgende keer!
      
                                                      Stefan Boer