home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / szadb21b / source / src / start.s < prev    next >
Text File  |  1991-07-08  |  11KB  |  412 lines

  1. *************************************************************************
  2. *                                    *
  3. *    DSTART.S    Startup module for C programs using dLibs    *
  4. *            modified for szadb                 *
  5. *************************************************************************
  6.  
  7. *
  8. *  Use this module when compiling adb without on-online help
  9. *  Sozobon preprocessor unfortunately does not take .s files
  10. *
  11.  
  12. *
  13. *  More modifications to make it TT compatible
  14. *  this module now computes screen parameters and reserves screen
  15. *  buffers in an area between program text and __break.
  16. *
  17.  
  18. *
  19. * entry points
  20. *
  21. .globl    _ossp
  22. .globl    __base            * basepage pointer
  23. .globl    __start            * startup entry point
  24. .globl    _etext            * end of text segment
  25. .globl    _edata            * end of data segment
  26. .globl    _end            * end of BSS segment (end of program)
  27. .globl    __break            * location of stack/heap break
  28. .globl    __exit            * terminate immediately with exit code
  29. .globl    __argc            * number of arguments
  30. .globl    __argv            * argument list pointer
  31. .globl    __envp            * environment string pointer
  32. .globl    _errno            * system error number
  33. .globl    _gemdos            * trap #1 (gemdos) hook
  34. .globl    _bios            * trap #13 (bios) hook
  35. .globl    _xbios            * trap #14 (xbios) hook
  36. .globl    _bdos            * trap #2 (bdos) hook
  37.  
  38. *
  39. * external references
  40. *
  41. .globl    __STKSIZ        * Stack size value from C (unsigned long)
  42. .globl    __main            * Initial entry point for C program
  43. .globl    _main            * C program main() function
  44. .globl  _w            * structure describing screen parameters
  45. .globl    _screen            * work screen buffer
  46. .globl    _linbuf            * current line image for transcript writing
  47. .globl    _svline            * saved line to protect from help()
  48. .globl  _linsize        * so many long words + 6 bytes in _linbuf
  49.  
  50. *
  51. * useful constants
  52. *
  53. MINSTK        equ    1024    * Minimum 1K stack size
  54. MARGIN        equ    512    * Minimum memory to return to OS
  55.  
  56. *
  57. * GEMDOS functions
  58. *
  59. Cconws        equ    $09    * Console write string
  60. Pterm        equ    $4C    * Process terminate (with exit code)
  61. Mshrink        equ    $4A    * Shrink program space
  62. Getrez        equ    $04    * Find current resolution
  63.  
  64. *
  65. * basepage offsets
  66. *
  67. p_hitpa        equ    $04    * top of TPA
  68. p_tbase        equ    $08    * base of text
  69. p_tlen        equ    $0C    * length of text
  70. p_dbase        equ    $10    * base of data
  71. p_dlen        equ    $14    * length of data
  72. p_bbase        equ    $18    * base of BSS
  73. p_blen        equ    $1C    * length of BSS
  74. p_env        equ    $2C    * environment string
  75. p_cmdlin    equ    $80    * command line image
  76.  
  77. *
  78. * STARTUP ROUTINE (must be first object in link)
  79. *
  80. .text
  81. __start:
  82. *
  83. * save initial stack and basepage pointers
  84. *
  85.     move.l    sp,a5            * a5 = initial stack pointer
  86.     move.l    4(sp),a4        * a4 = basepage address
  87.     move.l    a4,__base
  88.     move.l    p_tbase(a4),d3
  89.     add.l    p_tlen(a4),d3
  90.     move.l    d3,_etext        * end of text segment
  91.     move.l    p_dbase(a4),d3
  92.     add.l    p_dlen(a4),d3
  93.     move.l    d3,_edata        * end of data segment
  94.     move.l    p_bbase(a4),d3
  95.     add.l    p_blen(a4),d3
  96.     move.l    p_env(a4),__envp    * save environment pointer
  97.     move.l  a4,_end            * save basepage address for a moment
  98. *
  99. * compute work screen location, its parameters and reserve memory for it
  100. *
  101.     move.l  #255,d0
  102.     add.l    d0,d3            * here a space for our work screen
  103.     not.l    d0
  104.     and.l    d0,d3            * align it on 0x100 boundary
  105.     move.l    d3,_screen        * set work screen start
  106.  
  107. *
  108. * This code fills fields in _w structure from a file window.c
  109. * and finds how much memory has to be reserved
  110. * All changes in window structure have to be reflected here!
  111. *
  112.  
  113.     move.w  #Getrez,-(sp) 
  114.     jsr    _xbios
  115.     move.w    d0,_w+6            * and store it in w.res
  116. *
  117. * get all other info from line-A stuff
  118. *
  119.     .dc.w    $0a000
  120.     lea    _w,a2
  121.     move.l  a1,20(a2)        * a pointer to pointers to fonts
  122.     moveq   #0,d0
  123.     move.w    d0,(a2)+        * clear curc
  124.     move.l    d0,(a2)+        * clear curl
  125.     move.w  -44(a0),d0        * number of columns = V_CEL_MX
  126.     addq    #1,d0
  127.     move.w    (a2)+,d3        * grab resolution
  128.     cmp.w   #2,d3            * is this still ST resolution?
  129.     bgt    sfind            * jump if no
  130.     moveq    #80,d1
  131.     cmp.w   d1,d0            * no more than 80 columns?
  132.     ble    sfind            * jump in this case
  133. *
  134. *    it looks like that we are running on Moniterm
  135. *    szadb will work only with a standard monitor hooked on a side
  136. *    so stick canned values into _w structure;
  137. *
  138.     subq    #1,d3            * test resolution
  139.     bge    cols
  140.     lsr.w    #1,d1            * only 40 columns for low
  141. cols:
  142.     move.w    d1,(a2)+        
  143.     move.w  #25,(a2)+        * always 25 rows
  144.     moveq    #16,d1
  145.     moveq    #80,d2    
  146.     subq    #1,d3            * medium or low res?
  147.     beq    fsize            * jump if not
  148.     lsr.w    #1,d1            * fontsz only 8
  149.     lsl.w    #1,d2            * but fsz 160
  150. fsize:
  151.     move.w    d1,(a2)+        * store fontsz
  152.     addq    #2,a2            * skip csz
  153.     move.w    #1280,(a2)+        * lsz is fixed here
  154.     move.w    d2,(a2)            * fill fsz
  155.     move.l  #7999,d0        * this+1 = screen size in long words
  156.     bra    blanksc
  157. *
  158. * no monitor trickery here - try to find out real values for screen
  159. * parameters
  160. *
  161. sfind:
  162.     move.w    d0,(a2)+        * d0 -> cols
  163.     move.w  -42(a0),d0        * number of rows = V_CEL_MY
  164.     addq    #1,d0
  165.     move.w    d0,(a2)+
  166.     move.w  -46(a0),d1
  167.     move.w  d1,(a2)+        * fontsz
  168.     addq    #2,a2            * skip csz
  169.     move.w  -40(a0),d0        * width of line in bytes
  170.     move.w  d0,(a2)+        * lsz - upper half of d0 already clear
  171.     divu    d1,d0
  172.     move.w    d0,(a2)            * fsz
  173.     move.w  (a0),d0            * number of planes
  174.     mulu    -4(a0),d0        * and multiply by max_y
  175.     mulu    -12(a0),d0        * and by max_x - total size in pixels
  176.     lsr.l   #5,d0            * total size of screen in long words
  177. *
  178. * blank out screen area
  179. *
  180. blanksc:
  181.     move.l    _screen,a0
  182.     move.l    d0,d1
  183.     swap    d1
  184.     moveq    #0,d3
  185. clean:                    * overshot by 1 in a case
  186.                     * of screen size not divisible by 32
  187.     move.l    d3,(a0)+
  188.     dbra    d0,clean
  189.     dbra    d1,clean
  190.     move.l    a0,_linbuf        * buffer for a current line characters
  191.     move.w    -10(a2),d0        * screen width
  192.     subq    #1,d0
  193.     lsr.w    #2,d0            * decremented count in long words
  194.     move.w    d0,_linsize        * for use by dbra in _cleanlb
  195.     lsl.w    #2,d0            * this number is even
  196.     addq.w    #6,d0            * number of columns + '\r\n'
  197.     add.w    d0,a0            * _linbuf ends here
  198.     move.l    a0,_svline        * this buffer used only when help
  199.                     * is active
  200.     add.w    d0,a0            * same size as for linbuf
  201. *
  202. * reserve space for a work screen between end of the program
  203. * and a space for stack - calculate initial __break value
  204. newbrk:
  205.     move.l    a0,__break
  206.     move.l  _end,a4            * restore pointer to basepage
  207.     move.l    a0,_end            * our end of program (with screen)
  208.  
  209. *
  210. * call C function to get command line arguments
  211. * this has to be done after screen setup, since _initargs moves __break
  212. *
  213.     lea.l    p_cmdlin(a4),a0        * get pointer to command line image
  214.     move.b    (a0)+,d0
  215.     ext.w    d0            * extract length
  216.     move.w    d0,-(sp)        * cmdlen
  217.     move.l    a0,-(sp)        * cmdline
  218.     jsr    __initar        * call _initargs(cmdline, cmdlen)
  219.     addq.l    #6,sp
  220. *
  221. * calculate free space available to program
  222. *
  223.     move.l    __break,a3        * a3 = base of free space
  224.     move.l    a3,d3
  225.     neg.l    d3
  226.     add.l    p_hitpa(a4),d3
  227.     sub.l    #MARGIN,d3        * d3 = free space
  228. *
  229. * calculate new stack size (store in d2)
  230. *
  231.     move.l    #__STKSIZ,a2        * a2 = &_STKSIZ
  232.     move.l    a2,d2            * if __STKSIZ is undefined
  233.     beq    minimum            *   use MINSTK
  234.     move.l    (a2),d2            * if __STKSIZ is positive
  235.     bpl    setstk            *   use __STKSIZ
  236.     add.l    d3,d2            * if __STKSIZ is negative
  237.     cmp.l    #MINSTK,d2        *   try (free space + __STKSIZ)
  238.     bge    setstk            * if < MINSTK
  239. minimum:
  240.     move.l    #MINSTK,d2        *   use MINSTK
  241. *
  242. * check to see if there is enough room for requested stack
  243. *
  244. setstk:
  245.     cmp.l    d3,d2
  246.     blt    shrink            * if (available < requested)
  247.     move.l    #stkerr,-(sp)
  248.     move.w    #Cconws,-(sp)
  249.     trap    #1            *   report a stack error
  250.     addq.l    #6,sp
  251.     move.w    #-39,-(sp)
  252.     move.w    #Pterm,-(sp)
  253.     trap    #1            *   and return error -39 (ENSMEM)
  254. *
  255. * set up new stack pointer and Mshrink
  256. *
  257. shrink:
  258.     add.l    a3,d2            * new stack = free base + stack size
  259.     move.l    d2,sp
  260.     sub.l    a4,d2            * keep space = new stack - __base
  261.     move.l    d2,-(sp)
  262.     move.l    a4,-(sp)
  263.     clr.w    -(sp)
  264.     move.w    #Mshrink,-(sp)
  265.     trap    #1            * Mshrink(0, _base, keep);
  266.     add.l    #12,sp
  267. *
  268. * Look at kernel sp
  269. *
  270.     move.l    #0,-(sp)
  271.     move.w    #$20,-(sp)
  272.     trap    #1
  273.     add.w    #6,sp
  274.     move.l    d0,_ossp
  275. *
  276. * call C entry point function _main()
  277. *
  278.     jsr    __main            * if _main returns
  279.     move.w    d0,4(sp)        *   insert return value and fall thru
  280.  
  281. *
  282. * void _exit(code)
  283. *   int code;
  284. *
  285. * Terminate process with a return value of <code>
  286. *
  287. __exit:
  288.     tst.l    (sp)+            * pop return PC off the stack
  289.     move.w    (sp)+,d7        * exit code
  290.  
  291.     move.l    _ossp,d0        * old system stack pointer
  292.     move.l    d0,-(sp)
  293.     move.w    #$20,-(sp)
  294.     trap    #1
  295.     add.w    #6,sp
  296.  
  297.     move.w    d7,-(sp)
  298.     move.w    #Pterm,-(sp)
  299.     trap    #1            *   and terminate.
  300.  
  301. *
  302. * operating system trap hooks for C
  303. *
  304.  
  305. *
  306. * long gemdos(function, [parameter, ...])
  307. *   int function;
  308. *
  309. _gemdos:
  310.     move.l    (sp)+,traprtn        * save return address
  311.     trap    #1            * do gemdos trap
  312.     bra    chkstk
  313.  
  314. *
  315. * long bios(function, [parameter, ...])
  316. *   int function;
  317. *
  318. _bios:
  319.     move.l    (sp)+,traprtn        * save return address
  320.     trap    #13            * do bios trap
  321.     bra    chkstk
  322.  
  323. *
  324. * long xbios(function, [parameter, ...])
  325. *   int function;
  326. *
  327. _xbios:
  328.     move.l    (sp)+,traprtn        * save return address
  329.     trap    #14            * do xbios trap
  330.     bra    chkstk
  331.  
  332. *
  333. * int bdos(function, parameter)
  334. *   int function;
  335. *   long parameter;
  336. *
  337. _bdos:
  338.     move.l    (sp),traprtn        * save return address
  339.     move.l    a6,(sp)            * save old frame pointer
  340.     move.l    sp,a6            * set up frame pointer
  341.     tst.l    -(a6)            *   (fake "link a6,#0")
  342.     move.w    8(a6),d0        * function code in D0.W
  343.     move.l    10(a6),d1        * parameter value in D1.L
  344.     trap    #2            * do bdos trap
  345.     move.l    (sp)+,a6        * restore old frame pointer
  346.  
  347. *
  348. * check for stack overflow (done after all OS traps)
  349. *
  350. chkstk:
  351. *    cmp.l    __break,sp
  352. *    bgt    nosweat            * if (_break > sp)
  353. *    move.l    #stkovf,-(sp)
  354. *    move.w    #Cconws,-(sp)
  355. *    trap    #1            *   report a stack overflow
  356. *    addq.l    #6,sp
  357. *    move.w    #-1,-(sp)
  358. *    move.w    #Pterm,-(sp)
  359. *    trap    #1            *   and return error -1 (ERROR)
  360. nosweat:
  361.     move.l    traprtn,-(sp)        * else, restore return address
  362.     rts                * and do a normal return.
  363.  
  364. *
  365. * this call to _main ensures that it the user's main() function will be
  366. * linked, even if it is in a library.
  367. *
  368.     jsr    _main            * NO PATH TO THIS STATEMENT
  369.  
  370. * THE FOLLOWING IS SELF MODIFYING CODE, DO NOT DISTURB
  371.     move.l    #$644c6962,$7320(sp)
  372.     moveq.l    #$31,d3
  373.     move.l    $0(a2,d0),d7
  374.  
  375. *
  376. * initialized data space
  377. *
  378. .data
  379. .even
  380. stkerr:                    * not enough memory for stack
  381.     .dc.b    'Not enough memory',$d,$a,0
  382. stkovf:                    * impending stack overflow
  383.     .dc.b    'Stack overflow',$d,$a,0
  384. _errno:                    * system error number
  385.     .dc.w    0
  386. __argc:                    * number of command line args
  387.     .dc.w    0
  388. __argv:                    * pointer to command line arg list
  389.     .dc.l    0
  390. *
  391. * uninitialized data space
  392. *
  393. .bss
  394. .even
  395. __base:                    * pointer to basepage
  396.     .ds.l    1
  397. _etext:                    * pointer to end of text segment
  398.     .ds.l    1
  399. _edata:                    * pointer to end of data segment
  400.     .ds.l    1
  401. _end:                    * pointer to end of BSS (end of program)
  402.     .ds.l    1
  403. __break:                * pointer to stack/heap break
  404.     .ds.l    1
  405. __envp:                    * pointer to environment string
  406.     .ds.l    1
  407. traprtn:                * storage for return PC in trap hooks
  408.     .ds.l    1
  409. _ossp:
  410.     .ds.l    1
  411. .end
  412.