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