Sunday, March 24, 2013

NCB85 3. Cross compiled Hello World

Používať moderné IDE na vývoj pre CP/M nie je žiadna prevratná myšlienka. Fakt ale je, že to skoro nikto nerobí. Snáď preto, že starí CP/M harcovníci majú odpor k Windows, alebo možno preto, že iba nepoznajú silu a výhody moderných IDE. Preto som sa do toho vrhol ja.

Každý C program začína metódou "main()". Lenže v CP/M sa programy spúšťajú od adresy 0x0100. Ako na to ? Písať k main niečo ako ORG 0x0100 by nebolo to pravé orechové. Robí sa to inač. Každý program v C má zavádzač. Nazýva sa C Run Time Start Off, skrátene CRTSO. Pre CP/M by mohol vyzerať takto nejako:
;   Run time start off for Small C.
;   cseg
    .module CRET
    .area CRET (REL,CON) ;program area CRTSO is RELOCATABLE
    .list (err, loc, bin, eqt, cyc, lin, src, lst, md)
    .nlist (pag)
    .globl crtsoend
    lxi h,0
    dad sp
    shld stksav
    lhld 6 ; pick up core top
    lxi d,-10 ; decrease by 10 for safety
    dad d
    sphl ; set stack pointer
    call main ; call main program
    lhld stksav ; restore stack pointer
    sphl
    ret ; go back to CCP
stksav: .ds 2
crtsoend:
    .end
Všimnime si volanie "call main". Áno to je ono. Tu nám zavádzač spúšťa našu main metódu. Tá bižutéria okolo, je už len presunutie zásobníka. Vlastnej tvorbe a fantázii sa medze nekladú. Musel som upraviť SmallC verziu pretože, neviem prečo ale bola zlá. Hneď na začiatku bolo SPHL. Nastavenie SP na hodnotu v HL. Ale to je asi blbosť. Veď CP/M nedáva v HL žiadnu hodnotu hovoriacu o zásobníku. Zase keby som nechal SP bez zmeny, tak by ukazoval niekam do CCP kde je priestor iba pre 8 úrovní. Preto som zvolil inú taktiku. Radšej si ho alokujem tam kde bolo CCP a miesta mám habadej.

C zdrojáky

SmallC nám všetky C zdrojáky preloží do ASM. Ďalší krok je spustiť assembler ktorý spracuje tieto vzniknuté ASM. Posledný krok je link. Linker nám musí zostaviť výsledný program, pozostávajúci z viacerých REL súborov. REL sú relokovateľné fragmenty. Je to výsledok volania assemblera. Linker ich zostaví do jedného celku, pričom na adrese 0x0100 bude ako prvý CRTSO. Ostatné fragmenty už môžu ísť v ľubovoľnom poradí za ním. Pri Hello World si vystačíme s tromi C súbormi.

/*
* File: main.c, march 2013
* hello world on CP/M
*/

/**
* main routine
* @return
*/
main() {
    print("Hello World!!");
}

/**
* prints zero terminated string
* @param str
* @return
*/
print(char *str) {
    while (*str) {
       putchar(*str++);
    }
}


Druhý súbor je z knižice SmallC. Je to chio8080.c
#define EOL 10
getchar() {
    return (bdos(1,1));
}

putchar (c) char c; {
    if (c == EOL) bdos(2,13);
    bdos(2,c);
    return c;
}


BDOS služba 1 je vstup jedného znaku z konzoly. BDOS služba 2 je výstup jedného znaku na konzolu. Posledný súbor je bdos.c ktorý už len zavolá CALL 5 volanie CP/M BDOS. Listing neuvádzam. Je to len CALL 5 a nejaké POP a PUSH.

COM file

Výstupom linkera je Intel HEX súbor. CP/M potrebuje spustiteľný COM file. Je možné nahrať na CP/M stroj HEX súbor a pomocou príkazu LOAD ho prekonvertovať na COM. Dá sa to ale aj priamo na Windows. Použijeme utilitu hex2bin, ktorá robí presne to isté. Naviac nám do build okna vypíše aj veľkosť výsledného COM.

Building project
scc8080 -t -a main.c
as8085 -l -o -s -p -g main.s
scc8080 -t -a bdos.c
as8085 -l -o -s -p -g bdos.s
scc8080 -t -a chio8080.c
as8085 -l -o -s -p -g chio8080.s
as8085 -l -o -s -p -g cret.asm
as8085 -l -o -s -p -g crun8080lib.asm
aslink -n -i -u -o -m -b CRET=0x0100 -b LIB8080=crtsoend+0x0100 -b SMALLC_GENERATED=crun8080_end+crtsoend+0x0100 hello cret.rel crun8080lib.rel main.rel bdos.rel chio8080.rel
sort -k1.8,1.9 -k1.4,1.7 hello.ihx > hello.hex
hex2bin -e com -c hello.hex
hex2bin v1.0.1, Copyright (C) 1999 Jacques Pelletier
Lowest address = 00000100
Highest address = 00000374
Build finished


Po nahratí na CP/M stroj a spustení COM súboru nám to naozaj vypíše Hello World!!
Niekomu by sa COM súbor zdal moc veľký. Je to spôsobené tým, že je tam prilinkovaná kompletná run-time knižnica crun8080lib. Táto obsahuje aj napríklad rutiny na násobenie, delenie, rotácie, switch príkazy a kopu ďalších, ktoré v Hello World nepoužívame.

No comments:

Post a Comment