home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
compiler
/
szadb21b
/
source
/
src
/
start.s
< prev
next >
Wrap
Text File
|
1991-07-08
|
11KB
|
412 lines
*************************************************************************
* *
* DSTART.S Startup module for C programs using dLibs *
* modified for szadb *
*************************************************************************
*
* Use this module when compiling adb without on-online help
* Sozobon preprocessor unfortunately does not take .s files
*
*
* More modifications to make it TT compatible
* this module now computes screen parameters and reserves screen
* buffers in an area between program text and __break.
*
*
* entry points
*
.globl _ossp
.globl __base * basepage pointer
.globl __start * startup entry point
.globl _etext * end of text segment
.globl _edata * end of data segment
.globl _end * end of BSS segment (end of program)
.globl __break * location of stack/heap break
.globl __exit * terminate immediately with exit code
.globl __argc * number of arguments
.globl __argv * argument list pointer
.globl __envp * environment string pointer
.globl _errno * system error number
.globl _gemdos * trap #1 (gemdos) hook
.globl _bios * trap #13 (bios) hook
.globl _xbios * trap #14 (xbios) hook
.globl _bdos * trap #2 (bdos) hook
*
* external references
*
.globl __STKSIZ * Stack size value from C (unsigned long)
.globl __main * Initial entry point for C program
.globl _main * C program main() function
.globl _w * structure describing screen parameters
.globl _screen * work screen buffer
.globl _linbuf * current line image for transcript writing
.globl _svline * saved line to protect from help()
.globl _linsize * so many long words + 6 bytes in _linbuf
*
* useful constants
*
MINSTK equ 1024 * Minimum 1K stack size
MARGIN equ 512 * Minimum memory to return to OS
*
* GEMDOS functions
*
Cconws equ $09 * Console write string
Pterm equ $4C * Process terminate (with exit code)
Mshrink equ $4A * Shrink program space
Getrez equ $04 * Find current resolution
*
* basepage offsets
*
p_hitpa equ $04 * top of TPA
p_tbase equ $08 * base of text
p_tlen equ $0C * length of text
p_dbase equ $10 * base of data
p_dlen equ $14 * length of data
p_bbase equ $18 * base of BSS
p_blen equ $1C * length of BSS
p_env equ $2C * environment string
p_cmdlin equ $80 * command line image
*
* STARTUP ROUTINE (must be first object in link)
*
.text
__start:
*
* save initial stack and basepage pointers
*
move.l sp,a5 * a5 = initial stack pointer
move.l 4(sp),a4 * a4 = basepage address
move.l a4,__base
move.l p_tbase(a4),d3
add.l p_tlen(a4),d3
move.l d3,_etext * end of text segment
move.l p_dbase(a4),d3
add.l p_dlen(a4),d3
move.l d3,_edata * end of data segment
move.l p_bbase(a4),d3
add.l p_blen(a4),d3
move.l p_env(a4),__envp * save environment pointer
move.l a4,_end * save basepage address for a moment
*
* compute work screen location, its parameters and reserve memory for it
*
move.l #255,d0
add.l d0,d3 * here a space for our work screen
not.l d0
and.l d0,d3 * align it on 0x100 boundary
move.l d3,_screen * set work screen start
*
* This code fills fields in _w structure from a file window.c
* and finds how much memory has to be reserved
* All changes in window structure have to be reflected here!
*
move.w #Getrez,-(sp)
jsr _xbios
move.w d0,_w+6 * and store it in w.res
*
* get all other info from line-A stuff
*
.dc.w $0a000
lea _w,a2
move.l a1,20(a2) * a pointer to pointers to fonts
moveq #0,d0
move.w d0,(a2)+ * clear curc
move.l d0,(a2)+ * clear curl
move.w -44(a0),d0 * number of columns = V_CEL_MX
addq #1,d0
move.w (a2)+,d3 * grab resolution
cmp.w #2,d3 * is this still ST resolution?
bgt sfind * jump if no
moveq #80,d1
cmp.w d1,d0 * no more than 80 columns?
ble sfind * jump in this case
*
* it looks like that we are running on Moniterm
* szadb will work only with a standard monitor hooked on a side
* so stick canned values into _w structure;
*
subq #1,d3 * test resolution
bge cols
lsr.w #1,d1 * only 40 columns for low
cols:
move.w d1,(a2)+
move.w #25,(a2)+ * always 25 rows
moveq #16,d1
moveq #80,d2
subq #1,d3 * medium or low res?
beq fsize * jump if not
lsr.w #1,d1 * fontsz only 8
lsl.w #1,d2 * but fsz 160
fsize:
move.w d1,(a2)+ * store fontsz
addq #2,a2 * skip csz
move.w #1280,(a2)+ * lsz is fixed here
move.w d2,(a2) * fill fsz
move.l #7999,d0 * this+1 = screen size in long words
bra blanksc
*
* no monitor trickery here - try to find out real values for screen
* parameters
*
sfind:
move.w d0,(a2)+ * d0 -> cols
move.w -42(a0),d0 * number of rows = V_CEL_MY
addq #1,d0
move.w d0,(a2)+
move.w -46(a0),d1
move.w d1,(a2)+ * fontsz
addq #2,a2 * skip csz
move.w -40(a0),d0 * width of line in bytes
move.w d0,(a2)+ * lsz - upper half of d0 already clear
divu d1,d0
move.w d0,(a2) * fsz
move.w (a0),d0 * number of planes
mulu -4(a0),d0 * and multiply by max_y
mulu -12(a0),d0 * and by max_x - total size in pixels
lsr.l #5,d0 * total size of screen in long words
*
* blank out screen area
*
blanksc:
move.l _screen,a0
move.l d0,d1
swap d1
moveq #0,d3
clean: * overshot by 1 in a case
* of screen size not divisible by 32
move.l d3,(a0)+
dbra d0,clean
dbra d1,clean
move.l a0,_linbuf * buffer for a current line characters
move.w -10(a2),d0 * screen width
subq #1,d0
lsr.w #2,d0 * decremented count in long words
move.w d0,_linsize * for use by dbra in _cleanlb
lsl.w #2,d0 * this number is even
addq.w #6,d0 * number of columns + '\r\n'
add.w d0,a0 * _linbuf ends here
move.l a0,_svline * this buffer used only when help
* is active
add.w d0,a0 * same size as for linbuf
*
* reserve space for a work screen between end of the program
* and a space for stack - calculate initial __break value
newbrk:
move.l a0,__break
move.l _end,a4 * restore pointer to basepage
move.l a0,_end * our end of program (with screen)
*
* call C function to get command line arguments
* this has to be done after screen setup, since _initargs moves __break
*
lea.l p_cmdlin(a4),a0 * get pointer to command line image
move.b (a0)+,d0
ext.w d0 * extract length
move.w d0,-(sp) * cmdlen
move.l a0,-(sp) * cmdline
jsr __initar * call _initargs(cmdline, cmdlen)
addq.l #6,sp
*
* calculate free space available to program
*
move.l __break,a3 * a3 = base of free space
move.l a3,d3
neg.l d3
add.l p_hitpa(a4),d3
sub.l #MARGIN,d3 * d3 = free space
*
* calculate new stack size (store in d2)
*
move.l #__STKSIZ,a2 * a2 = &_STKSIZ
move.l a2,d2 * if __STKSIZ is undefined
beq minimum * use MINSTK
move.l (a2),d2 * if __STKSIZ is positive
bpl setstk * use __STKSIZ
add.l d3,d2 * if __STKSIZ is negative
cmp.l #MINSTK,d2 * try (free space + __STKSIZ)
bge setstk * if < MINSTK
minimum:
move.l #MINSTK,d2 * use MINSTK
*
* check to see if there is enough room for requested stack
*
setstk:
cmp.l d3,d2
blt shrink * if (available < requested)
move.l #stkerr,-(sp)
move.w #Cconws,-(sp)
trap #1 * report a stack error
addq.l #6,sp
move.w #-39,-(sp)
move.w #Pterm,-(sp)
trap #1 * and return error -39 (ENSMEM)
*
* set up new stack pointer and Mshrink
*
shrink:
add.l a3,d2 * new stack = free base + stack size
move.l d2,sp
sub.l a4,d2 * keep space = new stack - __base
move.l d2,-(sp)
move.l a4,-(sp)
clr.w -(sp)
move.w #Mshrink,-(sp)
trap #1 * Mshrink(0, _base, keep);
add.l #12,sp
*
* Look at kernel sp
*
move.l #0,-(sp)
move.w #$20,-(sp)
trap #1
add.w #6,sp
move.l d0,_ossp
*
* call C entry point function _main()
*
jsr __main * if _main returns
move.w d0,4(sp) * insert return value and fall thru
*
* void _exit(code)
* int code;
*
* Terminate process with a return value of <code>
*
__exit:
tst.l (sp)+ * pop return PC off the stack
move.w (sp)+,d7 * exit code
move.l _ossp,d0 * old system stack pointer
move.l d0,-(sp)
move.w #$20,-(sp)
trap #1
add.w #6,sp
move.w d7,-(sp)
move.w #Pterm,-(sp)
trap #1 * and terminate.
*
* operating system trap hooks for C
*
*
* long gemdos(function, [parameter, ...])
* int function;
*
_gemdos:
move.l (sp)+,traprtn * save return address
trap #1 * do gemdos trap
bra chkstk
*
* long bios(function, [parameter, ...])
* int function;
*
_bios:
move.l (sp)+,traprtn * save return address
trap #13 * do bios trap
bra chkstk
*
* long xbios(function, [parameter, ...])
* int function;
*
_xbios:
move.l (sp)+,traprtn * save return address
trap #14 * do xbios trap
bra chkstk
*
* int bdos(function, parameter)
* int function;
* long parameter;
*
_bdos:
move.l (sp),traprtn * save return address
move.l a6,(sp) * save old frame pointer
move.l sp,a6 * set up frame pointer
tst.l -(a6) * (fake "link a6,#0")
move.w 8(a6),d0 * function code in D0.W
move.l 10(a6),d1 * parameter value in D1.L
trap #2 * do bdos trap
move.l (sp)+,a6 * restore old frame pointer
*
* check for stack overflow (done after all OS traps)
*
chkstk:
* cmp.l __break,sp
* bgt nosweat * if (_break > sp)
* move.l #stkovf,-(sp)
* move.w #Cconws,-(sp)
* trap #1 * report a stack overflow
* addq.l #6,sp
* move.w #-1,-(sp)
* move.w #Pterm,-(sp)
* trap #1 * and return error -1 (ERROR)
nosweat:
move.l traprtn,-(sp) * else, restore return address
rts * and do a normal return.
*
* this call to _main ensures that it the user's main() function will be
* linked, even if it is in a library.
*
jsr _main * NO PATH TO THIS STATEMENT
* THE FOLLOWING IS SELF MODIFYING CODE, DO NOT DISTURB
move.l #$644c6962,$7320(sp)
moveq.l #$31,d3
move.l $0(a2,d0),d7
*
* initialized data space
*
.data
.even
stkerr: * not enough memory for stack
.dc.b 'Not enough memory',$d,$a,0
stkovf: * impending stack overflow
.dc.b 'Stack overflow',$d,$a,0
_errno: * system error number
.dc.w 0
__argc: * number of command line args
.dc.w 0
__argv: * pointer to command line arg list
.dc.l 0
*
* uninitialized data space
*
.bss
.even
__base: * pointer to basepage
.ds.l 1
_etext: * pointer to end of text segment
.ds.l 1
_edata: * pointer to end of data segment
.ds.l 1
_end: * pointer to end of BSS (end of program)
.ds.l 1
__break: * pointer to stack/heap break
.ds.l 1
__envp: * pointer to environment string
.ds.l 1
traprtn: * storage for return PC in trap hooks
.ds.l 1
_ossp:
.ds.l 1
.end