Beter C dan nooit...
Freddy Vulto
Voorwoord
Inhoudsopgave
Inleiding
Compiler Disk v1.10
System
Standard Library
Compiler Disk v1.20
System
CF.COM
CG.COM
FPC.COM
MX.COM
M80.COM
L80.COM
Standard Library
MSX-C Library System Disk
Graphic Library
BIOS Library
Math Library
Curses Library
Tips & Truuks
Identifiers
Parameteroverdracht
Geheugenbeheer
Literatuur
Lijst van Tabellen
Tabel 1: Compilatiestappen MSX-C
Tabel 2: Inhoud Compiler Disk v1.10
Tabel 3: Functies in Standard Library v1.10
Tabel 4: Inhoud Compiler Disk v1.20
Tabel 5: Functies in Standard Library v1.20
Tabel 6: Inhoud Library System Disk
Tabel 7: Functies in Graphic Library
Tabel 8: Functies in BIOS Library
Tabel 9: Functies in Math Library
Tabel 10: Functies in Curses Library
Tabel 11: Behandeling van identifiers
Tabel 12: Parameteroverdracht
Tabel 13: Geheugen-layout
MSX-C is een compleet produkt voor het ontwikkelen van programma's onder MSX-DOS in de programmeertaal C. Er zijn – in tegenstelling tot Small C, Hisoft C of BDS C – complete librarys opgenomen speciaal voor de MSX! Het is nu eindelijk mogelijk om op een MSX de snelheid van machinetaal volledig te combineren met het gemak van de hogere programmeertaal. Mijn advies luidt derhalve: "Trek je zwembroek aan en jump into C!"
Dankzij de standaardisatie en het uitstekende werk van de ASCII Corporation is het mogelijk om de taal te leren via bijna elk boek over C. Voor een compleet overzicht raad ik het standaardwerk "The C programming language" van Brian W. Kernighan en Dennis M. Ritchie aan. De twee schrijvers van dit boek zijn de grondleggers van C en ze behandelen in dit boek de volledige basis. Voor de chauvinisten onder ons is er ook een Nederlandse vertaling.
Een boek met een titel waarin de term 'C++' is opgenomen zou ik laten liggen, want deze uitbreiding van C is niet van toepassing op de MSX.
Het MSX-C pakket is opgesplitst in 2 gedeelten:
De Compiler Disk bevat de noodzakelijke programmacode voor het compileren van een standaard C programma, terwijl op de Library System Disk een aantal aardige functies zijn gedefinieerd die gebruik maken van specifieke MSX functies.
Voordat kan worden gestart met MSX-C dient een zogenaamde MSX-C Library System Disk aangemaakt te worden. Op deze disk komen alle bestanden te staan die nodig zijn voor het hieronder beschreven compilatieproces. De disk kan worden gemaakt door zelf noest aan het werk te gaan met het COPY commando of door gebruik te maken van de batch file MKSYS.BAT. Copieer MKSYS naar de aan te maken disk en geef vanaf deze disk het commando:
MKSYS <drive>
De batch file zorgt er nu verder via vraag en antwoord voor dat de bestanden vanaf de opgegeven 'drive' worden gecopieerd naar de drive van waaruit MKSYS is opgestart.
Een C source file kan in een willekeurige teksteditor (bijv. TED) worden geschreven, maar moet altijd zijn voorzien van de extensie '.C'. Deze source file kan dan vervolgens via een aantal compilatiestappen worden omgezet in een uitvoerbaar machinetaalprogramma. Deze stappen vormen het eigenlijke hart van MSX-C en zijn weergegeven in onderstaande figuur:
Tabel 1: Compilatiestappen MSX-C
|.C ......C source file | Parser (CF.COM) | |.TCO ....T-code file | (Function Parameter Checker (FPC.COM)) | Code Generator (CG.COM) | |.MAC ....Assembler file | Macro Assembler (M80.COM) | |.REL ....Verplaatsbare machinecode file | Linker (L80.COM) | |.COM ....Command file
De commando's voor het uitvoeren van deze stappen zijn vastgelegd in de batch file C.BAT, zodat een C source file - bijv. TEST.C - compleet gecompileerd kan worden met het commando:
C TEST
Indien men naast de standaard C functies gebruik wenst te maken van specifieke MSX functies, moet TEST.C worden gecompileerd met gebruikmaking van de batch file MSXC.BAT:
MSXC TEST [CF options] [CG options]
Gezien het omvangrijke en tijdrovende compilatieproces kan het best gebruik worden gemaakt van een op 7 MHz werkende MSX met een flinke hoeveelheid geheugen, zodat het hele proces kan draaien op een RAMdisk. Alleen bij gebruik van MSX-C v1.20 is MSX-DOS 2.20 noodzakelijk.
Op de MSX-C Compiler Disk bevindt zich de ASCII MSX-C Compiler. De compiler bestaat uit CF.COM, CG.COM, FPC.COM en MX.COM (zie de beschrijvingen verderop). Verder is een standaard library aanwezig, compleet met source en batchfiles voor het aanpassen van deze library. M80.COM, L80.COM en LIB80.COM staan niet op de disk en moeten derhalve van een MSX-DOS(2) Tools Disk worden getrokken.
MSX-C maakt gebruik van de volgende 'library' files:
De files CK.REL en CEND.REL worden altijd in het uiteindelijke programma opgenomen, in respectievelijk het begin en het einde. Het zijn dus eigenlijk geen library files. De source bevindt zich in respectievelijk CK.MAC en CEND.MAC.
CLIB.REL CLIB.REL CRUN.REL
Aangezien het compileren uit veel stappen bestaat, kan het best gebruik worden gemaak van de meegeleverde batch files:
Met behulp van C.BAT wordt de C source file gecompileerd tot een .COM file. De functie-aanroepen worden gecontroleerd met behulp van FPC.COM, die daarbij gebruik maakt van LIB.TCO. GENLIB.BAT geeft het startsein voor een complete batch-cyclus die de hele standaard library opnieuw compileert.
De overige files op de MSX-C Compiler Disk zijn leerzame voorbeelden van wat er zoal mogelijk is met de C programmeertaal. Het programma Q.COM kan worden gegenereerd met MKQ.BAT. De file is opgebouwd uit Q.C, RND.MAC, LINE.MAC, COLOR.MAC en CALBIO.MAC.
Van de MSX-C compiler zijn verschillende versies in omloop. De volgende lijst geeft een overzicht van de versies tezamen met hun belangrijkste kenmerken.
Op dit moment zijn de 1.10 en de 1.20 de belangrijkste versies. Versie 1.20 is geheel gebaseerd op MSX-DOS 2.20. Een door MSX-C v1.20 gecompileerd programma geeft een foutmelding indien MSX-DOS 2.20 niet aanwezig is. Indien men een programma wil schrijven dat nog geschikt is voor MSX-DOS 1, zal derhalve altijd gebruik moeten worden gemaakt van MSX-C v1.10.
Tabel 2: Inhoud Compiler Disk v1.10
------------------------------------------------------------------- PRIMARY FILES SUPPORT FILES SOURCE FILES ------------------------------------------------------------------- SYSTEM: cf.com cg.com fpc.com. . . . . . lib.tco mx.com . . . . . . arel.bat crel.bat LIBRARY FILES: ck.rel . . . . . . . . . . . . . . . .ck.mac clib.rel . . . . . . . . . . . . . . .lib0.mac lib1.c lib2.c lib3.c libk.c crun.rel . . . . . . . . . . . . . . .crun.mac cend.rel . . . . . . . . . . . . . . .cend.mac HEADER FILES: stdio.h bdosfunc.h BATCH FILES: c.bat mksys.bat forremk.bat genlib.bat . . . . genlib01.bat genlib02.bat genlib03.bat genlib04.bat genlib05.bat genlib06.bat SAMPLE FILES: q.c. . . . . . . . mkq.bat . . . . . .rnd.mac line.mac color.mac calbio.mac -------------------------------------------------------------------
De inhoud van de MSX-C Compiler Disk v1.10 is nagenoeg hetzelfde als die van de MSX-C Compiler Disk v1.20. Voor een uitgebreide beschrijving van de system files en de diverse functies zie het volgende hoofdstuk: Compiler Disk v1.20.
Onderstaande tabel geeft een overzicht van de functies die zijn opgenomen in de standard library van MSX-C versie 1.10. Achter de functie staat aangegeven in welke file de sourcecode en respectievelijk de header van de functie is te vinden. Voor omschrijvingen van de functies zie MSX-C v1.20.
Tabel 3: Functies in Standard Library v1.10
Name |
Declaration |
SourceFile |
HeaderFile |
abs |
int abs(n) |
lib1.c |
stdio.h |
alloc |
char *alloc(nbytes) |
lib1.c |
stdio.h |
atoi |
int atoi(s) |
lib1.c |
stdio.h |
bdos |
char bdos(c, de, hl) |
lib0.mac |
bdosfunc.h |
bdosh |
int bdosh(c, de, hl) |
lib0.mac |
bdosfunc.h |
bios |
char bios(bios_code, c) |
lib0.mac |
bdosfunc.h |
call |
int call(addr, a, hl, bc, de) |
lib0.mac |
stdio.h |
calla |
char calla(addr, a, hl, bc, de) |
lib0.mac |
stdio.h |
close |
STATUS close(fd) |
lib2.c |
stdio.h |
creat |
FD creat(filename) |
lib2.c |
stdio.h |
execl |
VOID execl(nargs, progname, args) |
libk.c |
stdio.h |
execv |
VOID execv(progname, argv) |
libk.c |
stdio.h |
exit |
VOID exit(code) |
libk.c |
stdio.h |
expargs |
int expargs(argc, argv, maxargc, xargv) |
lib2.c |
stdio.h |
fclose |
STATUS fclose(fp) |
lib2.c |
stdio.h |
fgets |
char *fgets(s, n, fp) |
lib2.c |
stdio.h |
fopen |
FILE *fopen(nargs, xfn, xmode, xbsiz) |
lib2.c |
stdio.h |
fprintf |
STATUS fprintf(nargs, iobuf, format) |
lib3.c |
stdio.h |
fputs |
STATUS fputs(s, fp) |
lib2.c |
stdio.h |
free |
void free(ap) |
lib1.c |
stdio.h |
fscanf |
int fscanf(nargs, iobuf, format) |
lib3.c |
stdio.h |
fsetbin |
STATUS fsetbin(fp) |
lib2.c |
stdio.h |
fsettext |
STATUS fsettext(fp) |
lib2.c |
stdio.h |
getc |
int getc(fp) |
lib2.c |
stdio.h |
getch |
char getch() |
lib2.c |
stdio.h |
getchar |
int getchar() |
lib2.c |
stdio.h |
getche |
char getche() |
lib2.c |
stdio.h |
gets |
char *gets(s, n) |
lib2.c |
stdio.h |
inp |
char inp(port) |
lib0.mac |
stdio.h |
isalpha |
int isalpha(c) |
stdio.h |
stdio.h |
iscntrl |
int iscntrl(c) |
stdio.h |
stdio.h |
isdigit |
int isdigit(c) |
stdio.h |
stdio.h |
islower |
int islower(c) |
stdio.h |
stdio.h |
isspace |
int isspace(c) |
stdio.h |
stdio.h |
isupper |
int isupper(c) |
stdio.h |
stdio.h |
kbhit |
BOOL kbhit() |
lib2.c |
stdio.h |
longjmp |
void longjmp(env, val) |
lib0.mac |
stdio.h |
max |
int max(x, y) |
lib1.c |
stdio.h |
memcpy |
void memcpy(dest, source, count) |
lib0.mac |
stdio.h |
memset |
void memset(dest, byte, count) |
lib0.mac |
stdio.h |
min |
int min(x, y) |
lib1.c |
stdio.h |
movmem |
void movmem(source, dest, count) |
lib0.mac |
stdio.h |
open |
STATUS open(filename, mode) |
lib2.c |
stdio.h |
outp |
void outp(port, val) |
lib0.mac |
stdio.h |
printf |
STATUS printf(nargs, format) |
lib3.c |
stdio.h |
putc |
STATUS putc(c, fp) |
lib2.c |
stdio.h |
putchar |
STATUS putchar(c) |
lib2.c |
stdio.h |
puts |
STATUS puts(s) |
lib2.c |
stdio.h |
qsort |
void qsort(base, n, width, compar) |
lib1.c |
stdio.h |
read |
int read(fd, buf, n) |
lib2.c |
stdio.h |
rename |
STATUS rename(oldname, newname) |
lib2.c |
stdio.h |
rsvstk |
void rsvstk(n) |
lib1.c |
stdio.h |
sbrk |
char *sbrk(n) |
lib1.c |
stdio.h |
scanf |
int scanf(nargs, format) |
lib3.c |
stdio.h |
sensebrk |
VOID sensebrk() |
lib2.c |
stdio.h |
setjmp |
VOID setjmp(env) |
lib0.mac |
stdio.h |
setmem |
VOID setmem(dest, byte, count) |
lib0.mac |
stdio.h |
sprintf |
VOID sprintf(nargs, buffer, format) |
lib3.c |
stdio.h |
sscanf |
int sscanf(nargs, line, format) |
lib3.c |
stdio.h |
strcat |
char *strcat(d, s) |
lib1.c |
stdio.h |
strcmp |
int strcmp(s, t) |
lib1.c |
stdio.h |
strcpy |
char *strcpy(d, s) |
lib1.c |
stdio.h |
strlen |
size_t strlen(s) |
lib1.c |
stdio.h |
tolower |
char tolower(c) |
lib1.c |
stdio.h |
toupper |
char toupper(c) |
lib1.c |
stdio.h |
ungetc |
STATUS ungetc(c, fp) |
lib2.c |
stdio.h |
ungetch |
VOID ungetch(c) |
lib2.c |
stdio.h |
unlink |
STATUS unlink(filename) |
lib2.c |
stdio.h |
write |
int write(fd, buf, n) |
lib2.c |
stdio.h |
Tabel 4: Inhoud Compiler Disk v1.20
------------------------------------------------------------------- PRIMARY FILES SUPPORT FILES SOURCE FILES -------------------------------------------------- SYSTEM: cf.com cg.com fpc.com. . . . . . lib.tco mx.com . . . . . . arel.bat crel.bat LIBRARY FILES: ck.rel . . . . . . . . . . . . . . . .ck.mac clib.rel . . . . . . . . . . . . . . .clibc.c clibmac.mac direct.c io.c malloc.c process.c stdio.c stdlib.c string.c crun.rel . . . . . . . . . . . . . . .crun.mac cend.rel . . . . . . . . . . . . . . .cend.mac HEADER FILES: stdio.h bdosfunc.h conio.h ctype.h direct.h io.h malloc.h memory.h process.h setjmp.h stdlib.h string.h type.h BATCH FILES: c.bat mksys.bat forremk.bat genlib.bat . . . . genliba.bat genlibc.bat genrel.bat gentco.bat SAMPLE FILES: q.c. . . . . . . . mkq.bat . . . . . .rnd.mac line.mac color.mac calbio.mac search.c . . . . . search.bat. . . . .bk.mac wc.c head.c rom1.c . . . . . . . . . . . . . . . .rom0.mac -------------------------------------------------------------------
CF is de 'parser'. Dit betekent zoveel als 'taalkundige ontleder'. Een C file wordt door CF om gewerkt/vertaald tot een zogenaamde T-code file met de extensie '.TCO'. In deze TCO file staat gecodeerd (in ASCII) de programmacode van de C file. Het eventuele commentaar is verwijderd. De T-code file dient als input voor de volgende compilatiestap middels 'CG.COM'. Tevens wordt de T-code file gebruikt door FPC voor de parametercontrole.
Het intikken van 'CF' achter de DOS-prompt levert:
MSX-C ver 1.20p (parser) Copyright (C) 1989 by ASCII Corporation Usage: cf [options] filename options available: -c disables comment nesting -e[filename] makes diagnostic file -f enables implicit function and parameter declaration -t enables implicit pointer convertion -j enables kanji code literal -m displays memory usage statistics -o[filename] makes T-code file -rP:S:H allocate tables in ratio P:S:H (Pool:Symbol table:Hash) -s continues submit even if errors are detected
De op te geven 'filename' moet van het type '.C' zijn. Deze extensie wordt door CF automatisch achter de filenaam geplakt en behoeft dus niet te worden opgegeven. Bijvoorbeeld: behandelen van de file FRED.C door CF:
CF FRED
Er kan eventueel gebruik gemaakt worden van switches:
-c : 'disable comment nesting'
Indien deze switch wordt gebruikt is het niet meer mogelijk om commentaar te nesten (in elkaar te laten vallen). Het volgende is dan niet meer mogelijk:
/* /* Commentaar...commentaar...
...commentaar */ */
In de oorspronkelijke definitie van C is dit nesten niet toegestaan. Toch is het nesten handig bij het markeren van grote stukken source-code die eventjes niet meegecompileerd hoeven te worden. Er kan dan worden volstaan met het zetten van een '/*' en een '*/' aan het begin respectievelijk einde van het stuk source code.
-e[X] : 'makes diagnostic file on drive X'
Met behulp van deze switch kan een diagnose file met de extensie '.DIA' aangemaakt worden op drive 'X'. De uitvoer van CF wordt nu gedeeltelijk naar de DIA file gestuurd in plaats van naar het beeldscherm. Deze optie kan makkelijk zijn om foutmeldingen te verzamelen.
-f : 'enables implicit function and parameter declaration'
Functies en parameters hoeven met deze optie niet meer expliciet gedeclareerd te worden. Het is een goede gewoonte in C om functies altijd expliciet te declareren en dus geen gebruik te maken van deze switch.
-t : 'enables implicit pointer conversion'
Indien deze optie wordt gebruikt, worden pointers automatisch geconverteerd. Dus wanneer in een vergelijking een 'pointer to char' en een 'pointer to int' voorkomen, wordt geen foutmelding gegeven. Ook voor deze switch geldt: misschien handig als je weet wat je doet, als je niet weet wat je aan het doen bent resulteert het gebruik van deze optie waarschijnlijk alleen maar in meer moeilijk te traceren fouten!
-j : 'enables kanji code literal'
Iets met kanji (?). Deze optie is niet aanwezig bij MSX-C versie 1.10.
-m : 'displays memory usage statistics'
Geeft informatie over het geheugengebruik van de 3 interne tabellen van CF. De te reserveren geheugenruimte kan worden opgegeven middels de '-r' switch.
-o[filename] : 'makes T-code file'
Maakt de T-code (.TCO) file volgens de aangegeven specificatie. Bij MSX-C versie 1.10 kan alleen een (andere) drive worden gespecificeerd.
-rP:S:H : 'allocates tables in ratio Pool/Symbol_table/Hash'
Hiermee kan opgegeven worden in welke verhouding de grootte van de 3 interne tabellen van CF ingedeeld dient te worden. Bijvoorbeeld: '-r3:1:2'. Zie ook: '-m'.
-s : 'continues submit even if errors are detected'
Hiermee kan worden doorgegaan met het coderen ondanks dat er fouten zijn gedecteerd.
Sommige switches mogen worden samengevoegd tot één string, voorafgegaan door één '-' teken. Dit geldt niet voor alle switches; uitproberen dus.
Voorbeeld: Behandelen van de file FRED.C door CF, waarbij de files FRED.TCO en FRED.DIA gemaakt moeten worden op drive B, de commando's niet genesteld mogen zijn en het geheugengebruik zichtbaar moet worden gemaakt:
CF -coBm -eB FRED
CG is de Code Generator. De T-code file wordt door CG omgezet in een file met de extensie '.MAC'. In deze MAC file staat de gecompileerde C file in mnemonic notatie! Via de Macro Assembler M80 kan deze file worden gecompileerd. Het intikken van 'CG' achter de DOS-prompt levert:
MSX-C ver 1.20p (code generator)
Copyright (C) 1989 by ASCII Corporation
Usage: cg [-rNkulo<filename>] filename
De op te geven 'filename' moet een T-code file zijn, dus de extensie '.TCO' hebben. Deze extensie wordt door CG automatisch achter de filenaam geplakt en behoeft dus niet te worden opgegeven. Tijdens het compileren laat CG elke functienaam zien die wordt gecompileerd. Achter de functienaam wordt de voortgang van het compileerproces zichtbaar gemaakt door achtereenvolgens een punt weer te geven per gecompileerde sprong of loop in de functie, een dubbele punt per gedeclareerde variabele en een puntkomma ter afsluiting. Het compileerproces kan worden beïnvloed door de volgende switches:
-rN:
De default grootte van de symbol table kan worden opgeven door middel van een decimaal getal N. Wanneer CG vastloopt doordat de symbol table te klein is, wordt een advies gegeven met betrekking tot de grootte van de symbol table.
-k:
De TCO file die als input heeft gediend wordt automatisch gewist.
-u:
De functienamen en de voortgangssymbolen (...::;) worden niet getoond op het scherm.
-l:
(??) Het enige effect wat ik tot nu toe heb kunnen ontdekken is het plaatsen van een '@' achter het 'printf' label in de MAC file. (?)
-o<filename>:
De output (MAC) file wordt gestuurd naar de gespecificeerde file.
Voorbeeld: Behandelen van de file FRED.TCO door CG, waarbij de file FRED.MAC geplaatst moet worden op schijf B, de symbol table een grootte van 2000 moet krijgen, en de file FRED.TCO na afloop gewist moet worden:
CG -oBr2000k FRED
FPC is de Function Parameter Checker. Met behulp van FPC kan gecontroleerd worden of de functieaanroepen van een C programma wel volledig zijn; er wordt gecontroleerd of de parameters bij de functieaanroep van het juiste type zijn (int, char) en of er genoeg parameters mee worden gegeven. Deze controle kan u veel zoekwerk besparen.
FPC maakt voor deze controle gebruik van speciale T-code files waarin alleen de headers van de functies zijn opgenomen. Deze files kunnen door FPC zelf aangemaakt worden. Er zijn standaard twee van deze 'header T-code files' met daarin headers van functies uit de volgende bibliotheken:
LIB.TCO : LIB0, LIB1, LIB2, LIB3, LIBK
MLIB.TCO : CURSES, GLIB, MSXBIOS, MATH
Het intikken van 'FPC' achter de DOS-prompt levert:
MSX-C function parameter checker ver 1.20p
Usage: fpc [-istu] [-c outputfile] [-d func[,func...]] inputfile(s)
Met behulp van de optie '-c outputfile' kan de bovengenoemde file met headers worden aangemaakt. De betekenissen van de overige parameters zijn mij nog niet duidelijk. Enkele voorbeelden:
FPC fred mlib lib
heeft tot gevolg dat alle gebruikte functies in de file FRED.C worden gecontroleerd. Bij deze controle wordt gebruik gemaakt van de files MLIB.TCO en LIB.TCO.
FPC -c lib lib0 lib1 lib2 lib3 libk
zorgt ervoor dat een file 'LIB.TCO' aangemaakt wordt met daarin headers van de functies uit de LIB0, LIB1, LIB2, LIB3 en LIBK bibliotheken. FPC maakt daarbij gebruik van de T-code files van deze bibliotheken.
MX is de Module Extracting Utility. Met behulp van MX kan een library gemaakt worden met hersitueerbare (relocatable) modulen. MX splitst de opgegeven file in modulen die vervolgens allemaal apart gecompileerd dienen te worden tot REL-files. Door al deze REL-files met behulp van LIB80 samen te voegen heeft men de uiteindelijke bibliotheek verkregen. Om deze cyclus te vergemakkelijken heeft MX de mogelijkheid om een batchfile te genereren waarin de benodigde commando's zijn opgenomen. Het intikken van 'MX' achter de DOS-prompt levert:
MSX-C module extracting utility ver 1.20p Usage: mx [options] filename [module list] options: -l generates batch to make library file -o[path\] makes output files on directory -uX replaces every underscore(_) character to X
De op te geven 'filename' mag de extensie .MAC of .TCO hebben. De extensie wordt automatisch achter de filenaam geplakt en wanneer beide aanwezig zijn heeft de MAC file voorrang. De geëxtraheerde modules worden op de disk bewaard met hun modulenaam als filenaam (pas dus op voor overschrijven van een bestaande file!) en eenzelfde extensie als de source file (TCO of MAC). Eventueel kan een 'module list' opgegeven worden. Dit is een rij door spaties van elkaar gescheiden modulenamen. Alleen deze modules worden dan geëxtraheerd. Indien geen 'module list' wordt opgegeven worden alle modules geëxtraheerd.
-l : 'generates batch to make library file'
Output wordt gegenereerd met daarin alle commando's voor het compileren en weer samenvoegen van alle modules. Om hier een batch file van te maken moet de output middels het '>'-commando worden omgeleid naar een batch-file. Voor het genereren van de output maakt MX gebruik van twee batchfiles met compileercommando's: AREL.BAT voor MAC files en CREL.BAT voor T-code files. Slordig is wel dat de eerste en de laatste regel van de batch-file een voor DOS onbegrijpelijke tekst zijn en dus twee foutmeldingen opleveren bij het runnen van de batch-file.
-o[path\] : 'makes output files on directory'
Alle output files worden gestuurd naar de gespecificeerde directory. Bij MSX-C versie 1.10 kan alleen de drive worden opgegeven.
-uX : 'replaces every underscore(_) character to X'
Indien in de te extraheren modulenaam het '_' teken voorkomt wordt deze vervangen door een op te geven teken X. Bijvoorbeeld:
MX -loB crun > temp.bat
Dit commando zorgt ervoor dat uit de file CRUN.MAC alle modules worden geëxtraheerd en onder hun modulenaam en de extensie .MAC bewaard op schijf B. De output van MX wordt omgeleid naar de file TEMP.BAT, zodat na het commando:
TEMP
de geëxtraheerde modules worden gecompileerd en samengevoegd tot de bibliotheek CRUN.LIB. Indien men uiteindelijk deze bibliotheek wil gebruiken met L80, moet de bibliotheek worden hernoemd tot CRUN.REL. Nog een voorbeeld:
MX -loB crun lauhl laut1 > temp.bat
Met dit commando worden in plaats van alle modules nu alleen de modules 'lauhl' en 'laut1' gextraheerd. Voor de rest is het resultaat hetzelfde als bij het eerste voorbeeld.
Nog een laatste waarschuwing: Zorg ervoor dat je source-file geen module bevat met dezelfde naam als je source file, want deze module zal anders bij het extraheren je source file overschrijven.
De macro-assembler M80 is bij MSX-C versie 1.20 op een dusdanige manier aangepast dat de assember ook kan werken met subdirectories. Gerefeerd kan worden aan deze versie van de assembler middels:
MSX.M-80 2.00
Ook wordt bij het genereren van een listing file de huidige datum bovenaan de pagina gezet. Dit in tegenstelling tot versie 1.00 waar de release-datum van M80 (01-Apr-85) bovenaan de pagina wordt gezet. Een uitgebreide handleiding van M80 circuleert in het MSX-circuit. Ook kan de handleiding worden gedownload van verschillende BBS'en.
De linker is bij MSX-C versie 1.20 op een dusdanige manier aangepast dat de linker ook kan werken met subdirectories. Gerefeerd kan worden aan deze versie middels:
MSX.L-80 2.00 03-Apr-89 Copyright (c) 1989 Microsoft
Een beschrijving van L80 is opgenomen in de handleiding van M80. Deze handleiding circuleert in het MSX-circuit. Ook kan de handleiding worden gedownload van verschillende BBS'en.
Versie 1.20 van de Standard Library maakt volledig gebruik van MSX-DOS 2. Programma's die gebruik maken van de Standard Library versie 1.20, kunnen derhalve niet draaien onder MSX-DOS 1; een MSX-C programma controleert automatisch het MSX-DOS versienummer en zal een foutmelding geven indien het DOS-versienummer lager is dan 2.xx.
De Standard Library is samengesteld uit de volgende onderdelen:
CK.MAC MSX-C Ultra Main Program (Ver 1.2) CLIBMAC.MAC MSX-C Standard Library Assembler Part (Ver 1.2) CRUN.MAC MSX-C Run Time Library (Ver 1.2) CEND.MAC MSX-C Standard Trailer File (Ver 1.2) DIRECT.C Directory Manipulate Functions IO.C Low Level Input/Ouput Functions MALLOC.C Storage Management Functions PROCESS.C Process Control Functions STDIO.C Buffered Input/Output Functions STDLIB.C Standard Library STRING.C String Manipulate Functions
Alle source files (met uitzondering van CK.MAC, CRUN.MAC en CEND.MAC) zijn gecompileerd en samengevoegd tot de relocatable library file CLIB.REL. De volgende header files zijn aanwezig:
BDOSFUNC.H MSX-DOS Function Call Support CONIO.H Console and I/O Port Functions CTYPE.H Character Type Header DIRECT.H Directory Manipulation Functions IO.H Low Level File Input/Output Functions MALLOC.H Storage Management Functions MEMORY.H Memory Manipulate Functions PROCESS.H Process Control Functions SETJMP.H Longjmp Support STDIO.H Buffered Input/Output Functions STDLIB.H Standard Library STRING.H String Manipulate Functions TYPE.H Common Types and Constants
De header file STDIO.H wordt bij compilatie automatisch gekoppeld aan de overige header files.
De voor de gebruiker beschikbare functies van de Standard Library worden hieronder beschreven. Aangegeven is achtereenvolgens: de naam van de functie, de declaratie zoals deze in de source library aanwezig is, de source file waarin de source code van de functie is te vinden, en een korte beschrijving van de functie. De functies die beginnen met een underscore (_) zijn alleen bestemd voor intern gebruik van de MSX-C library. Bij het debuggen van de library kan het handig zijn om te weten waar deze functies zijn gecodeerd en wat ze ongeveer doen.
Tabel 5: Functies in Standard Library v1.20
Name |
Declaration |
SourceFile |
Description |
_attr |
TINY _attr(path) |
direct.c |
Get attribute of directory entry. |
_bc |
TINY _bc(c, b) |
stdio.c |
|
_chai |
VOID _chai(limit, fd) |
clibmac.mac |
|
_chkversion |
VOID _chkversion() |
clibmac.mac |
|
_cmp |
int _cmp(p, q) |
direct.c |
|
_cutpath |
char *_cutpath(mode, p) |
stdlib.c |
Cut out path. |
_deffcb |
char *_deffcb(fn, fcb) |
process.c |
Set up default FCB area for the program to be exec'ed. |
_exec |
VOID _exec(progname, nargs, param, checkp) |
Prepare to call _execgo. |
|
_execgo |
char _execgo(progname, lflag) |
process.c |
Execute! |
_exit |
VOID _exit(code) |
clibmac.mac |
Jumps to the "Terminate with error code (62h)" BDOS-routine. |
_ffirst |
STATUS _ffirst(fn, fib, flag) |
clibmac.mac |
|
_fillbuf |
STATUS _fillbuf(fp) |
stdio.c |
|
_flshserial |
VOID _flshserial() |
stdio.c |
|
_fnext |
STATUS _fnext(fib) |
clibmac.mac |
|
_getc |
int _getc(fp) |
stdio.c |
|
_gv2 |
unsigned _gv2(p) |
stdio.c |
|
_igs |
int _igs(func, ___) |
stdio.c |
Allows various aspects of file handles to be examined and altered. In particular it can be used to determine whether a file handle refers to a disk file or a device. _ioctl uses the "I/O Control for devices (4Bh)" BDOS-routine. Consult your DOS Reference Manual for more details. |
_ioctl |
unsigned _ioctl(fd, subfunc, stat) |
io.c |
|
_main |
VOID _main() |
process.c |
Called by xmain in ck.rel. |
_noraw |
TINY _noraw(fd) |
io.c |
|
_p_path |
char *_p_path(fn, last_item, flag) |
clibmac.mac |
|
_parsefn |
char *_parsefn(fn, fcb, flag) |
clibmac.mac |
|
_putc |
STATUS _putc(c, fp) |
stdio.c |
|
_raw |
TINY _raw(fd) |
io.c |
|
_rawmode |
TINY _rawmod(fd, mode) |
io.c |
|
_scn |
int _scn(param, infunc, ___, ugfunc) |
stdio.c |
|
_seek |
STATUS _seek(fd, offset, mode) |
clibmac.mac |
|
_setarg |
VOID _setarg(s) |
process.c |
Set an argument string to command line (for exec). |
_setprog |
STATUS _setprog(prog, whole, checkp) |
process.c |
Search prog and set fullpath name in whole (for exec) |
_skipsp |
char *_skipsp(s) |
process.c |
Skip leading blanks. |
_spr |
STATUS _spr(param, outfunc, ___) |
stdio.c |
|
_sscn |
int _sscn(ptr) |
stdio.c |
|
_sspr |
STATUS _sspr(c, ptr) |
stdio.c |
|
_stdenv |
VOID _stdenv(fp) |
process.c |
|
_suget |
VOID _suget(c, ptr) |
stdio.c |
|
_swp |
VOID _swp(width, x, y) |
stdlib.c |
|
_unquote |
VOID _unquote(s) |
process.c |
|
_uspr |
recursive TINY _uspr(str, n, radix) |
stdio.c |
|
_whlpath |
STATUS _whlpath(whole, prog) |
direct.c |
|
abs |
int abs(n) |
stdlib.c |
Returns the absolute value of its int argument. |
alloc |
char *alloc(nbytes) |
malloc.c |
Returns a pointer to space for nbytes, or NULL if the request cannot be satisfied. The space is unitialized. |
atoi |
int atoi(s) |
stdlib.c |
Converts s to int. |
bdos |
char bdos(c) |
clibmac.mac |
Calls BDOS-routine and returns a character (register A). |
bdosh |
int bdosh(c) |
clibmac.mac |
Calls BDOS-routine and returns an integer (register HL). |
bios |
char bios(code) |
clibmac.mac |
Calls CP/M BIOS routine. Valid values for code include: |
call |
int call(addr, a, hl, bc, de) |
clibmac.mac |
Calls routine starting at address pointed to by adrr. Before calling, register a, hl, bc and de will be filled with the specified values. Returns with integer (register HL). |
calla |
char calla(addr, a, hl, bc, de) |
clibmac.mac |
Calls routine starting at address pointed to by addr. Before calling, register a, hl, bc and de will be filled with the specified values. Returns with character (register A). |
callxx |
VOID callxx(adrs, reg) |
clibmac.mac |
Calls routine starting at address pointed to by adrs. Before calling, register af, ix, iy, bc, de and hl will be filled according to reg (structure XREG is specified in BDOSFUNC.H). On returning, reg will be updated with the new register values. |
chdir |
STATUS chdir(path) |
direct.c |
Change current work directory to path. |
clearerr |
VOID clearerr(fp) |
stdio.c |
Clears all error settings from file fp. |
close |
STATUS close(fd) |
clibmac.mac |
Releases the specified file handle for re-use by directly calling the operating system using the "Close file handle (45h)" BDOS-routine. Any buffered data will be flushed to disk. Returns ERROR if an error occured. |
creat |
FD creat(filename) |
clibmac.mac |
Creates a file or sub-directory by directly calling the operating system using the "Create file handle (44h)" BDOS-routine. Open mode is set to "no read" and no special attributes. Returns file handle or ERROR if an error occured. |
eof |
TINY eof(fd) |
io.c |
Returns zero if end of file occured. |
execl |
VOID execl(nargs, progname, args) |
process.c |
Execute program progname with argument string args. No path check will be done. |
execlp |
VOID execlp(nargs, progname, args) |
process.c |
Execute program progname with argument string args. A path check will be done. |
execv |
VOID execv(progname, argv) |
process.c |
Execute program progname with argument array argv. No path check will be done. |
execvp |
VOID execvp(progname, argv) |
process.c |
Execute program progname with argument array argv. A path check will be done. |
exit |
VOID exit(code) |
process.c |
Causes normal program termination. Open files are flushed, open streams are closed, and control plus code is returned to whatever loaded the transient program. This will almost always be the command interpreter, but in some cases it may be another transient program. |
expargs |
int expargs(argc, argv, maxargc, xargv) |
direct.c |
?? |
fclose |
STATUS fclose(fp) |
stdio.c |
Flushes any unwritten data for fp, discards any unread buffered input, frees any automatically allocated buffer, then closes the stream. It returns EOF if any errors occured, and zero otherwise. |
fcloseall |
TINY fcloseall() |
stdio.c |
Closes all open streams using fclose. Returns number of closed streams or ERROR if an error occured. |
feof |
int feof(fp) |
stdio.h |
Returns non-zero if the end of file indicator for fp is set. |
ferror |
int ferror(fp) |
stdio.h |
Returns non-zero if the error indicator for fp is set. |
fflush |
STATUS fflush(fp) |
stdio.c |
On an output stream, fflush causes any buffered but unwritten data to be written; on an input stream, the effect is undefined. It returns EOF for a write error, and zero otherwise. fflush(NULL) flushes all output streams. |
fgets |
char *fgets(s, n, fp) |
stdio.c |
Fgets reads at most the next n-1 characters into the array s, stopping if a newline is encountered; the newline is included in the array, which is terminated by '\0'. fgets returns s, or NULL if end of file or error occurs. |
fileno |
int fileno(fp) |
stdio.h |
Returns the file handle of file fp. File handles are used by the system calls like open, write, create and unlink. |
flushall |
TINY flushall() |
stdio.c |
Flushes all streams using fflush. Returns number of flushed streams. |
fopen |
FILE *fopen(nargs, xfn, xmode, xbsiz) |
Opens the file pointed to by xfn, and returns a stream, or NULL if the attempt fails. Legal values for xmode include: |
|
fprintf |
STATUS fprintf(nargs, iobuf, format) |
Converts and writes output to iobuf under the control of format. The return value is non-zero if an error occured. The format string contains two types of objects: ordinary characters, which are copied to the output stream, and conversion specifications, each of which causes conversion and printing of the next successive argument to fprintf. Each conversion specification begins with the character % and ends with a conversion character. Between the % and conversion character there may be, in order: |
|
fputs |
STATUS fputs(s, fp) |
stdio.c |
Fputs writes the string s (which need not contain '\n') on fp; it returns non-negative, or EOF for an error. |
fread |
int fread(buf, size, count, fp) |
stdio.c |
Fread reads from fp into the array buf at most count objects of size size. Fread returns the number of objects read; this may be less than the number requested. Feof and ferror must be used to determine status. |
free |
void free(ap) |
malloc.c |
Deallocates the space pointed to by ap; it does nothing if ap is NULL. ap must be a pointer to space previously allocated by alloc. |
fscanf |
int fscanf(nargs, iobuf, format) |
Reads from iobuf under control of format, and assigns converted values through subsequent arguments, each of which must be a pointer! It returns when format is exhausted. fscanf returns EOF if end of file or an error occurs before any conversion; otherwise it returns the number of input items converted and assigned. |
|
fsetbin |
STATUS fsetbin(fp) |
stdio.c |
Set file mode to binary mode. |
fsettext |
STATUS fsettext(fp) |
stdio.c |
Set file mode to text mode. |
fwrite |
int fwrite(buf, size, count, fp) |
stdio.c |
Fwrite writes, from the array buf, count objects of size size on fp. It returns the number of objects written, which is less than count on error. |
getc |
int getc(fp) |
stdio.c |
Getc returns the next character of fp as an unsigned char (converted to an int), or EOF if end of file or error occurs. |
getch |
char getch() |
io.c |
Getch reads a character from the standard input. If no character is ready it will wait for one. No echo or control characters checks will be done. |
getchar |
int getchar() |
stdio.c |
Getchar is equivalent to getc(stdin). |
getche |
char getche() |
io.c |
Getche reads a character from the standard input and echos it to the standard output. If no character is ready it will wait for one. Various control characters will be trapped by this function for various control purposes. If one of these characters is detected then it will be processed and this function will wait for another character. Thus these characters will never be returned by this function. |
getcwd |
char *getcwd(cwd, n) |
direct.c |
Get current work directory. |
getenv |
char *getenv(var) |
stdlib.c |
Returns the environment string associated with var. Returns NULL if the enviroment name var is invalid or if no memory can be nallocated for the temporary buffer. |
gets |
char *gets(s, n) |
stdio.c |
Gets reads the next input line into the array s; it replaces the terminating newline with '\0'. It return s, or NULL if end of file or error occurs. |
inp |
char inp(port) |
clibmac.mac |
Input character from port port. |
isalnum |
int isalnum(c) |
ctype.h |
Return non-zero if isalpha(c) or isdigit(c), 0 if not. |
isalpha |
int isalpha(c) |
ctype.h |
Return non-zero if c is alpabetic, 0 if not. |
isatty |
BOOL isatty(fd) |
io.c |
Returns zero if the file handle fd refers to a disk file, or non-zero if fd refers to a device. |
iscntrl |
int iscntrl(c) |
ctype.h |
Return non-zero if c is control character, 0 if not. |
isdigit |
int isdigit(c) |
ctype.h |
Return non-zero if c is digit, 0 if not. |
iskanji |
int iskanji(c) |
ctype.h |
Return non-zero if c is kanji first byte, 0 if not. |
iskanji2 |
int iskanji2(c) |
ctype.h |
Return non-zero if c is kanji second byte, 0 if not. |
islower |
int islower(c) |
ctype.h |
Return non-zero if c is lower case, 0 if not. |
isspace |
int isspace(c) |
ctype.h |
Return non-zero if c is blank, tab, newline, return, formfeed or vertical tab. |
isupper |
int isupper(c) |
ctype.h |
Return non-zero if c is upper case, 0 if not. |
isxdigit |
int isxdigit(c) |
ctype.h |
Return non-zero if c is hexadecimal digit, 0 if not. |
kbhit |
BOOL kbhit() |
io.c |
Returns non-zero when a character is ready (that is, a key was pressed) for input from the keyboard. kbhit directly calls the operating system using the "Console status (0Bh)" BDOS-routine. |
longjmp |
void longjmp(env, val) |
clibmac.mac |
Restores the state sved by the most recent call to setjmp, using information saved in ev, and execution resumes as if the setjmp function had just executed and returned the non-zero value val. The function containing the setjmp must not have terminated. Accessible objects have the values they had when longjmp was called, except that non-volatile automatic variables in the function calling setjmp become undefined if they were changed after the setjmp call. |
max |
int max(x, y) |
stdlib.c |
Returns the integer which represents the highest value. |
memcpy |
void memcpy(dest, source, count) |
clibmac.mac |
Copy lenght characters from source to dest. |
memset |
void memset(dest, byte, count) |
clibmac.mac |
Place character byte into first length characters of dest. |
min |
int min(x, y) |
stdlib.c |
Returns the integer which represents the lowest value. |
mkdir |
STATUS mkdir(path) |
direct.c |
Make directory path. |
movmem |
void movmem(source, dest, count) |
clibmac.mac |
Same as memcpy except that it works even if the objects overlap. |
open |
FD open(filename, mode) |
clibmac.mac |
Opens the file pointed to by filename. open is rather like the fopen function, except that instead of returning a file pointer, it returns a file descriptor, or NULL if the attempt fails. open directly calls the operating system using the "Open file handle (43h)" BDOS-routine, whilst fopen subserves the standard library. Legal values for mode are: |
outp |
void outp(port, val) |
clibmac.mac |
Output value val to port port. |
perror |
VOID perror(msg) |
stdlib.c |
Print previous error from dos. |
printf |
STATUS printf(nargs, format) |
stdio.c |
Equivalent to fprintf(stdout, format). |
putc |
STATUS putc(c, fp) |
stdio.c |
Putc writes the character s (which need not contain '\n') on fp. It returns the character written, or EOF for error. |
putchar |
STATUS putchar(c) |
stdio.c |
Putchar is equivalent to putc(c, stdout). |
putenv |
STATUS putenv(env) |
stdlib.c |
Sets environment item to the specified value. env must be of format: |
puts |
STATUS puts(s) |
stdio.c |
Puts writes the string s and a newline to stdout. It returns EOF if an error occurs, non-negative otherwise. |
qsort |
void qsort(base, n, width, compar) |
stdlib.c |
Sorts into ascending order an array base[0]...base[n-1] of objects of size size. The comparison function cmp must return negative if its first argument (the search key) is less than its second (a table entry), zero if equal, and positive if greater. |
read |
int read(fd, buf, bytes) |
clibmac.mac |
Reads bytes number of bytes from file fd to buffer buf. Returns with the number of bytes transferred; read returnes no error code. To obtain error codes, see fileno, feof, ferror or eof must be used. |
rename |
STATUS rename(oldname, newname) |
clibmac.mac |
Changes the name of the ffile; it returns non-zero if the attempt fails. |
rmdir |
STATUS rmdir(path) |
direct.c |
Remove directory. |
rsvstk |
void rsvstk(n) |
malloc.c |
Changes space to set aside for the stack to n. Default size is 1000. |
sbrk |
char *sbrk(n) |
malloc.c |
Returns a pointer to n more bytes of storage. sbrk returns -1 if there was no space. |
scanf |
int scanf(nargs, format) |
stdio.c |
Identical to fscanf(stdin, format). |
sensebrk |
VOID sensebrk() |
io.c |
If a character is ready (that is, a key was pressed) for input from the keyboard, it will be read and tested for certain special control characters. sensebrk directly calls the operating system, using the "Console status (0Bh)" BDOS-routine. |
setbuf |
VOID setbuf(fp, buf) |
stdio.c |
If buf is NULL, buffering is turned off for the stream. Otherwise setbuf is equivalent to (void) setvbuf(stream, buf, _IOBF, BUFSIZ). |
setjmp |
VOID setjmp(env) |
clibmac.mac |
Saves state information in env for use by longjmp. The return is zero from a direct call of setjmp, and non-zero from a subsequent call of longjmp. A call to setjmp can only occur in certain contexts, basically the test of if, switch, and loops, and only in simple relational expressions. |
setmem |
VOID setmem(dest, byte, count) |
Place character byte into first length characters of dest. |
|
setvbuf |
STATUS setvbuf(fp, buf, mode, size) |
stdio.c |
Controls buffering for the stream; it must be called before reading, writing, or any other operation. A mode of _IOFBF causes full buffering, _IOLBF line buffering of text files, and _IONBF no buffering. If buf is not NULL, it will be used as the buffer; otherwise a buffer will be allocated. size determines the buffer size. setvbuf returns non-zero for any error. |
sprintf |
VOID sprintf(nargs, buffer, format) |
stdio.c |
The same as printf except that the output is written into the string buffer, terminated with '\0'. buffer must be big enough to hold the result. |
sscanf |
int sscanf(nargs, line, format) |
Equivalent to scanf except that the input characters are taken from the string s. |
|
strcat |
char *strcat(d, s) |
string.c |
Concatenate string s to end of string d; return s. |
strchr |
char *strchr(s, c) |
string.c |
Return pointer to first occurence of c in s, or NULL if not present. |
strcmp |
int strcmp(s, t) |
string.c |
Compare string s to string t; return <0 if s<t, 0 if s==t, or >0 if s>t. |
strcpy |
char *strcpy(d, s) |
string.c |
Copy string s to string d, including '\0'; return d. |
strlen |
size_t strlen(s) |
string.c |
Return lenght of string s. |
strlwr |
char *strlwr(s) |
string.c |
Convert string s to lower case; return s. |
strncat |
char *strncat(d, s, n) |
string.c |
Concatenate at most n characters of string s to string d, terminate d with '\0'; return d. |
strncmp |
int strncmp(s, t, n) |
string.c |
Compare at most n characters of string s to string t; return <0 if s<t, 0 if s==t, or >0 if s>t. |
strncpy |
char *strncpy(d, s, n) |
string.c |
Copy at most n characters of string s to d; return d. Pad with '\0's if s has fewer than n characters. |
strupr |
char *strupr(s) |
string.c |
Convert string s to upper case; return s. |
tolower |
char tolower(c) |
string.c |
Return c converted to lower case. |
toupper |
char toupper(c) |
string.c |
Return c converted to upper case. |
ungetc |
STATUS ungetc(c, fp) |
stdio.c |
Ungetc pushes c (converted to an unsigned char) back onto fp, where it will be returned on the next read. Only one character of pushback per stream is guarenteed. EOF may not be pushed back. Ungetc returns the character pushed back, or EOF for error. |
ungetch |
VOID ungetch(c) |
stdio.c |
Ungetch(c) is equivalent to ungetc(c, stdin). |
unlink |
STATUS unlink(filename) |
clibmac.mac |
Deletes the object (file or sub-directory) specified by filename from the file system. Returns non-zero if an error occured. |
write |
int write(fd, buf, n) |
clibmac.mac |
Writes bytes number of bytes from buffer buf to file fd. Returns with the number of bytes transferred; write returnes no error code. To obtain error codes, see fileno, feof, ferror or eof. |
xmain |
void xmain() |
ck.mac |
Used internally. |
Tabel 6: Inhoud Library System Disk
------------------------------------------------------------------- PRIMARY FILES SUPPORT FILES SOURCE FILES -------------------------------------------------- LIBRARY FILES: mlib.rel . . . . . glib.rel msxbios.rel math.rel curses.rel glib.rel . . . . . . . . . . . . . . .glib.mac msxbios.rel. . . . . . . . . . . . . .msxbios.mac math.rel . . . . . . . . . . . . . . .mathmac.mac prsc.c curses.rel . . . . . . . . . . . . . .cursesc.c curses2.c T-CODE FILES: mlib.tco. . . . . .glib.tco math.tco msxbios.tco curses.tco glib.tco. . . . . .glibc.c msxbios.tco . . . .msxbiosc.c math.tco. . . . . .mathc.c prsc.c curses.tco. . . . .cursesc.c curses2.c HEADER FILES: glib.h . . . . . . msxbios.h msxbios.h math.h curses.h . . . . . msxbios.h BATCH FILES: msxc.bat genall.bat . . . . genmath.bat gencurs.bat genglib.bat genbios.bat genmlib.bat gentco.bat gen.bat mksys.bat forremk.bat SAMPLE FILES: gcal.com . . . . . . . . . . . . . . .gcal.c ------------------------------------------------------------------
De MSX-C Library System Disk bevat een complete bibliotheek voor specifieke MSX functies! De bibliotheek is opgebouwd uit 4 delen:
GLIB grafische functies
MSXBIOS BIOS functies
MATH rekenkundige functies voor variabelen van het type 'long' en 'float'
CURSES functies voor windows onder screen 0
Deze bibliotheken (respectievelijk GLIB.REL, MSXBIOS.REL, MATH.REL en CURSES.REL) zijn samengevoegd in MLIB.REL. De source van de grafische library is te vinden in GLIB.MAC: machinetaal dus! Veel grafische functies bestaan uit alleen maar een BIOS-aanroep, maar er zijn ook een aantal primaire functies 'echt' in machinetaal geprogrammeerd. De grafische library maakt voor de BIOS-aanroepen gebruik van de MSXBIOS library, welke is gedefinieerd in MSXBIOS.MAC.
De source-code van de rekenkundige functies is te vinden in MATHMAC.MAC. In PRSC.C bevinden zich nieuwe definities van de 'printf' en 'scanf' functies zodat deze ook overweg kunnen met de 'slong' en 'xdouble' variabelen. De source van de CURSES library is te vinden in CURSESC.C en CURSES2.C. De volgende header files zijn aanwezig:
GLIB.H Header file voor de grafische library
MATH.H Header file voor de rekenkundige library
MSXBIOS.H Header file voor de MSXBIOS library
CURSES.H Header file voor de windows libary
Voor het compileren van een C source file met gebruikmaking van de MSX-C library kan gebruik gemaakt worden van de batch file MSXC.BAT. Het is tevens mogelijk om de library aan te passen. Met behulp van de batchfile GENALL.BAT kan dan de complete library opnieuw aangemaakt worden. GENALL.BAT maakt hiervoor gebruik van achtereenvolgens GENMATH.BAT, GENCURS.BAT, GENGLIB.BAT, GENBIOS.BAT, GENMLIB.BAT, GENTCO.BAT en GEN.BAT.
Met behulp van MKSYS.BAT kan een 'Library System Disk' aangemaakt worden. Op deze disk komen dan alle files te staan die nodig zijn om een C programma te compileren tot een COM-file. Met behulp van FORREMK.BAT kan een 'Library Remake System Disk' aangemaakt worden. Op deze disk komen dan alle files te staan die nodig zijn om een gewijzigde MSX-C library te compileren. Als leerzaam voorbeeld programma is tenslotte het bioritme-programma GCAL.COM bijgevoegd. Dit programma is in zijn geheel geprogrammeerd in C. De source is te vinden in GCAL.C.
Tabel 7: Functies in Graphic Library
Name |
Declaration |
SourceFile |
HeaderFile |
Description Dutch |
boxfill |
VOID boxfill(x1, y1, x2, y2, color, logop) |
glib.mac |
glib.h |
Tekent een ingekleurde rechthoek op het scherm met linkerbovenhoek (x1, y1) en rechteronderhoek (x2, y2) in de kleur 'color'. 'Logop' geeft de logische operatie aan waarmee de kleur wordt bepaald. MSX-C gebruikt voor dit alles een eigen routine. |
boxline |
VOID boxline(x1, y1, x2, y2, color, logop) |
glib.mac |
glib.h |
Tekent een rechthoek op het scherm met linkerbovenhoek (x1, y1) en rechteronderhoek (x2, y2) in de kleur 'color'. 'Logop' geeft de logische operatie aan waarmee de kleur wordt bepaald. MSX-C gebruikt voor dit alles een eigen routine. |
calatr |
NAT calatr(plane) |
glib.mac |
glib.h |
Keert terug met een pointer naar de sprite-attribuut-tabel van het vlak 'plane'. |
calpat |
NAT calpat(patnum) [GLIB.MAC, GLIB.H] |
glib.mac |
glib.h |
Keert terug met een pointer naar het gedefinieerde sprite-patroon van de sprite met het nummer 'patnum'. |
circle |
VOID circle(x, y, r, color, s_angl, e_angl, aspect) |
glib.mac |
glib.h |
Tekent een cirkel op het scherm met middelpunt (x, y) en straal 'r' in de kleur 'color'. 'S_angl' en 'e_angl' geven de begin en eindhoek aan van het te tekenen cirkelgedeelte. 'Aspect' geeft de verhouding tussen de verticale en de horizontale straal weer. Aangeroepen wordt de cirkel-routine in het BASIC ROM met de volgende deelstring: |
color |
VOID color(fore, back, bord) |
glib.mac |
glib.h |
Wijzigt de voorgrond-, achtergrond- en randkleur in respectievelijk 'fore', 'back' en 'bord' door een aanroep van CHGCLR in het MSX-BIOS. |
colspr |
VOID colspr(plane, color) |
glib.mac |
glib.h |
Inkleuren van het sprite-vlak aangegeven door 'plane'. 'Color' is een pointer naar de kleurdata voor 8 of 16 bytes, alnaar gelang de sprite grootte (8x8 of 16x16). |
cpym2v |
VOID cpym2v(src, dir, dx, dy, dp, logop) |
glib.mac |
glib.h |
Een kader wordt gevuld met data die de Z80 aanbiedt vanaf adres 'src'. Het VRAM kader wordt aangegeven door (dx, dy). De nieuwe kleur wordt berekend door de logische operatie 'logop' uit te voeren met de oude pixelkleur en de nieuwe kleur. 'Dir' geeft aan of de door de Z80 geleverde data naar links (dir=0) of naar rechts (dir=1) weggeschreven moet worden (??). Deze functie werkt alleen bij de screenmodes 5 t/m 8. |
cpyv2m |
VOID cpyv2m(sx1, sy1, sx2, sy2, sp, dest) |
glib.mac |
glib.h |
Een kader wordt uit het VRAM gelezen en geplaatst vanaf 'dest' in het gewone RAM. Het kader wordt aangegeven door (sx1, sy1)-(sx2, sy2). 'Sp' geeft het aantal dots per lijn aan . Deze functie werkt alleen bij de screenmodes 5 t/m 8. |
cpyv2v |
VOID cpyv2v(sx1, sy1, sx2, sy2, sp, dx, dy, dp, logop) |
glib.mac |
glib.h |
Copieert een kader van de ene plaats in het VRAM naar een andere plaats in het VRAM. Het sourcekader wordt aangegeven door (sx1, sy1)-(sx2, sy2) en gecopieerd naar (dx, dy). De nieuwe kleur wordt berekend met behulp van 'logop' en de oude kleur. 'Sp' en 'dp' geven het aantal dots per lijn aan (??). Deze functie werkt alleen bij de screen modes 5 t/m 8. |
filvrm |
VOID filvrm(adr, len, data) |
glib.mac |
glib.h |
Schrijft 'len' bytes met de waarde 'data' naar het VRAM vanaf geheugenplaats 'adr'. |
getplt |
NAT getplt(pal) |
glib.mac |
glib.h |
Opvragen van kleurcodes van de paletkleur 'pal' door een aanroep van GETPLT in het SUBROM. Teruggekeerd wordt met de codes in de volgorde Groen, Rood en Blauw. |
ginit |
VOID ginit() |
glib.mac |
glib.h |
Initialiseert de lees- en schrijfpoort van de VDP. Deze routine moet bij gebruik van de glib-library in het begin van je programma één keer worden aangeroepen. |
glocate |
VOID glocate(x, y) |
glib.mac |
glib.h |
Zet de grafische cursor op de lokatie (x, y): (GRPACX, GRPACY) = (x, y). |
grpprt |
VOID grpprt(c, logop) |
glib.mac |
glib.h |
Print het karakter 'c' op het grafische scherm. De kleur van het karakter wordt bepaald door de logische operatie 'logop' los te laten op de nieuwe kleur en de oude pixelkleuren. Aangeroepen wordt de GRPPRT routine in het BIOS. |
gtxmax |
NAT gtxmax() |
glib.mac |
glib.h |
Geeft aan wat de horizontale resolutie is bij de huidige schermmode. |
gtymax |
NAT gtymax() |
glib.mac |
glib.h |
Geeft aan wat de verticale resolutie is bij de huidige schermmode. |
iniplt |
VOID iniplt() |
glib.mac |
glib.h |
Initialiseert het palet en het VRAM door een aanroep van INIPLT in het SUBROM. |
inispr |
VOID inispr(size) |
glib.mac |
glib.h |
Initialiseren van alle sprites door een aanroep van CLRSPR in de BIOS. Vervolgens worden afhankelijk van de waarde van 'size' de volgende acties ondernomen: |
interlace |
VOID interlace() |
glib.mac |
glib.h |
Schakelt het scherm in interlaced mode. |
invdp |
TINY invdp() |
glib.mac |
glib.h |
Leest een byte van de VDP leespoort. Zie setrd(). |
knjprt |
VOID knjprt(c, logop, mode) |
glib.mac |
glib.h |
Print het KANJI karakter 'c' op het grafische scherm. De kleur van het karakter wordt bepaald door de logische operatie 'logop' los te laten op de nieuwe kleur en de oude pixelkleuren. 'Mode' kan variëren van 0-2. Aangeroepen wordt de KNJPRT routine in het SUBROM. |
ldirmv |
VOID ldirmv(dst, src, len) |
glib.mac |
glib.h |
Copieert een blok van 'len' bytes van het VRAM naar het RAM geheugen. |
ldirvm |
VOID ldirvm(dst, src, len) |
glib.mac |
glib.h |
Copieert een blok van 'len' bytes van het RAM geheugen naar het VRAM. 'Src' bevat het beginadres van het RAM en 'dst' bevat het doeladres van het VRAM. |
line |
VOID line(x1, y1, x2, y2, color, logop) |
glib.mac |
glib.h |
Tekent een lijn op het scherm van (x1, y1) naar (x2, y2) in de kleur 'color'. 'Logop' geeft de logische operatie aan waarmee de kleur wordt bepaald. MSX-C gebruikt voor dit alles een eigen routine. |
outvdp |
VOID outvdp(data) |
glib.mac |
glib.h |
Schrijft 'data' naar de VDP schrijfpoort. Zie setwrt(). |
paint |
VOID paint(x, y, color, b_color) |
glib.mac |
glib.h |
Inkleuren van een vlak op het grafische scherm met de kleur 'color'. De coördinaten (x, y) moeten wijzen naar een punt op het in te kleuren vlak. 'B_color' geeft de kleur aan van de lijnen waarbinnen de computer met kleuren dient te blijven. Aangeroepen wordt een routine in het SUBROM. |
point |
TINY point(x, y) |
glib.mac |
glib.h |
Geeft het kleurnummer aan van het door de coördinaten (x, y) aangegeven punt. MSX-C gebruikt hiervoor een eigen routine. |
pset |
VOID pset(x, y, color, logop) |
glib.mac |
glib.h |
Zet een punt op de coördinaten (x, y) in de kleur 'color'. De nieuwe kleur wordt volgens 'logop' berekend met 'color' en de oude kleur. MSX-C gebruikt voor dit alles een eigen routine. |
putspr |
VOID putspr(plane, x, y, color, pat) [GLIB.MAC, GLIB.H] |
glib.mac |
glib.h |
Plaatst de sprite met het nummer 'pat' op positie (x, y) van het vlak aangegeven door 'plane'. De sprite krijgt de kleur aangegeven door 'color'. MSX-C gebruikt hiervoor een eigen routine. |
rdvdp |
TINY rdvdp(vreg) |
glib.mac |
glib.h |
Leest de waarde van het VDP register 'vreg' (0-23). De VDP registers kunnen eigenlijk niet worden gelezen, maar het BIOS bewaart in het geheugen copiën van deze registers. Deze copiën worden door deze functie uitgelezen. |
rdvsts |
TINY rdvsts(sreg) |
glib.mac |
glib.h |
Leest de waarde van het VDP status-register 'sreg' (0-9). |
rstplt |
VOID rstplt() |
glib.mac |
glib.h |
Terugzetten van palet vanuit VRAM door een aanroep van RSTPLT in het SUBROM. |
setpg |
VOID setpg(dsppag, actpag) |
glib.mac |
glib.h |
Zorgt ervoor dat van het VRAM de pagina 'dsppag' wordt afgebeeld en dat de instructies waarmee een nieuwe afbeelding wordt opgebouwd van toepassing zijn op de pagina 'actpag'. |
setplt |
VOID setplt(pal, grbdat) |
glib.mac |
glib.h |
Stelt de paletkleur 'pal' in aan de hand van de in 'grbdat' aangegeven groen-, rood- en blauwcodes. Aangeroepen wordt de SETPLT routine in het SUBROM. |
setrd |
VOID setrd(adr) |
glib.mac |
glib.h |
Maakt de VDP klaar voor uitlezen van het VRAM. Ná deze aanroep kan rechtstreeks van het VRAM worden gelezen met de instructie invdp(). Het VRAM-adres wordt na een leesinstructie automatisch verhoogd. |
setwrt |
VOID setwrt(adr) |
glib.mac |
glib.h |
Maakt de VDP klaar voor schrijven naar het VRAM. Ná deze aanroep kan rechtstreeks naar het VRAM worden geschreven met de instructie outvdp(). Het VRAM-adres wordt na een schrijfinstructie automatisch verhoogd. |
sprite |
VOID sprite(pat, data) |
glib.mac |
glib.h |
Definieert de sprite met het nummer 'pat'. 'Data' is een pointer naar de sprite definitie van 8 of 16 bytes, alnaar gelang de sprite grootte (8x8 of 16x16). |
totext |
VOID totext() |
glib.mac |
glib.h |
Zet het scherm in tekstmode door een aanroep van de BIOS routine TOTEXT. |
vpeek |
TINY vpeek(adr) |
glib.mac |
glib.h |
Leest de geheugenplaats 'adr' van het VRAM uit. |
vpoke |
VOID vpoke(adr, value) |
glib.mac |
glib.h |
Schrijft op geheugenplaats 'adr' van het VRAM de waarde 'value'. |
vramsize |
NAT vramsize() |
glib.mac |
glib.h |
Keert terug met de grootte van het Video geheugen (VRAM) (16, 64, of 128K). |
wrtvdp |
VOID wrtvdp(regnum, value) |
glib.mac |
glib.h |
Schrijft de waarde 'value' naar het VDP register met het nummer 'regnum'. Aangeroepen wordt de BIOS routine: WRTVDP. |
Tabel 8: Functies in BIOS Library
Name |
Declaration |
SourceFile |
HeaderFile |
Description Dutch |
*fnkstr |
char *fnkstr(n) |
msxbios.h |
msxbios.h |
Levert een pointer naar de string van functietoets 'n' (1-10). |
*inlin |
char *inlin() |
msxbios.mac |
msxbios.h |
Leest invoer van het toetsenbord vanaf de cursor in een buffer, totdat een CR of CTRL-STOP is ingedrukt. Geeft als resultaat het startadres van de buffer. Aangeroepen wordt de INLIN routine ($00B1) in het BIOS. |
beep |
VOID beep() |
msxbios.mac |
msxbios.h |
Laten horen van een geluidstoon. Aangeroepen wordt de BEEP routine ($00C0) in het BIOS. |
breakx |
TINY breakx() |
msxbios.mac |
msxbios.h |
Controleert de status van de CTRL-STOP toetscombinatie. Teruggekeerd wordt met 0 indien CTRL-STOP niet is ingedrukt, 1 indien wel. Aangeroepen wordt de BREAKX routine ($00B7) in het BIOS. |
calbas |
VOID calbas(adrs, reg) |
msxbios.mac |
msxbios.h |
Roept een routine in het BASIC-ROM aan die begint op het adres aangegeven door 'adrs'. 'Reg' is een pointer naar een tabel met registerwaarden voor F, A, BC, DE en HL. |
calbio |
VOID calbio(adrs, reg) |
msxbios.mac |
msxbios.h |
Roept een routine in het BIOS-ROM aan die begint op het adres aangegeven door 'adrs'. 'Reg' is een pointer naar een tabel met registerwaarden voor F, A, BC, DE en HL. |
callx |
VOID callx(adrs, reg) |
msxbios.mac |
msxbios.h |
Roept een routine aan die begint op het adres aangegeven door 'adrs'. 'Reg' is een pointer naar een tabel met registerwaarden voor F, A, BC, DE en HL. |
calslt |
VOID calslt(slot, adrs, reg) |
msxbios.mac |
msxbios.h |
Roept een routine in 'slot' aan die begint op het adres aangegeven door 'adrs'. 'Reg' is een pointer naar een tabel met registerwaarden voor F, A, BC, DE en HL. |
calsub |
VOID calsub(adrs, reg) |
msxbios.mac |
msxbios.h |
Roept een routine in het SUB-ROM aan de begint op het adres aangegeven door 'adrs'. 'Reg' is een pointer naar een tabel met registerwaarden voor F, A, BC, DE en HL. |
chget |
char chget() |
msxbios.mac |
msxbios.h |
Wacht op en keert terug met invoer van het toetsenbord. Aangeroepen wordt de CHGET routine ($009F) in het BIOS. |
chgsnd |
VOID chgsnd(onoff) |
msxbios.mac |
msxbios.h |
Verandert de status van de 1 bits geluidspoort (??). Indien 'onoff' gelijk is aan 0 (FALSE) wordt het uit gezet, anders aan. |
chput |
VOID chput(c) |
msxbios.mac |
msxbios.h |
Stuurt karakter 'c' naar het scherm. Aangeroepen wordt de CHPUT routine ($00A2) in het BIOS. |
chsns |
BOOL chsns() |
msxbios.mac |
msxbios.h |
Controleert de status van de toetsenbordbuffer. Teruggekeerd wordt met 0 indien zich geen karakter in de buffer bevindt. Aangeroepen wordt de CHSNS routine ($009C) in het BIOS. |
cls |
VOID cls() |
msxbios.mac |
msxbios.h |
Wissen van scherm. Aangeroepen wordt de CLS routine ($00C3) in het BIOS. |
di |
VOID di() |
msxbios.mac |
msxbios.h |
Uitschakelen van de interrupt. |
disscr |
VOID disscr() |
msxbios.mac |
msxbios.h |
Schakelt de weergave van het scherm uit. aangeroepen wordt de DISSCR routine ($0041) in het BIOS. Zie ook 'enascr()'. |
dspfnk |
VOID dspfnk() |
msxbios.mac |
msxbios.h |
Inschakelen van functietoets-display. Aangeroepen wordt de DSPFNK routine ($00CF) in het BIOS. |
ei |
VOID ei() |
msxbios.mac |
msxbios.h |
Inschakelen van de interrupt. |
enascr |
VOID enascr() |
msxbios.mac |
msxbios.h |
Schakelt de weergave van het scherm aan. Aangeroepen wordt de ENASCR routine ($0044) in het BIOS. Zie ook disscr(). |
erafnk |
VOID erafnk() |
msxbios.mac |
msxbios.h |
Uitschakelen van functietoets-display. Aangeroepen wordt de ERAFNK routine ($00CC) in het BIOS. |
gicini |
VOID gicini() |
msxbios.mac |
msxbios.h |
Initialiseert de PSG (Programmable Sound Generator). Aangeroepen wordt de GICINI routine ($0090) in het BIOS. |
gtpad |
TINY gtpad(pad) |
msxbios.mac |
msxbios.h |
Opvragen status van een randapparaat, aangegeven door 'pad': |
gtpdl |
TINY gtpdl(pdl) |
msxbios.mac |
msxbios.h |
Opvragen status van de paddle, aangegeven met 'pdl' (1-12). De paddles aan aansluiting 1 worden geïdentificeerd als 1, 3, 5, 7, 9 en 11. De paddles aan aansluiting 2 zijn 2, 4, 6, 8, 10 en 12. Teruggekeerd word met de waarde van de paddle (0-255). Aangeroepen wordt de GTPDL routine ($00DE) in het BIOS. |
gtstck |
TINY gtstck(port) |
msxbios.mac |
msxbios.h |
Leest de stand uit van een joystick of van de vier cursor-toetsen, afhankelijk van 'port': |
gttrig |
BOOL gttrig(trig) |
msxbios.mac |
msxbios.h |
Opvragen status van de vuurknop, aangegeven met 'trig': |
inifnk |
VOID inifnk() |
msxbios.mac |
msxbios.h |
Initialiseert de definities van de functietoetsen. Aangeroepen wordt de INIFN routine ($003E) in het BIOS. |
kilbuf |
VOID kilbuf() |
msxbios.mac |
msxbios.h |
Wissen van de toetsenbord buffer. Aangeroepen wordt de KILBUF routine ($0156) in het BIOS. |
locate |
VOID locate(csrx, csry) |
msxbios.mac |
msxbios.h |
Positioneert de cursor. Aangeroepen wordt de POSIT routine ($00C6) in het BIOS. |
lptout |
BOOL lptout(c) |
msxbios.mac |
msxbios.h |
Stuurt karakter 'c' naar de printer. Keert terug met 0 indien de uitvoer is gelukt, 1 indien afgebroken. Aangeroepen wordt de LPTOUT routine ($00A5) in het BIOS. |
lptstt |
BOOL lptstt() |
msxbios.mac |
msxbios.h |
Controleert de status van de printer. Teruggekeerd wordt met 0 indien de printer niet gereed is, 1 indien wel gereed. Aangeroepen wordt de LPTSTT routine in het BIOS. |
msx2 |
TINY msx2() |
msxbios.h |
msxbios.h |
Levert 0 indien het een MSX1 machine betreft. |
pinlin |
char *pinlin() |
msxbios.mac |
msxbios.h |
Leest invoer van het toetsenbord vanaf kolom 1 in een buffer, totdat een CR of CTRL-STOP is ingedrukt. Geeft als resultaat het startadres van de buffer. Aangeroepen wordt de PINLIN routine ($00AE) in het BIOS. |
rdpsg |
TINY rdpsg(reg) |
msxbios.mac |
msxbios.h |
Leest de inhoud van PSG register 'reg'. Aangeroepen wordt de RDPSG routine ($0096) in het BIOS. |
rdslt |
TINY rdslt(slot, adrs) |
msxbios.mac |
msxbios.h |
Leest van 'slot' het geheugenadres, aangegeven door 'adrs'. Aangeroepen wordt de RDSLT routine in het BIOS. |
rnd |
NAT rnd(range) |
msxbios.mac |
msxbios.h |
Keert terug met een random getal wat ligt in het bereik 0..'range'. |
screen |
VOID screen(mode) |
msxbios.mac |
msxbios.h |
Schakelt het scherm in 'mode' en initialiseert bij een MSX2 machine ook het palet. Aangeroepen wordt de CHGMOD routine ($005F) in het BIOS. |
snsmat |
TINY snsmat(row) |
msxbios.mac |
msxbios.h |
Keert terug met de status van de door 'row' gespecificeerde rij van het toetsenbord: |
sound |
VOID sound(reg, val) |
msxbios.mac |
msxbios.h |
Schrijft de waarde 'val' naar register 'reg' van de PSG. Aangeroepen wordt de WRTPSG routine ($0093) in het BIOS. |
wrslt |
VOID wrslt(slot, adrs, value) |
msxbios.mac |
msxbios.h |
Schrijft de waarde 'value' naar adres 'adrs' in het slot aangegeven door 'slt'. Aangeroepen wordt de WRSLT routine in het BIOS. |
In de MATH-library bevinden zich routines voor het rekenen met 'signed long' en 'xdouble' variabelen. Hiertoe wordt gebruik gemaakt van een serie routines in de Basic-ROM. Deze routines, die samen de naam MathPack gekregen hebben, zijn zowel in MSX1 en MSX2 aanwezig. Ze kunnen alle soorten getallen bewerken. Integers, getallen van enkele en dubbele precisie kunnen worden geconverteerd, verplaatst en er kunnen rekenkundige bewerkingen op worden losgelaten. Een aanroep van de MathPack is geen simpele inter-slot call. Ten gevolge van een ontwerpfout van het BIOS MathPack moet pagina 1 van het Basic-ROM ook ingeschakeld zijn. Tevens moet de fout-afhandeling worden omgebogen zodat niet naar de BASIC interpreter wordt gesprongen in geval van een fout.
In de MATH-library bevinden zich nog een aantal 'bugs':
De routine voor het aanroepen van een MathPack-functie is vrijwel identiek aan de CALBAS-routine, zoals gedefinieerd in de MSXBIOS library. Het is misschien mogelijk om beide routines te combineren.
Een snellere versie van de MATH-library kan worden gegenereerd door het label 'FAST' te definiëren (en de library opnieuw te compileren). Het programma moet dan wel zelf 'MATHINI' en 'MATHEND' aanroepen vòòr en ná alles.
Tabel 9: Functies in Math Library
Name |
Declaration |
SourceFile |
HeaderFile |
Description Dutch |
atosl |
SLONG *atosl(v, s) |
mathmac.mac |
math.h |
Zet een ASCII string om naar een 'long' waarde. |
atoxd |
STATUS atoxd(ans, s) |
mathmac.mac |
math.h |
Zet de ASCII string 's' om in een 'xdouble' waarde. |
itosl |
SLONG *itosl(ans, p1) |
mathmac.mac |
math.h |
Zet een 'integer' waarde om in een 'long' waarde. |
itoxd |
STATUS itoxd(ans, i) |
mathmac.mac |
math.h |
Zet de 'integer' waarde om in een 'xdouble' waarde. |
math2 |
STATUS math2(add, ?, ?, ans, p1, p2) |
mathmac.mac |
math.h |
*p1 -> dac, *p2 -> arg |
mathu |
|
mathmac.mac |
math.h |
Roept de routine 'add' in het Math-pack aan. |
slabs |
SLONG *slabs(ans, p1) |
mathmac.mac |
math.h |
*ans = |*p1|; |
sladd |
SLONG *sladd(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 + *p2; |
sland |
SLONG *sland(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 & *p2; |
slcmp |
int slcmp(p1, p2) |
mathmac.mac |
math.h |
(*p1 - *p2) |
slcpy |
SLONG *slcpy(ans, p1) |
mathmac.mac |
math.h |
|
sldiv |
SLONG *sldiv(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 / *p2 (signed) |
slmod |
SLONG *slmod(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 % *p2 (signed) |
slmul |
SLONG *slmul(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 * *p2; |
slneg |
SLONG *slneg(ans, p1) |
mathmac.mac |
math.h |
*ans = -*p1 |
slnot |
SLONG *slnot(ans, p1) |
mathmac.mac |
math.h |
*ans = ~*p1; |
slor |
SLONG *slor(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 | *p2; |
slrl |
SLONG *slrl(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 << k; |
slrlc |
SLONG *slrlc(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 << k; |
slrr |
SLONG *slrr(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 >> k; |
slrrc |
SLONG *slrrc(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 >> k; |
slsgn |
int slsgn(p1) |
mathmac.mac |
math.h |
|
slsla |
SLONG *slsla(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 << k; |
slsll |
SLONG *slsll(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 << k; |
slsra |
SLONG *slsra(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 >> k; |
slsrl |
SLONG *slsrl(ans, p1, k) |
mathmac.mac |
math.h |
*ans = *p1 >> k; |
slsub |
SLONG *slsub(ans, p1, p2) |
mathmac.mac |
math.h |
|
sltoa |
char *sltoa(str, sl, radix) |
mathmac.mac |
math.h |
Zet een 'long' waarde om in een ASCII string. |
sltoxd |
STATUS sltoxd(ans, p1) |
mathmac.mac |
math.h |
Converteert de 'signed long' waarde naar een 'xdouble' waarde. Zie ook 'ultoxd()'. |
slxor |
SLONG *slxor(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 ^ *p2; |
uitosl |
SLONG *uitosl(ans, p1) |
mathmac.mac |
math.h |
Zet een 'unsigned int' waarde om in een 'long' waarde. |
uldiv |
SLONG *uldiv(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 / *p2 (unsigned) |
ulmod |
SLONG *ulmod(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 % *p2 |
ultoxd |
STATUS ultoxd(ans, p1) |
mathmac.mac |
math.h |
Converteert de 'unsigned long' waarde naar een 'xdouble' waarde. Zie ook 'sltoxd()'. |
xdadd |
STATUS xdadd(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 + *p2; in xdouble type |
xdatn |
STATUS xdatn(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)atn((*p1)); in xdouble type |
xdceil |
STATUS xdceil(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)ceil((*p1)); in xdouble type |
xdcmp |
int xdcmp(p1, p2) |
mathmac.mac |
math.h |
Keert terug met '1' indien (*p1 > *p2), '0' indien (*p1 == *p2) of '-1' indien (*p1 < *p2) |
xdcos |
STATUS xdcos(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)cos((*p1)); in xdouble type |
xdcpy |
XDOUBLE *xdcpy(ans, p1) |
mathmac.mac |
math.h |
Copieert de waarde aangegeven door 'p1' naar 'ans'. |
xddiv |
STATUS xddiv(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 * *p2; in xdouble type |
xdexp |
STATUS xdexp(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)exp((*p1)); in xdouble type |
xdfabs |
STATUS xdfabs(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)fabs((*p1)); in xdouble type |
xdfix |
STATUS xdfix(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)fix((*p1)); in xdouble type |
xdfloor |
STATUS xdfloor(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)floor((*p1)); in xdouble type |
xdlog |
STATUS xdlog(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)log((*p1)); in xdouble type |
xdmul |
STATUS xdmul(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 * *p2; in xdouble type |
xdneg |
STATUS xdneg(ans, p1) |
mathmac.mac |
math.h |
*ans = -(*p1); in xdouble type |
xdnrm |
STATUS xdnrm(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)(*p1); in xdouble type |
xdpow |
STATUS xdpow(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = pow(*p1, *p2); in xdouble type |
xdrnd |
STATUS xdrnd(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)rnd((*p1)); in xdouble type |
xdsgn |
int xdsgn(p1) |
mathmac.mac |
math.h |
Keert terug met '1' indien (*p1 > 0), '0' indien (*p1 == 0) of '-1' indien (*p < 0). |
xdsin |
STATUS xdsin(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)sin((*p1)); in xdouble type |
xdsqrt |
STATUS xdsqrt(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)sqrt((*p1)); in xdouble type |
xdsub |
STATUS xdsub(ans, p1, p2) |
mathmac.mac |
math.h |
*ans = *p1 - *p2; in xdouble type |
xdtan |
STATUS xdtan(ans, p1) |
mathmac.mac |
math.h |
*ans = (XDOUBLE)tan((*p1)); in xdouble type |
xdtoa |
char *xdtoa(s, p1, digits) |
mathmac.mac |
math.h |
Zet een 'xdouble' waarde gedefinieerd door 'p1' om in een ASCII string. De variabele 'digits' geeft aan in hoeveel decimalen achter de komma de string moet worden uitgevoerd. |
xdtoi |
STATUS xdtoi(ans, p1) |
mathmac.mac |
math.h |
Zet de 'xdouble' waarde om in een 'integer' waarde. |
xdtosl |
STATUS xdtosl(ans, p1) |
mathmac.mac |
math.h |
Zet de 'integer' waarde om in een 'signed long' waarde. |
Tabel 10: Functies in Curses Library
Name |
Declaration |
SourceFile |
HeaderFile |
Description Dutch |
addch |
STATUS addch(ch) |
cursesc.c |
curses.h |
|
addstr |
STATUS addstr(str) |
cursesc.c |
curses.h |
|
box |
STATUS box(win, vert, hor) |
cursesc.c |
curses.h |
|
cgetch |
char cgetch() |
curses2.c |
curses.h |
|
clear |
STATUS clear() |
curses2.c |
curses.h |
|
clearok |
clearok(win, bf) |
curses.h |
curses.h |
|
clrtobot |
VOID clrtobot() |
cursesc.c |
curses.h |
|
clrtoeol |
VOID clrtoeol() |
cursesc.c |
curses.h |
|
delch |
STATUS delch() |
cursesc.c |
curses.h |
|
deleteln |
VOID deleteln() |
cursesc.c |
curses.h |
|
delwin |
VOID delwin(win) |
cursesc.c |
curses.h |
|
echo |
VOID echo() |
curses.h |
curses.h |
|
endwin |
VOID endwin() |
cursesc.c |
curses.h |
|
erase |
VOID erase() |
cursesc.c |
curses.h |
|
getstr |
STATUS getstr(str) |
curses2.c |
curses.h |
|
getyx |
getyx(win, y, x) |
curses.h |
curses.h |
|
inch |
char inch() |
curses2.c |
curses.h |
|
initscr |
WINDOW *initscr() |
cursesc.c |
curses.h |
|
insertln |
STATUS insch(ch) |
cursesc.c |
curses.h |
|
insertln |
VOID insertln() |
cursesc.c |
curses.h |
|
memmove |
VOID memmove(d, s, n) |
cursesc.c |
curses.h |
|
move |
STATUS move(y, x) |
cursesc.c |
curses.h |
|
mvaddch |
STATUS mvaddch(y, x, ch) |
curses2.c |
curses.h |
|
mvaddstr |
STATUS mvaddstr(y, x, str) |
curses2.c |
curses.h |
|
mvdelch |
STATUS mvdelch(y, x) |
curses2.c |
curses.h |
|
mvgetch |
char mvgetch(y, x) |
curses2.c |
curses.h |
|
mvgetstr |
STATUS mvgetstr(y, x, str) |
curses2.c |
curses.h |
|
mvinch |
char mvinch(y, x) |
curses2.c |
curses.h |
|
mvinsch |
STATUS mvinsch(y, x, c) |
curses2.c |
curses.h |
|
mvprintw |
STATUS mvprintw(nargs, y, x, format) |
curses2.c |
curses.h |
|
mvwadch |
STATUS mvwadch(win, y, x, ch) |
curses2.c |
curses.h |
|
mvwadstr |
STATUS mvwadstr(win, y, x, str) |
curses2.c |
curses.h |
|
mvwdelch |
STATUS mvwdelch(win, y, x) |
curses2.c |
curses.h |
|
mvwgtch |
char mvwgtch(win, y, x) |
curses2.c |
curses.h |
|
mvwgtstr |
STATUS mvwgtstr(win, y, x, str) |
curses2.c |
curses.h |
|
mvwin |
STATUS mvwin(win, y, x) |
cursesc.c |
curses.h |
|
mvwinch |
char mvwinch(win, y, x) |
curses2.c |
curses.h |
|
mvwinsch |
STATUS mvwinsch(win, y, x, c) |
curses2.c |
curses.h |
|
mvwprintw |
STATUS mvwprintw(nargs, win, y, x, format) |
curses2.c |
curses.h |
|
newwin |
WINDOW *newwin(lines, cols, begin_y, begin_x) |
cursesc.c |
curses.h |
|
noecho |
VOID noecho() |
curses.h |
curses.h |
|
offcur |
VOID offcur() |
cursesc.c |
curses.h |
|
oncur |
VOID oncur() |
cursesc.c |
curses.h |
|
overwrite |
VOID overwrite(win1, win2) |
cursesc.c |
curses.h |
|
printw |
STATUS printw(nargs, format) |
curses2.c |
curses.h |
|
raw |
VOID raw() |
curses.h |
curses.h |
|
refresh |
STATUS refresh() |
cursesc.c |
curses.h |
|
scroll |
STATUS scroll(win) |
cursesc.c |
curses.h |
|
scrollok |
scrollok(win, bf) |
curses.h |
curses.h |
|
subwin |
WINDOW *subwin(win, lines, cols, begin_y, begin_x) |
cursesc.c |
curses.h |
|
touchwin |
STATUS touchwin(win) |
cursesc.c |
curses.h |
|
waddch |
STATUS waddch(win, ch) |
cursesc.c |
curses.h |
|
waddstr |
STATUS waddstr(win, str) |
cursesc.c |
curses.h |
|
wclear |
STATUS wclear(win) |
curses2.c |
curses.h |
|
wclrbot |
VOID wclrbot(win) |
cursesc.c |
curses.h |
|
wclreol |
VOID wclreol(win) |
cursesc.c |
curses.h |
|
wclrtobot |
VOID wclrtobot(win) |
curses.h |
curses.h |
|
wclrtoeol |
VOID wclrtoeol(win) |
curses.h |
curses.h |
|
wdelch |
STATUS wdelch(win) |
cursesc.c |
curses.h |
|
wdeleteln |
VOID wdeleteln(win) |
cursesc.c |
curses.h |
|
werase |
VOID werase(win) |
cursesc.c |
curses.h |
|
wgetch |
char wgetch(win) |
curses2.c |
curses.h |
|
wgetstr |
STATUS wgetstr(win, str) |
curses2.c |
curses.h |
|
winch |
char winch(win) |
curses2.c |
curses.h |
|
winsch |
STATUS winsch(win, ch) |
cursesc.c |
curses.h |
|
winsertln |
VOID winsertln(win) |
cursesc.c |
curses.h |
|
wmove |
STATUS wmove(win, y, x) |
cursesc.c |
curses.h |
|
wprintw |
STATUS wprintw(nargs, win, format) |
curses2.c |
curses.h |
|
wrefresh |
STATUS wrefresh(win) |
cursesc.c |
curses.h |
De verschillende programma's die een C-source behandelen kennen allemaal hun eigen behandeling van identifiers, zoals is weergegeven in het volgende overzicht:
Tabel 11: Behandeling van identifiers
----------------------------------------------------------- significante onderscheid hoofd-/ labellengte kleine letters ----------------------------------------------------------- Compiler (CF & CG) 16 JA Assembler (M80) 6 NEE Linker (L80) 6 NEE -----------------------------------------------------------
De MSX-C Compiler (CF & CG) maakt onderscheid tussen hoofd- en kleine letters en heeft een significante labellente van 16 tekens. De assembler (M80) en de linker (L80) daarentegen maken geen onderscheid tussen hoofdletters en kleine letters en hebben een significante labellengte van maar 6 tekens. Identifiers van variabelen en functies worden door de MSX-C Compiler doorgespeeld naar M80 en L80, zodat deze identifiers beperkt zijn tot 6 significante tekens, en er geen onderscheid tussen onder- en bovenkast wordt gemaakt. Identifiers van define labels en typedefs worden daarentegen alleen door de compiler gebruikt, en hebben dus wel een significante labellengte van 16 tekens waarbij wel onderscheid wordt gemaakt tussen hoofdletters en kleine letters.
Voorbeeld
De volgende functiedeclaraties zijn voor M80 identiek en zullen dus resulteren in een foutmelding van M80:
De compiler ziet WEL verschil tussen de volgende declaraties:
Parameteroverdracht tussen de verschillende functies kan in MSX-C geschieden via de stack en/of de Z80-registers. Door de compiler in recursive' mode te zetten, geschiedt de parameteroverdracht in zijn geheel via de stack. Hiermee is het mogelijk om functies recursief aan te roepen. In de 'non-recursive' mode worden de eerste 3 parameters via de Z80 registers overgedragen.
Met behulp van de preprocessor commando's:
#pragma rec
#pragma nonrec
kan de compiler worden geschakeld in respectievelijk 'recursive' en 'nonrecursive' mode. Het is ook mogelijk om één functie te declareren als 'recursive' door dit sleutelwoord vòòr de functie te zetten:
recursive VOID functie()
Standaard worden functies door de compiler gecompileerd in de 'non-recursive' mode. De onderstaande tabel geeft een overzicht van de parameteroverdracht in de verschillende modes:
---------------------------------------------------------- non-recursive recursive -------------------------------------------- lengte parameter ---------------------------------- 1 byte (char) 2 bytes (integer) ---------------------------------------------------------- 1 A HL (SP-1) 2 E DE (SP-2) 3 C BC (SP-3) 4 (SP-1) (SP-4) 5 (SP-2) (SP-5) : : : n (SP-(n-3)) (SP-n) ---------------------------------------------------------- {SP = Stack Pointer}
In recursive' mode wordt, afhankelijk van het feit of een parameter is gedeclareerd als char of integer, de parameter overgedragen via respectievelijk het A of HL register. Voor de 2e en de 3e parameter worden respectievelijk het DE en BC register gebruikt, waarbij de high-byte (D respectievelijk B) een ongedefinieerde waarde heeft bij overdracht van een char. De 4e en alle volgende parameters worden overgedragen via de stack, waarbij een als char gedeclareerde waarde 2 bytes in beslag neemt.
Het laatste adres op de stack is het terugkeeradres waarnaar terug wordt gesprongen bij het einde van de routine. Indien een getal zonder declaratie wordt overgedragen - dus zonder aan te geven of het een char of integer is - wordt door de compiler aangenomen dat het een integer waarde is.
Bijvoorbeeld: Stel dat we de functie EXAMPL aanroepen met de volgende parameters:
EXAMPL (char1, int1, char2, char3, int2, int3);
Dan kan EXAMPL de parameters vinden op de volgende lokaties:
char1: A int1: DE char2: C char3: (SP-1) int2: (SP-2) int3: (SP-3)
Met de functieaanroep
EXAMPL(12);
wordt het getal 12 overgedragen via register HL. Het getal 12 kan worden overgedragen via register A door gebruik te maken van type-casting:
EXAMPL((char) 12);
Bij een typisch MSX-C programma is het 64K geheugen van de MSX als volgt ingedeeld:
-------------------------------------------------------- 0FFFFh ----------------------------- hooks 0FD99h ----------------------------- working area 0F380h ----------------------------- (00006h)----------------------------- Top of TPA stack ^ : | (_torelance) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _v_ heap ----------------------------- (_endx) Transient Program 0100h ----------------------------- Start of TPA Transient Program Parameter Areas 0000h ----------------------------- -------------------------------------------------------- {TPA = Transient Program Area}
Het systeemdeel van het RAM-geheugen vanaf adres 0FD9Ah tot en met 0FFCAh is gereserveerd voor de hook-adressen. Het geheugen tussen adres 0F380h en 0FD99h wordt het werkgebied genoemd en bevat de variabelen die door het BIOS en de BASIC-interpreter worden gebruikt. Tussen het werkgebied en het TPA (Transient Program Area) in, bevindt zich geheugenruimte die kan worden gebruikt door externe apparatuur of andere programma's. char *alloc(size_t nbytes) [MALLOC.C] VOID free(char *ap) [MALLOC.C] VOID rsvstk(size_t n) [MALLOC.C] char *sbrk(size_t n) [MALLOC.C] The C programming Language CP/M voor gevorderden MSX ROM BIOS handboek
MSX-DOS 2.20 Programme Reference Manual 1; Function Codes Specifications, MSX-DOS 2.20 Programme Reference Manual 2; Transient Program Interface Specifications, HiSoft C Manual MSX Math-Pack (deel 1) Ken uw computer: de V9938 videochip De MSX-2 videoprocessor
In elk MSX-C programma wordt de stack pointer gelijk gemaakt aan de top van het TPA door adres 0006h uit te lezen. De sourcecode van deze uitleesroutine - die is gecompileerd in CK.REL en bij ieder MSX-C programma wordt meegelinkt - is te vinden in de sourcefile CK.MAC.
Het geheugen tussen de stack en adres 0100h is beschikbaar voor de uiteindelijke programmacode. De bovengrens van de programmacode wordt weergegeven door de variabele _endx. De variabele _torelance definieert de te reserveren groeiruimte voor de stack. Het vrije stuk geheugen tussen de ondergrens van de stack en de programmacode wordt wel heap (hoop) genoemd. Voor het beheer van de heap zijn in MSX-C een viertal functies gedefinieerd, te weten: alloc(), free(), rsvstk() en sbrk():
Keert terug met een pointer naar nbytes vrije ruimte in de heap, of NULL indien het verzoek niet kan worden ingewilligd. De toegewezen vrije ruimte is niet geïnitialiseerd.
Wanneer het via alloc verkregen stuk geheugen niet meer wordt gebruikt door het programma, kan het worden 'teruggegeven' aan alloc door een free() aanroep, met als argument de via alloc verkregen pointer.
Omdat programmadelen ook beslag kunnen leggen op geheugenruimte zonder hiervoor alloc aan te roepen (bijvoorbeeld via 'n sbrk aanroep), is het heel goed mogelijk dat het door alloc beheerde geheugen niet continu is.
Dit is de reden dat alloc de vrije ruimte beheert via een lijst van vrije blokken. Ieder blok bevat de grootte, een pointer naar het volgende blok en de vrije ruimte zelf. De blokken worden bewaard in volgorde van oplopend geheugenadres en het laatste (hoogste) blok wijst naar het eerste.
Als nu om een stukje geheugen wordt gevraagd, wordt de lijst doorlopen totdat een stukje geheugen van voldoende omvang is gevonden. Als er geen geheugenstukje van voldoende omvang beschikbaar is, wordt via sbrk een nieuw stuk geheugen gevraagd.
Geeft het geheugen vrij waarnaar door pointer ap wordt verwezen. ap moet zijn verkregen door een alloc aanroep.
Wijzigt de te reserveren ruimte (_torelance) voor de stack. De default waarde voor _torelance is 1000.
Keert terug met een pointer naar n bytes vrij te gebruiken geheugen, of -1 indien de heap niet groot genoeg is. Als de heap wel groot genoeg is, 'kaapt' sbrk het eerste stuk geheugen net boven de programmacode en verhoogt de variabele _endx met n.
Brian W. Kernighan/ Dennis M. Ritchie
Prentice Hall Software Series, ISBN 0-13-110362-8
A. Clarke/ J.M. Eaton/ D. Powys-Lybbe
Academic Service, ISBN 90 6233 166 1
H.S.H. Computervertrieb GmbH, 1989
H.S.H. Computervertrieb GmbH, 1989
H.S.H. Computervertrieb GmbH, 1988
MSX Computer Magazine 44
Emil Hensen, MSX Club Magazine 25, 26 en 27
Nico van Rooijen, HCC Nieuwbrief 113 en 114