MILC logo

IndexVorigeVolgendeLeeg

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


    
MAAK UW EIGEN BASIC COMMANDO'S:

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

Het CALL  commando  is  aan  MSX  Basic  toegevoegd  om  het
mogelijk  te  maken  uw  eigen  commando's  of   toekomstige
uitbreidingen te gebruiken.

De syntax luidt:

CALL <naam uitbreidingsbevel> [ (parameter,parameter ...) ]

In plaats van CALL mag ook het onderstrepingsteken _  worden
gebruikt.

Kennis van machinetaal is vereist voor het  zelf  maken  van
een CALL  commando.  Basic  programmeurs  kunnen  de  nieuwe
commando's natuurlijk wel zonder problemen gebruiken in  hun
eigen programma's.

Voordat we ingaan op het maken van een CALL  commando  wordt
er eerst enige achtergrondinformatie gegeven.


                    UITBREIDINGSPAGINA'S

Een pagina is een stuk geheugen (ROM of RAM) van 16  kB.  De
pagina's zijn genummerd van 0 t/m 3.

Page:    Adresbereik:
0        &H0000-&H3FFF
1        &H4000-&H7FFF
2        &H8000-&HBFFF
3        &HC000-&HFFFF

De MSX computer heeft standaard pagina's met RAM, BIOS, Disk
ROM en Basic ROM. Daar kunnen echter door de  fabrikant  (in
ROM vorm) of door de gebruiker (in  het  RAM)  uitbreidings-
pagina's aan worden toegevoegd.

Een uitbreidingspagina  kan  een  machinetaalprogramma,  een
apparaatuitbreiding, een  Basic-uitbreiding  of  een  Basic-
programma bevatten. De informatie daarover is opgeslagen  in
SLTATR. SLTATR is een gedeelte van  het  systeemgebied,  dat
begint op adres &HFCC9. Er  is  ‚‚n  byte  gereserveerd  per
mogelijke pagina. Er zijn 4 primaire sloten mogelijk die elk
4 secundaire sloten kunnen hebben. Elk slot bestaat weer uit
4 pages, zodat SLTATR 4*4*4=64 bytes lang is.  De  bits  van
deze bytes hebben de volgende betekenis:

Bit 7    Basic programma (1=ja)
Bit 6    apparaat uitbreiding (1=ja)
Bit 5    statement uitbreiding (1=ja) (CALL commando)
Bit 4-0  ongebruikt

U kunt het adres dat bij een bepaalde pagina hoort berekenen
met de volgende formule:

ADRES = &HFCC9 + 16 * primaire gleufnummer + 4 *  secundaire
gleufnummer + paginanummer

Voorbeeld: in uw computer zit het RAM in slot 3-2 en u heeft
een statement uitbreiding in page 1 gemaakt. Het adres wordt
dan:

&HFCC9 + 16 * 3 + 4 * 2 + 1 = &HFD02

Bit 5 staat voor een statement uitbreiding, dus de waarde 32
(2^5) moet naar adres &HFD02 worden geschreven: POKE &HFD02,
32.


              ALGEMENE VORM UITBREIDINGSPAGINA

De eerste 16 bytes van een uitbreidingspagina zijn als volgt
opgebouwd:

Offset:  Naam:               Bevat:
------------------------------------------------------------
+0       ID                  "AB"
+2       INIT                beginadr initialisatie
+4       STATEMENT           beginadr statement uitbreiding
+6       DEVICE              beginadr apparaat uitbreiding
+8       TEXT                beginadr Basic programma
+10      -                   6 bytes gereserveerd
------------------------------------------------------------

Aan het begin van een pagina moeten de letters  "AB"  (ASCII
&H41  en  &H42)  staan.  De  computer  herkent  daaraan   de
uitbreidingspagina. Bij  een  RESET  zal  de  computer  zelf
kijken wat er in de pagina's staat en SLTATR  overeenkomstig
invullen. Als u een CALL commando wilt gebruiken zonder  een
RESET, dan zult u zelf in  SLTART  moeten  POKEn.  Dat  komt
verderop nog aan bod.


                    STATEMENT UITBREIDING

Wij  interesseren  ons   nu   alleen   voor   de   statement
uitbreiding. Als er geen statement uitbreiding in de  pagina
aanwezig is, moet STATEMENT gelijk zijn aan  &H0000.  Alleen
page 1 kan een statement  uitbreiding  bevatten.  Er  kunnen
problemen  ontstaan  als  bij  andere  pagina's   het   veld
STATEMENT is ingevuld.

Het is overigens logisch dat  de  statement  uitbreiding  in
page 1 moet staan. In page 0 staat de BIOS en in page 3  het
systeemgebied, dus  die  moeten  ingeschakeld  blijven.  Het
Basic programma staat in page 2 (als het een groot programma
is tot in page 3), dus page 1 is de enige  mogelijkheid  die
overblijft.

Als  de computer  bij het  uitvoeren van een Basic programma 
een CALL  commando tegenkomt, wordt de naam van het commando 
(het  woord dat  achter CALL  staat) in PROCNM gezet. PROCNM 
ligt  in  het  systeem  gebied,  vanaf  &HFD89. Alle  kleine 
letters worden  omgezet in hoofdletters en de komma's worden 
eruit  gehaald  (probeert  u  maar  eens:  _F,O,R,M,A,T  het 
werkt!).  De naam  mag 15  tekens lang  zijn. Achter de naam 
wordt een  ASCII-teken 0 gezet. Daarna gaat de computer alle 
pagina's  langs die volgens SLTATR een statement uitbreiding 
bevatten.

Als de computer bij STATEMENT een waarde vindt die  ongelijk
is aan &H0000, dan springt hij naar dat  adres  en  laat  de
besturing verder aan  die  routine  over.  De  taak  van  de
routine is nu om te controleren of het het juiste  statement
is.

HL wijst naar het eerste teken  na  de  naam  van  het  CALL
statement in het tokenized  Basic.  Spaties  worden  daarbij
niet meegeteld. Bij bijvoorbeeld CALL FORMAT  wijst  HL  dus
naar de positie na de T van FORMAT.

Als de routine ziet dat het de  juiste  naam  is,  moet  het
statement  worden  uitgevoerd  en  moet  de  routine  worden
verlaten met de carry gereset (gelijk aan 0  dus).  HL  moet
naar het eerste teken na het commando wijzen (het einde  van
de regel of een dubbele punt). Bij een CALL statement zonder
parameters  is  dat  dus  de  oude  situatie   (bijvoorbeeld
_FORMAT), bij _GENIC(10000) moet HL wijzen naar  de  positie
achter het tweede haakje.

Is het een ander commando,  dan  moet  de  routine  verlaten
worden met de carry  geset  (hoog)  en  HL  onveranderd.  De
andere registers mogen wel zijn veranderd.

Deze  theorie  is  samengevat  in  een  machinetaal  source,
geschreven door Erik Bos. Deze source bevind zich als  ASCII
file op deze ClubGuide (onder de  naam  CALL.ASC)  en  wordt
hieronder uitgebreid besproken. Ik heb  er  zoveel  mogelijk
uitleg bij gezet.


                      STANDAARD ROUTINE

Deze routine kunt u gebruiken voor al uw CALL statements. De
routine kan ‚‚n, maar ook twee of meer  routines  aansturen.
Als al het RAM in ‚‚n slot zit (is meestal zo), dan  kunt  u
maar ‚‚n blok CALL commando's tegelijk gebruiken. Er is  dan
namelijk maar  ‚‚n  page  1  beschikbaar,  en  de  statement
uitbreiding moet altijd in page  1  staan.  Met  behulp  van
MemMan is het overigens  wel  mogelijk  om  meerdere  'CALL-
blokken' aan te maken.

De source wordt geassembleerd op  &H9000.  De  initialisatie
routine schrijft het hele zaakje netjes  naar  &H4000  (page
1). U kunt de routine dan ook het beste BSAVEn met als  exec
adres het adres INIT. Als de routine bijvoorbeeld loopt  van
&H9000 tot &H9500 en INIT begint op &H9300,  dan  wordt  het
BSAVE"NAAM.BIN",&H9000,&H9500,&H9300.  De  CALL   commando's
worden dan ge‹nitialiseerd met BLOAD "NAAM.BIN",R.

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

; STANDAARD ROUTINE VOOR STATEMENT UITBREIDINGEN
; Door Erik Bos

BEGIN:  EQU  &H9000          ;beginadres

        ORG  BEGIN

Omdat de routine geassembleerd en dus ook geBLOAD  wordt  op
&H9000, maar werkt op &H4000, moet  dat  verschil  bij  alle
absolute   adresseringen   worden    verrekend.    (Absolute
adressering  betekent  dat  er  een  absoluut  adres   wordt
gebruikt. Bijvoorbeeld  LD  A,(&HFFFF)  of  JP  &HD000.)  We
gebruiken daarvoor het label OFFSET. Als u  bijvoorbeeld  in
plaats van CALL SYNTAX+OFFSET gewoon  CALL  SYNTAX  neerzet,
dan zal de computer naar een adres ergens  boven  de  &H9000
springen. De assembler heeft aan het label SYNTAX immers een
waarde boven &H9000  toegekend,  er  staat  ORG  &H9000.  In
werkelijkheid staat die subroutine na het verplaatsen ergens
boven &H4000. Dat verschil wordt  goedgemaakt  door  OFFSET.
Als u dit niet doet gaat het mis zodra u iets in het  gebied
vanaf &H9000  veranderd,  bijvoorbeeld  door  er  een  Basic
programma neer te zetten.

OFFSET: EQU  &H4000-BEGIN

Vul de 16 eerste bytes van de uitbreidingspagina in.

        DEFM "AB"
        DEFW 0               ;geen initialisatie
        DEFW CAL+OFFSET      ;begin statement uitbreiding
        DEFW 0               ;geen device
        DEFW 0               ;geen Basic
        DEFW 0
        DEFW 0
        DEFW 0

Hier springt de computer naartoe als hij een CALL  statement
tegenkomt. De routine checkt of het ‚‚n van de statements is
die in de TABEL staat.

CAL:    PUSH HL              ;HL wijst naar teken na CALL
        LD   DE,TABEL+OFFSET ;begin van de tabel
C_1:    LD   HL,&HFD89       ;PROCNM bevat naam
        LD   A,(DE)          ;lengte van naam
        AND  A               ;wis vlaggen
        JR   Z,C_ERR         ;einde tabel als A=0
        LD   B,A
        INC  DE

C_2:    LD   A,(DE)          ;vergelijk naam in tabel
        CP   (HL)            ;met naam in PROCNM
        JR   NZ,NEXT1        ;naar NEXT1 als verkeerde naam
        INC  DE
        INC  HL
        DJNZ C_2

Er moet ook nog worden  gecontroleerd  of  het  niet  verder
gaat. Stel er staat CALL GENICS in het Basic  programma,  en
GENIC in de tabel. Met alleen bovenstaande  routine  zou  de
computer  GENICS  herkennen  als  GENIC.  Daarom  wordt   er
gecontroleerd of er een 0 staat in PROCNM.

        LD   A,(HL)
        AND  A
        JR   NZ,NEXT2        ;NEXT2 als commando langer is

Lees het sprongadres en voer de routine uit. De routine moet
zelf zorgen dat HL en de carry de juiste waarde  hebben  bij
het verlaten van de routine.

        EX   DE,HL           ;HL is plaats in tabel
        LD   E,(HL)          ;low byte sprongadres
        INC  HL
        LD   D,(HL)          ;high byte sprongadres
        EX   DE,HL
        JP   (HL)            ;spring naar dat adres

Er is een fout teken gevonden. Bereken de volgende plaats in
de tabel. B bevat het aantal tekens van de naam dat nog niet
is geweest, achter de naam staat  nog  het  sprongadres  van
twee bytes. Vandaar dat BC nog met twee  bytes  extra  wordt
verhoogd.

NEXT1:  LD   C,B
        LD   B,0             ;BC=B
        INC  BC
        INC  BC
        EX   DE,HL
        ADD  HL,BC
        EX   DE,HL
        JR   C_1             ;probeer het nog eens

Het commando bleek langer te  zijn  (er  stond  nog  geen  0
achter de  gezochte  naam  in  PROCNM),  ga  verder  met  de
volgende in de TABEL.

NEXT2:  INC  DE              ;sla het sprongadres
        INC  DE              ;over
        JR   C_1             ;probeer het nog eens

Het commando is niet gevonden, keer terug met de C vlag hoog
en HL onveranderd.

C_ERR:  POP  HL
        SCF
        RET

(Nvdr. Dit artikel was  te  groot  voor  de  layout  van  de
ClubGuide. Het is daarom in twee stukken verdeeld.  Dit  was
het eerste deel. Ga nu terug naar het menu en laad daar  het
tweede deel in.)

    

Index

Vorige

Volgende