
|
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.)
|