
|
Call cartridge Genic Clubguide, 00-00-00
MACHINETAAL:
C A L L C A R T R I D G E
=============================
De nu volgende tekst is ook te vinden op de BBS-waterland en
is geschreven door Ramon van der Winkel die GENIC toe-
stemming heeft gegeven voor deze publicatie.
Aan de publicatie van dit artikel hebben meegewerkt:
Ramon van der Winkel (De schrijver van het artikel)
Rudy Oppers (De man van de modem)
Alex van der Wal (Initiatiefnemer & editor)
Deze tekstfile legt uit hoe een software-cartridge gemaakt
kan worden, die met CALL aan te roepen is. De software zal
in Z80-machinetaal geschreven moeten worden, het kunnen
programmeren in deze taal is dus een voorwaarde. Verder is
enige kennis van de slot structuur van de MSX van belang
(pagina's, sloten etc).
Als de computer opgestart of gereset wordt, wordt als eerste
de MSX-BIOS-ROM aangeroepen. Deze zal het hele geheugen
opzetten, zodat er BASIC programma's gerunt kunnen gaan
worden.
Als een van de laatste acties kijkt de BIOS-ROM of er in een
van de sloten een externe-ROM zit. Deze is voor de BIOS-ROM
herkenbaar, omdat de eerste twee bytes van de externe rom
een 65 en een 66 zijn, de ascii codes voor een A en een B.
Komt de BIOS-ROM deze codes tegen, dan wordt er een tabel
achter die twee codes verwacht, die op de volgende manier is
opgebouwd:
+0 "A"
+1 "B"
+2 INITIALISE Address LSB
+3 INITIALISE Address MSB
+4 STATEMENT Address LSB
+5 STATEMENT Address MSB
+6 DEVICE Address LSB
+7 DEVICE Address MSB
+8 BASIC TEXT Address LSB
+9 BASIC TEXT Address MSB
+A\
. \
. +- Gereserveerd, meestal 0
. /
+F/
Voor ons zijn voorlopig alleen de adressen +0 tot en met +5
van belang, de andere adressen worden gebruikt voor de uit-
breiding van de DEVICES (COM:, CAS:, A:, etc) en de BASIC
(een BASIC programma in de ROM).
Het startadres van deze cartridge is 4000h of 8000h, voor
adres 0000 zijn andere afspraken, adres C000h is niet te
gebruiken, omdat de rom daar zijn systeem variabelen heeft
staan en we die pagina dus niet weg kunnen schakelen. De
diskrom bijvoorbeeld staat vanaf adres 4000h, laten we er
voor het gemak maar even vanuit gaan, dat wij ons programma
daar ook neer gaan zetten.
De ROM was dus aan het opstarten, en vond de cartridge
indentificatiecodes A en B. Nu gaat de ROM het adres van +2
en +3 ophalen, en springt daar, als het niet 0000 is, naar
toe. Dit adres wordt dus na de reset van de computer een-
malig aangeroepen. Ons programma kan daar dus een stukje van
zichzelf initialiseren in het geheugen (als dat mogelijk
mocht zijn). De diskrom, om daar maar weer eens naar toe te
gaan, zet hier de koppen van de drives in de uitgangspositie
en initialiseert een aantal buffers en systeem variabelen
van adres 0F37Fh en lager (naar C200H toe dus).
Daarna kijkt de ROM naar de andere adressen. Als op +4 en +5
een adres staat, dan wordt in een special tabel gesigneerd
dat ons programma een CALL uitbreiding ondersteund. Zo wordt
ook voor de DEVICE en de BASIC TEXT een bit gezet in die
speciale tabel. De tabel staat vanaf adres 0FCC9h en is als
volgt opgebouwd:
Per slot worden 16 bytes bijgehouden, per secundair slot
binnen dat slot 4 bytes (4 secundair slot keer 4 bytes = 16
bytes). Per secundair slot wordt weer per pagina een byte
bijgehouden (4 pagina's keer 1 byte = 4 bytes). Willen we
dus de informatie over de pagina van de diskrom en zit deze
in pagina 1 (4000h..7FFFh) in slot 3-2, dan bepalen we het
adres in de tabel met de volgende formule:
0FCC9h + Primair slot nummer * 16 + secundair slot nummer *4
+ pagina nummer
Hier is dat dus 0FCC9h+3*16+2*4+1 = 0FCC9h+57 = 0FD02h. Hier
staat dus een byte met de speciale informatie omtrend de
diskrom. De byte is weer als volgt opgebouwd:
Bit7 = 1: BASIC TEXT handler gevonden
Bit6 = 1: DEVICE handler gevonden.
Bit5 = 1: CALL handler gevonden.
Op het moment dat er dus een CALL <tekst> uitgevoerd wordt,
worden alle pagina's in de sloten, waarvan Bit5 geSET is,
aangeroepen. Hoe de software dan weer in elkaar moet zitten,
leg ik nu uit.
Stel, op adres 4000h+4 en +5 staat de waarde 4010h, dan
begint ons programma dus vanaf adres 4010h.
Op het moment dat onze routine door de rom wordt aange-
roepen, staat vanaf adres 0FD89h de <tekst> die achter het
CALL statement was opgegeven. Alleen het eerste woord staat
hier dus. De <tekst> wordt door een 0 afgesloten, is
maximaal 15 tekens lang en is al helemaal omgezet in hoofd-
letters. Tekens als een komma zijn er al tussenuit ge-
filterd. (Probeer het maar eens: CALL S,Y,S,T,E,M dit
werkt!).
Verder bevat register HL de pointer naar de rest van de
tekstregel, vervolgt achter de <tekst> van de call. Als we
bijvoorbeeld CALL TEST ("Ramon",0) willen doorgeven, dan
staat de tekst TEST vanaf adres 0FD89h, gevolgt door een 0
en staat register HL op de spatie achter de tekst TEST.
Als we de tekst op adres 0FD89h getest hebben en hij komt
overeen met wat wij ervan dachten (TEST dus), dan roepen we
onze eigen routines aan, die de rest afhandelen. LET WEL OP:
Geen registers veranderen, zeker HL niet.
Als we daarna terugkeren, zorgen we ervoor, dat we de Carry
flag geRESET hebben. Op die manier weet de ROM, dat de tekst
door ons behandeld is en dat er niet verder geprobeert hoeft
te worden, door de diskrom bijvoorbeeld.
Bevalt de tekst ons echter niet, er is bijvoorbeeld TETS
ingetypt, dan zetten we de Carry flag en we keren weer
terug. De rom ziet dan dat de Carry flag gezet is en hij zal
het in de andere pagina's met een call-handler bit in de
speciale tabel gezet, gaan proberen. Als er geen pagina's
meer zijn, wordt er de foutmelding 'Syntax error' gegeven.
Houdt verder in de gaten dat de stack door de eigen routines
niet verknald wordt. Van te voren even opslaan en dan in de
eigen (RAM) pagina zetten, zorgt voor een veilige terugkeer.
Nu zitten we nog met een probleem: Als wij een eigen stukje
software hebben geladen vanaf adres 4000h, met de cartridge
header erboven, hoe vertellen we dan aan de ROM, dat wij een
call-handler ondersteunen, zonder dat we de computer hoeven
te resetten, om de rom het zelf te laten ondervinden?
Heel eenvoudig. We bepalen ons eigen slot-id (het primair en
secundaire slot waar we inzitten) en we berekenen de positie
van de onze pagina in de speciale tabel en we zetten daar
Bit5, de rom weet dan dat wij een call-handler ondersteunen.
Ik laat het hier voorlopig even bij, hieronder staan nog een
paar handige routines en een voorbeeld van een kant en klaar
programma met een cartridge header en een installatie
programma dat Bit5 zet.
Op de DEVICE en BASIC TEXT handler wil ik niet verder in-
gaan, omdat het dan nog moeilijker wordt en de meeste mensen
hier al moeite genoeg mee zullen hebben.
Veel sucses !!
Ramon van der Winkel
Wouter Sluislaan 12
1461 AC Zuidoostbeemster
Via BBS Waterland (02990-40202/45740): Post aan RAMON VAN
DER WINKEL, bord MSX.
De voorbeeld programma's:
ORG 04000H
;
CARTHEAD DEFB "AB"
DEFW 0 ;Geen INITIALISE handler
DEFW CALHAN ;CALL handler
DEFS $4010-$ ;De rest vullen met 00
;
CALHAN PUSH HL ;Store tekstpointer
LD DE,_STATEM ;Onze tekst
LD HL,0FD89H ;De <tekst>
CALHAN_LUS LD A,(DE) ;Ons teken
CP (HL) ;Vergelijk
JR NZ,CALHAN_BAD ;Niet hetzelfde, return met
INC HL ;met Carry set
INC DE
AND A ;Einde (00) ?
JR NZ,CALHAN_LUS ;Nog niet bereikt
CALL ENTRY ;Onze eigen routine aanroepen
SUB A ;Reset carry
JR CALHAN_EXIT
;
CALHAN_BAD SCF ;Tekst niet herkend
CALHAN_EXIT POP HL ;Restore tekstpointer
RET
;
_STATEM DEFB "TEST",0
;
ENTRY ;Hier komt je eigen routine te staan
RET
;
Opm: Er kunnen natuurlijk ook meerdere vergelijkingen
gedaan worden, op meerdere teksten, het hoeft niet bij
maar een vergelijking te blijven! (vergelijk diskrom:
CALL SYSTEM en CALL FORMAT).
De routine om het callhandler bit in de special tabel te
setten.
SETCALLBIT CALL GETOWNID ;Je eigen slotID ophalen
PUSH AF
AND %00000011 ;Primaire slot
SLA A ;*2
SLA A ;*4
SLA A ;*8
SLA A ;*16
LD C,A
POP AF
AND %00001100 ;Secundair slot (al *4)
OR C
INC A ;Pagina 1
LD C,A
LD B,0
LD HL,0FCC9H ;Speciale tabel
ADD HL,BC ;+ Offset
SET 5,(HL) ;Call handler bit
RET
;
GETOWNID DI
IN A,(0A8H)
SRL A
SRL A
AND 3 ;Primaire slot van
LD C,A ;onze pagina
LD B,0
LD HL,0FCC1H
ADD HL,BC ;Naar de 'expanded' tabel
OR (HL) ;Bit7=0 -> Geen sec slots
RET P ;Niet dus
LD C,A
INC HL
INC HL ;Ga nu naar de tabel met de
INC HL ;actieve secundaire slot
INC HL ;setting van iedere pagina
LD A,(HL)
AND %00001100 ;Van pagina 1
OR C ;En het primaire slot erbij
RET
;
|