Mercurial > hg > Members > kono > nitros9-code
diff 3rdparty/packages/cc/sources/cstart.a @ 867:0198655f2552
Added sources
author | boisy |
---|---|
date | Thu, 16 Jan 2003 19:54:21 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/3rdparty/packages/cc/sources/cstart.a Thu Jan 16 19:54:21 2003 +0000 @@ -0,0 +1,272 @@ + ifp1 + use ..../defs/os9defs.a + endc + +pushzero macro + clr ,-s clear a byte on stack + endm + +nfiles equ 2 stdin and stdout at least +Typ equ 1 +Edit equ 1 +Stk equ nfiles*256+128+256 stdin,stdout,stderr and fudge + psect cstart_a,$11,$81,Edit,Stk,_cstart + +cr equ $0d +sp equ $20 +comma equ ', +dquote equ '" +squote equ '' + +MAXARGS equ 30 allow for 30 arguments + +* +* rob the first dp byte so nothing gets assigned +* here. No valid pointer can point to byte zero. +* + vsect dp +__$$ fcb 0 + endsect + + vsect +argv rmb 2*MAXARGS pointers to args +argc rmb 2 argument counter +_sttop rmb 2 stack top + endsect + +* the following are globally known + vsect +memend: rmb 2 +_flacc: rmb 8 floating point & longs accumulator +_mtop: rmb 2 current non-stack memory top +_stbot: rmb 2 current stack bottom limit +errno: rmb 2 global error holder + endsect + +* +* move bytes (Y=From addr, U=To addr, X=Count) +* +movbytes + lda ,y+ get a byte + sta ,u+ put a byte + leax -1,x dec the count + bne movbytes and round again + rts + +_cstart: + pshs y save the top of mem + pshs u save the data beginning address + + clra setup to clear + clrb 256 bytes +csta05 sta ,u+ clear dp bytes + decb + bne csta05 + +csta10 ldx 0,s get the beginning of data address + leau 0,x (tfr x,u) + leax end,x get the end of bss address + pshs x save it + leay etext,pcr point to dp-data count word + + ldx ,y++ get count of dp-data to be moved + beq csta15 bra if none + bsr movbytes move dp data into position + + ldu 2,s get beginning address again +csta15 leau dpsiz,u point to where non-dp should start + ldx ,y++ get count of non-dp data to be moved + beq clrbss + bsr movbytes move non-dp data into position + +* clear the bss area - starts where +* the transferred data finished + clra +clrbss cmpu 0,s reached the end? + beq reldt bra if so + sta ,u+ clear it + bra clrbss + +* now relocate the data-text references +reldt ldu 2,s restore to data bottom + ldd ,y++ get dat-text ref. count + beq reldd + leax btext,pcr point to text + lbsr patch patch them + +* and the data-data refs. +reldd ldd ,y++ get the count of data refs. + beq restack bra if none + leax 0,u u was already pointing there + lbsr patch + +restack leas 4,s reset stack + puls x restore 'memend' + stx memend,u + +* process the params +* the stack pointer is back where it started so is +* pointing at the params +* +* the objective is to insert null chars at the end of each argument +* and fill in the argv vector with pointers to them + +* first store the program name address +* (an extra name inserted here for just this purpose +* - undocumented as yet) + sty argv,u + + ldd #1 at least one arg + std argc,u + leay argv+2,u point y at second slot + leax 0,s point x at params + lda ,x+ initialize + +aloop ldb argc+1,u + cmpb #MAXARGS-1 about to overflow? + beq final +aloop10 cmpa #cr is it EOL? + beq final yes - reached the end of the list + + cmpa #sp is it a space? + beq aloop20 yes - try another + cmpa #comma is it a comma? + bne aloop30 no - a word has started +aloop20 lda ,x+ yes - bump + bra aloop10 and round again + +aloop30 cmpa #dquote quoted string? + beq aloop40 yes + cmpa #squote the other one? + bne aloop60 no - ordinary + +aloop40 stx ,y++ save address in vector + inc argc+1,u bump the arg count + pshs a save delimiter + +qloop lda ,x+ get another + cmpa #cr eol? + beq aloop50 + cmpa 0,s delimiter? + bne qloop + +aloop50 puls b clean stack + clr -1,x + cmpa #cr + beq final + lda ,x+ + bra aloop + +aloop60 leax -1,x point at first char + stx ,y++ put address in vector + leax 1,x bump it back + inc argc+1,u bump the arg count + +* at least one non-space char has been seen +aloop70 cmpa #cr have + beq loopend we + cmpa #sp reached + beq loopend the end? + cmpa #comma comma? + beq loopend + lda ,x+ no - look further + bra aloop70 + +loopend clr -1,x yes - put in the null byte + bra aloop and look for the next word + +* now put the pointers on the stack +final leax argv,u get the address of the arg vector + pshs x goes on the stack first + ldd argc,u get the arg count + pshs d stack it + leay 0,u C progs. assume data & bss offset from y + + bsr _fixtop set various variables + + lbsr main call the program + + pushzero put a zero + pushzero on the stack + lbsr exit and a dummy 'return address' + +* no return here +_fixtop leax end,y get the initial memory end address + stx _mtop,y it's the current memory top + sts _sttop,y this is really two bytes short! + sts _stbot,y + ldd #-126 give ourselves some breathing space + +* on entry here, d holds the negative of a stack reservation request +_stkchec: +_stkcheck: + leax d,s calculate the requested size + cmpx _stbot,y is it lower than already reserved? + bhs stk10 no - return + cmpx _mtop,y yes - is it lower than possible? + blo fsterr yes - can't cope + stx _stbot,y no - reserve it +stk10 rts and return + +fixserr fcc /**** STACK OVERFLOW ****/ + fcb 13 + +fsterr leax <fixserr,pcr address of error string + ldb #E$MEMFUL MEMORY FULL error number + +erexit pshs b stack the error number + lda #2 standard error output + ldy #100 more than necessary + os9 I$WRITLN write it + pushzero clear MSB of status + lbsr _exit and out +* no return here + +* stacksize() +* returns the extent of stack requested +* can be used by programmer for guidance +* in sizing memory at compile time +stacksiz: + ldd _sttop,y top of stack on entry + subd _stbot,y subtract current reserved limit + rts + +* freemem() +* returns the current size of the free memory area +freemem: + ldd _stbot,y + subd _mtop,y + rts + +* patch - adjust initialised data which refer to memory locations. +* entry: +* y -> list of offsets in the data area to be patched +* u -> base of data +* x -> base of either text or data area as appropriate +* d = count of offsets in the list +* +* exit: +* u - unchanged +* y - past the last entry in the list +* x and d mangled + +patch pshs x save the base + leax d,y half way up the list + leax d,x top of list + pshs x save it as place to stop + +* we do not come to this routine with +* a zero count (check!) so a test at the loop top +* is unnecessary +patch10 ldd ,y++ get the offset + leax d,u point to location + ldd 0,x get the relative reference + addd 2,s add in the base + std 0,x store the absolute reference + cmpy 0,s reached the top? + bne patch10 no - round again + + leas 4,s reset the stack + rts and return + + endsect