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