; Run time start off for Small C.
.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 ; save the stack pointer
lhld 6 ; pick up core top
lxi d,-10 ; decrease by 10 for safety
dad d
sphl ; set stack pointer
lxi h,0x0080
push h ; line buffer is at 0080H
call Xarglist
lhld Xargc
push h
lxi h,Xargv
push h
call main ; call main program
jmp 0 ; warm boot, reload CCP
stksav: .ds 2
crtsoend:
.end
Musel som upraviť dodaný CRTSO k SmallC pretože nefungoval. Pridal som riadok s LXI H,0080 a PUSH H. Následne volaná C rutina Xarglist totižto očakáva vstupný parameter char pointer na buffer s obsahom príkazového riadku. Rozparsuje buffer podľa medzier a naplní Xargc a Xargv globálne premenné. Pôvodný stack ukazoval na priestor v CCP, kde bolo miesto na 8 úrovní. Túto hodnotu síce ukladáme, ale po ukončení sa aj tak nepoužije. Jednoduchšie je zavolať warm boot, ktorý reloadne CCP.
C program
/*
* File: main.c, march 2013
* command line arguments testing on CP/M
*/
/**
* main routine
* @return
*/
main(int argc, int argv[]) {
int i;
print("Argument test\r\n");
for (i=1; i < argc; i++) {
print("arg:");
putchar('0' + i);
print(", value:");
print(argv[i]);
print("\r\n");
}
}
print(char *str) {
while (*str) {
putchar(*str++);
}
}
V main metóde sa zmenila hlavička. Už máme dva parametre. Prvý je počet parametrov argc. Ale čo ten druhý ? Malo by tam byť napr. char *argv[]. Čiže pole pointerov na char. Žial SmallC umožňuje iba jednu úroveň indirekcie. Využíva sa tu trik, že pointer je rovnako veľký ako int. Takže to pole integerov je vlastne to isté ako pole pointerov. Toto je ďalšia oblasť, kde by sa mohlo SmallC vylepšiť.
Spustenie programu na CP/M
A0>cmd a b -t
Argument test
arg:1, value:A
arg:2, value:B
arg:3, value:-T
To vyzerá dobre :-)
Build
K main.c, bdos.c a chio8080.c pribudli ďalšie dva súbory: arglist.c a charclass.c.
Building projectVýsledný COM už narástol na 727 bytov hexadecimálne.
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
scc8080 -t -a arglist.c
as8085 -l -o -s -p -g arglist.s
scc8080 -t -a charclass.c
as8085 -l -o -s -p -g charclass.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 cmd cret.rel crun8080lib.rel main.rel bdos.rel chio8080.rel arglist.rel charclass.rel
sort -k1.8,1.9 -k1.4,1.7 cmd.ihx > cmd.hex
hex2bin -e com -c cmd.hex
hex2bin v1.0.1, Copyright (C) 1999 Jacques Pelletier
Lowest address = 00000100
Highest address = 00000827
Build finished
Roman, keď si sa už rozhodol robiť návrat z programu priamo skokom na teplý štart (čo je samozrejme korektné a veľmi bežné), tak môžeš zo začiatku CRTSO vyhodiť odpamätávanie adresy zásobníka a aj samotnú premennú stksav.
ReplyDeleteInak, samozrejme, veľmi pekne postupuješ vo svojom snažení :-)
Samozrejme. stksav som tam nechal viac menej len z didaktických dôvodov :-)
ReplyDelete