view 3rdparty/packages/cc/sources/cstart.a @ 1942:b41df77588b0

printer is now scbbp sio is now scbbt All references changed in various files
author boisy
date Sat, 26 Nov 2005 22:51:50 +0000
parents 0198655f2552
children
line wrap: on
line source

 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