MILC logo

IndexVorigeVolgendeLeeg

Call commando's maken (2)
Genic Clubguide, 00-00-00


    
VERVOLG VAN HET CALL ARTIKEL:

       C A L L   C O M M A N D O ' S   M A K E N   (2)
      =================================================

(Nvdr. Dit artikel  was  te  lang  voor  de  layout  van  de
ClubGuide. Het is daarom in twee stukken  verdeeld.  In  het
eerste deel waren we ergens midden in  de  standaard  source
blijven steken daar pakken we nu de draad weer op.)


                  VERVOLG STANDAARDROUTINE

De routine INIT moet worden aangeroepen  om  het  blok  CALL
statements naar de juiste plaats te copi‰ren  en  om  SLTATR
dienovereenkomstig in te stellen. Het blok moet in  het  RAM
op page 1 worden gezet. Op adres &HF341 t/m &HF344 staat  de
plaats van het RAM voor page 0 t/m 3. De plaats voor het RAM
van page 1 staat dus op &HF342. Dat is op de volgende manier
gecodeerd:

Bit: 7   6   5   4   3   2   1   0
     U   -   -   -   S1  S0  P1  P0

U: Slot wel (1) of niet (0) uitgebreid met secundaire sloten
S0-S1: Nummer van secundair slot (0-3)
P0-P1: Nummer van primair slot (0-3)

De routine ENASLT  selecteert  een  bepaald  slot  voor  een
bepaalde pagina. HL moet een adres bevatten in die pagina, A
geeft aan om welke gleuf het gaat (codering zie boven).

INIT:   LD   A,(&HF342)      ;plaats RAM page 1
        LD   H,&H40          ;page 1
        CALL &H24            ;BIOS routine ENASLT
        LD   HL,&H9000       ;bronadres routine
        LD   DE,&H4000       ;begin van page 1
        LD   BC,&H4000       ;1 page = 16 kB = &H4000 bytes
        LDIR                 ;verplaats naar page 1
        XOR  A               ;herstel slot 0-0 (MSX1 Basic)
        LD   H,&H40          ;page 1
        CALL &H24            ;ENASLT

Bereken juiste adres in SLTATR en zet daar de waarde 32.

        LD   HL,&HFCCA       ;&HFCC9 + pagenummer (=1)
        LD   BC,&H10
        LD   A,(&HF342)      ;plaats RAM page 1
        AND  &B00000011      ;primaire gleuf
CLUS1:  JR   Z,CNEXT
        ADD  HL,BC           ;tel primair*16 erbij op
        DEC  A
        JR   CLUS1
CNEXT:  LD   BC,4
        LD   A,(&HF342)      ;plaats RAM page 1
        AND  A               ;wis vlaggen
        JP   P,CEINDE        ;is er wel een secundair slot
        AND  &B00001100      ;secundaire slot * 4
        RRCA                 ;secundaire slot * 2
        RRCA                 ;secundaire slot
CLUS2:  JR   Z,CEINDE
        ADD  HL,BC           ;tel secundair*4 erbij op
        DEC  A
        JR   CLUS2
CEINDE: LD   (HL),&H20       ;zet bit 5 aan
        RET                  ;einde initialisatie

Met JP P,CEINDE wordt gekeken of bit 7 gelijk is aan 0.  Bit
7 wordt gebruikt om aan te geven of het getal positief is of
negatief. Als het negatief is, dan is  bit  7  hoog.  Bit  7
geeft in dit geval aan of er een secundair slot is of  niet.
JP P betekent spring als positief, dus als bit 7  gelijk  is
aan 0.

Let op: alhoewel het hier om een absolute  adressering  gaat
moet er toch niet JP P,CEINDE+OFFSET staan! De initialisatie
routine wordt immers gewoon ergens vanaf &H9000  uitgevoerd,
waardoor de  OFFSET  moet  worden  weggelaten.  Bij  een  JP
P,CEINDE+OFFSET zou de computer naar page 1  springen,  waar
dan MSX1 Basic geschakeld zit. Dit natuurlijk met  onbekende
gevolgen...

Het aanroepen van een aantal ROM routines die u  vaak  nodig
hebt, wordt door het volgende gedeelte geregeld. De  routine
CALBAS (adres &H159) roept een Basic  routine  uit  het  ROM
aan. Het adres moet in IX staan.

De routines ILLEGA en SYNTAX spreken voor zich.  Met  R_BYTE
en R_WORD kunt  u  de  getalswaarden  die  achter  het  CALL
statement tussen haakjes staan uitlezen. Een word is een  16
bits getal, tussen -32768 en +32767.

Voorbeeld: u heeft een routine geschreven om het CAPS lampje
aan en uit te zetten. Syntax: _CAPS(getal).  Als  het  getal
gelijk is aan 1 gaat  het  lampje  aan.  U  moet  dan  eerst
controleren op het haakje, en daarna met  R_BYTE  het  getal
uitlezen. Vervolgens controleren op haakje sluiten.

ILLEGA: LD   IX,&H475A       ;Illegal function call error
        JP   &H159           ;routine van Basic-ROM

SYNTAX: LD   IX,&H4055       ;Syntax error routine van
        JP   &H159           ;Basic-ROM aanroepen

R_BYTE: LD   IX,&H521C       ;Lees een byte van getokenized
        JP   &H159           ;Basic, resultaat in A

R_WORD: LD   IX,&H6F0B       ;Lees een word van getokenized
        JP   &H159           ;Basic, resultaat in DE

Nu volgt de tabel. Daarin moet achtereenvolgens de naam,  de
lengte van de naam en het sprongadres staan. De  tabel  moet
worden afgesloten door een 0. Er staan nu  twee  voorbeelden
in.

TABEL:  DEFB 6               ;lengte CALL commando
        DEFM "TESTJE"        ;de naam
        DEFW TESTJE+OFFSET   ;het adres

        DEFB 4
        DEFM "DSKI"
        DEFW DSKI+OFFSET

        DEFB 0               ;afsluiten

Als voorbeeld nu de source van twee CALL commando's, _TESTJE
en _DSKI(drive,sektor,aantal,adres). _TESTJE  zet  de  tekst
GENIC op het scherm, _DSKI(d,s,a,ad) leest sektoren  in  van
diskette.

TESTJE: LD   HL,TEXT+OFFSET  ;begin tekst
T_1:    LD   A,(HL)          ;ASCII teken
        AND  A
        JR   Z,T_2           ;klaar als 0

        CALL &HA2            ;teken naar scherm
        INC  HL
        JR   T_1             ;volgende teken

T_2:    POP  HL              ;HL is pointer naar tokenized
                             ;Basic achter commando
        XOR  A               ;wis carry
        RET

TEXT:   DEFM "GENIC",0

Bij de DSKI routine wordt  gebruik  gemaakt  van  zogenaamde
BDOS calls. Ik kom daar  uitgebreid  op  terug  in  de  disk
cursus.

DSKI:   POP  HL              ;HL is pointer achter tokenized
                             ;Basic achter commando
        LD   A,(HL)
        CP   "("
        JP   NZ,SYNTAX+OFFSET ;syntax error als geen haakje
        INC  HL

        CALL R_BYTE+OFFSET   ;lees drivenummer
        LD   (DRIVE+OFFSET),A

        LD   A,(HL)
        CP   ","
        JP   NZ,SYNTAX+OFFSET ;syntax error als geen komma
        INC  HL

        CALL R_WORD+OFFSET   ;lees start sector
        LD   (SECTOR+OFFSET),DE

        LD   A,(HL)
        CP   ","
        JP   NZ,SYNTAX+OFFSET ;syntax error als geen komma
        INC  HL

        CALL R_BYTE+OFFSET   ;lees aantal sectoren
        LD   (COUNT+OFFSET),A
        AND  A               ;wis vlaggen
        JR   Z,ILLEGA+OFFSET ;Illegal function call als
                             ;0 sektoren

        LD   A,(HL)
        CP   ","
        JP   NZ,SYNTAX+OFFSET ;syntax error als geen komma
        INC  HL

        CALL R_WORD+OFFSET   ;lees adres

        LD   A,(HL)
        CP   ")"
        JP   NZ,SYNTAX+OFFSET ;syntax error als geen haakje
        INC  HL
        PUSH HL              ;bewaar pointer achter commando

        LD   C,&H1A          ;BDOS call SETDMA
        CALL &HF37D          ;stel adres in op DE

        LD   DE,(SECTOR+OFFSET)
        LD   HL,(DRIVE+OFFSET)
        LD   C,&H2F          ;BDOS call Absolute Disk Read
        CALL &HF37D          ;lees H sectoren van drive
                             ;nummer L, beginnende met
                             ;sector DE

        POP  HL              ;pointer achter commando
        XOR  A               ;wis carry
        RET

DRIVE:  DEFB 0
COUNT:  DEFB 0
SECTOR: DEFW 0

------------------------------------------------------------

Deze routine staat op de ClubGuide onder de naam CALL.BIN. U
kunt hem laden met  BLOAD"CALL.BIN",R.  De  commando's  CALL
TESTJE en CALL DSKI(drive,sector,aantal,adres)  werken  dan.
In het softwaremenu vindt u het programma CALL.ART, dat  ook
gebruikt kan worden om CALL.BIN te laden.


                      ZELF AAN DE SLAG

U  kunt  deze  routine  gebruiken  om  zelf  uw  eigen  CALL
commando's te maken. Ga daarbij als volgt te werk.

-  Schrijf  een  machinetaalroutine  die  u  door  een  CALL
commando wilt laten aanroepen.  U  mag  daarin  de  routines
ILLEGA, SYNTAX, R_BYTE en R_WORD gebruiken. Zorg dat bij het
verlaten van de routine HL wijst  naar  de  positie  na  het
commando en dat de C vlag gewist is. Denk er verder  om  dat
de stack niet verandert ten opzichte van de situatie voordat
uw routine werd aangeroepen.
- Zet de standaardroutine erbij en zet het  commando  in  de
tabel. De standaardroutine zorgt ervoor dat  er  alleen  bij
het  juiste  CALL  commando  naar  uw  routine  zal   worden
gesprongen.
- Let erop dat het totale blok CALL  commando's  nooit  meer
kan zijn dan 16 kB.
- U mag de BIOS routines in page 0 en het systeem gebied  in
page 3 natuurlijk ook gebruiken.
- Vergeet niet steeds bij elke absolute adressering  +OFFSET
erbij te zetten.


                          OPDRACHT

Maak nu zelf  de  commando's  _RAMVRAM(bron,doel,lengte)  en
_VRAMRAM(bron,doel,lengte). Deze commando's verplaatsen  een
stuk geheugen van  het  RAM  naar  het  VRAM  of  omgekeerd.
_RAMVRAM  kopieert  van  RAM  naar  VRAM.  U  kunt   daarbij
natuurlijk gebruik maken van de BIOS routines:

LDIRMV &H0059 Kopieert VRAM naar RAM. HL=bron, DE=doel,
              BC=lengte.
LDIRVM &H005C Kopieert RAM naar VRAM. HL=bron, DE=doel,
              BC=lengte.

Op de volgende ClubGuide komt de oplossing.

Ik hoop dat u nu zelf in staat bent om  CALL  commando's  te
maken en de opdracht uit te voeren. Als u  nog  vragen  hebt
kunt u  een  briefje  schrijven  of  mij  even  bellen.  Ook
suggesties of zelfgemaakte CALL commando's  zijn  van  harte
welkom.  De  mooiste  commando's  zullen  zeker  met   naam-
vermelding op de ClubGuide worden geplaatst.

    Dus stuur uw programma's, vragen of suggesties naar:

                       Stichting GENIC
                     T.a.v. Stefan Boer
                         Postbus 258
                       8470 AE Wolvega

U kunt ook bellen, telefoon 02982-1039 ('s avonds en in  het
weekend.)

                        Veel succes!

                                                Stefan Boer

    

Index

Vorige

Volgende