home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / unix / unixlib_1 / !UnixLib37_src_sys_s__syslib < prev    next >
Encoding:
Text File  |  1996-11-09  |  17.8 KB  |  926 lines

  1. ;----------------------------------------------------------------------------
  2. ;
  3. ; $Source: /unixb/home/unixlib/source/unixlib37/src/sys/s/RCS/_syslib,v $
  4. ; $Date: 1996/11/06 22:01:42 $
  5. ; $Revision: 1.6 $
  6. ; $State: Rel $
  7. ; $Author: unixlib $
  8. ;
  9. ; $Log: _syslib,v $
  10. ; Revision 1.6  1996/11/06 22:01:42  unixlib
  11. ; Yet more changes by NB, PB and SC.
  12. ;
  13. ; Revision 1.5  1996/10/30 21:59:00  unixlib
  14. ; Massive changes made by Nick Burret and Peter Burwood.
  15. ;
  16. ; Revision 1.4  1996/09/16 21:23:52  unixlib
  17. ; CL_0002 Nick Burret
  18. ; Minor changes to file handling
  19. ; Change most error numbers, and use in assembler sources (SJC)
  20. ; Various minor bug fixes and compatability changes.
  21. ;
  22. ; Revision 1.3  1996/07/21 22:19:42  unixlib
  23. ; CL_0001 Nick Burret
  24. ; Improve memory handling. Remove C++ library incompatibilities.
  25. ; Improve file stat routines.
  26. ;
  27. ; Revision 1.2  1996/05/06 09:01:35  unixlib
  28. ; Updates to sources made by Nick Burrett, Peter Burwood and Simon Callan.
  29. ; Saved for 3.7a release.
  30. ;
  31. ; Revision 1.1  1996/04/19 21:34:32  simon
  32. ; Initial revision
  33. ;
  34. ;----------------------------------------------------------------------------
  35.  
  36.     GET    Unix37:unixlib.s.asm_dec
  37.  
  38.     AREA    |C$$code|,CODE,READONLY
  39.  
  40.  
  41.     IMPORT    |_main|
  42.     EXPORT    |__main|
  43.  
  44.     NAME    __main
  45.  
  46.     ENTRY
  47. |__main|
  48.     SWI    XOS_GetEnv
  49.     [ |__4K_BOUNDARY| = 1
  50.     ; align top of wimpslot to 4k (downwards)
  51.     BIC    a2,a2,#&ff
  52.     BIC    a2,a2,#&f00
  53.     ]
  54.     MOV    sp,a2        ; Stack = top of RAM
  55.     SUB    sl,sp,#2048    ; Limit is 2K below.
  56.  
  57.     LDR    a4,[pc,#|__cli_ptr|-.-8]
  58.     STR    a1,[a4,#0]    ; Set pointer to command line
  59.     LDR    a4,[pc,#|__himem_ptr|-.-8]
  60.     STR    a2,[a4,#0]    ; Set top of memory
  61.     LDR    a4,[pc,#|__stack_ptr|-.-8]
  62.     STR    sl,[a4,#0]    ; Set bottom of stack
  63.     LDMIA    a3,{a1,a2}
  64.     AND    a2,a2,#&ff
  65.     LDR    a3,[pc,#|__time_ptr|-.-8]
  66.     STMIA    a3,{a1,a2}    ; Set start time.
  67.     LDR    a4,[pc,#|__robase_ptr|-.-8]
  68.     LDR    a1,[a4,#0]    ; get start of RO area
  69.     LDR    a4,[pc,#|__base_ptr|-.-8]
  70.     STR    a1,[a4,#0]    ; Set start address of code.
  71.     LDR    a4,[pc,#|__rwlimit_ptr|-.-8]
  72.     LDR    a1,[a4,#0]    ; Get start of R/W area
  73.     [ |__4K_BOUNDARY| = 1
  74.     ; align rwlimit to 4k
  75.     ADD    a1,a1,#&1000
  76.     SUB    a1,a1,#1
  77.     BIC    a1,a1,#&ff
  78.     BIC    a1,a1,#&f00
  79.     STR    a1,[a4,#0]
  80.     ]
  81.     LDR    a4,[pc,#|__lomem_ptr|-.-8]
  82.     STR    a1,[a4,#0]    ; Set start of used memory
  83.     LDR    a4,[pc,#|__break_ptr|-.-8]
  84.     STR    a1,[a4,#0]    ; Set end of used memory
  85.     LDR    a4,[pc,#|__stack_limit_ptr|-.-8]
  86.     STR    a1,[a4,#0]    ; Set ultimate limit on stack
  87.     CMP    sl,a1
  88.     BLS    |__exit_no_memory|    ; no stack - exit fast
  89.  
  90.     ; use of da's explicitly overridden if __dynamic_no_da is declared
  91.     ADR    a1,|__dynamic_no_da_ptr|
  92.     LDR    a1,[a1,#0]
  93.     TEQ    a1,#0
  94.     BNE    |__no_dynamic_area|
  95.  
  96.     ; check OS version for RISC OS 3.5+
  97.     MOV    a1,#129
  98.     MOV    a2,#0
  99.     MOV    a3,#255
  100.     SWI    XOS_Byte
  101.     BVS    |__no_dynamic_area|
  102.     CMP    a2,#165
  103.     BCC    |__no_dynamic_area|
  104.  
  105.     ; use old dynamic area if possible
  106.     ; if app mem size = mem size, then can't be a spawned program
  107.     MOV    a1,#14
  108.     MOV    a2,#0
  109.     SWI    XOS_ChangeEnvironment
  110.     CMP    a2,sp
  111.     BEQ    |__no_old_area|
  112.     ; validate numbers at top of application memory (see sys.s._exec)
  113.     LDMIA    sp,{a1,a2,a3,a4,v1,v2,v3,v4}
  114.     EOR    a3,a3,a1,ROR #7
  115.     CMP    a3,a1
  116.     EOREQ    v1,v1,a1,ROR #13
  117.     CMPEQ    v1,a1
  118.     EOREQ    v3,v3,a1,ROR #23
  119.     CMPEQ    v3,a1
  120.     EOREQ    a4,a4,a2,ROR #7
  121.     CMPEQ    a4,a2
  122.     EOREQ    v2,v2,a2,ROR #13
  123.     CMPEQ    v2,a2
  124.     EOREQ    v4,v4,a2,ROR #23
  125.     CMPEQ    v4,a2
  126.     BNE    |__no_old_area|
  127.     MOV    v6,a1                ; save new __lomem
  128.     MOV    a1,#2
  129.     SWI    XOS_DynamicArea
  130.     ; check new __lomem = end of dynamic area
  131.     ADD    a4,a4,a3
  132.     TEQ    a4,v6
  133.     BNE    |__no_old_area|
  134.     MOV    v6,#0
  135.     BVC    |__da_found|
  136.  
  137. |__no_old_area|
  138.     ; area name is program name + "_Heap"
  139.     LDR    a4,[pc,#|__cli_ptr|-.-8]
  140.     LDR    a1,[a4,#0]
  141.     MOV    a2,a1
  142.     ; search for space or end of cli string
  143. 01
  144.     LDRB    a3,[a2],#1
  145.     CMP    a3,#&20
  146.     CMPNE    a3,#0
  147.     BNE    %B01
  148.     SUB    a4,a2,#1        ; a4 is end of program name + 1
  149.     ; search back for '.' or beginning of program name
  150. 02
  151.     LDRB    a3,[a2,#-1]!
  152.     CMP    a2,a1
  153.     CMPNE    a3,#&2E
  154.     BNE    %B02
  155.     CMP    a3,#&2E
  156.     ADDEQ    a2,a2,#1
  157.     ; use a maximum of 10 characters from the program name
  158.     SUB    a3,a4,a2
  159.     CMP    a3,#10
  160.     MOVGT    a3,#10
  161.     ADDGT    a4,a2,a3
  162.     ADR    v5,|__dynamic_area_name_end_ptr|
  163.     LDR    v5,[v5,#0]
  164.     SUB    v5,v5,a3
  165.     MOV    a1,v5
  166. 03
  167.     LDRB    a3,[a2],#1
  168.     STRB    a3,[a1],#1
  169.     CMP    a2,a4
  170.     BLT    %B03
  171.  
  172.     ; check environment variable for creating a DA
  173.     MOV    a1,v5
  174.     MOV    a3,#-1
  175.     MOV    a4,#0
  176.     MOV    v1,#0
  177.     SWI    XOS_ReadVarVal
  178.     CMP    a3,#0
  179.     BGE    |__no_dynamic_area|
  180.  
  181.     ; create dynamic area
  182.     MOV    a1,#0
  183.     MOV    a2,#-1
  184.     ; set initial size of dynamic area to 0K
  185.     MOV    a3,#0
  186.     MOV    a4,#-1
  187.     MOV    v1,#&80
  188.     MOV    v2,#-1            ; maximum size is total RAM in m/c
  189.     MOV    v3,#0
  190.     MOV    v4,#0
  191.     ; v5 is already set from above
  192.     SWI    XOS_DynamicArea
  193.     BVS    |__exit_no_memory|    ; no DA, report and exit
  194.     MOV    v6,a3            ; setup for deletion at exit
  195. |__da_found|
  196.     ; v6 is size left in area, a4 is start offset
  197.     ADD    a1,v6,a4
  198.     LDR    v3,[pc,#|__lomem_ptr|-.-8]
  199.     STR    a4,[v3,#0]    ; Lomem is start of DA
  200.     LDR    v3,[pc,#|__break_ptr|-.-8]
  201.     STR    a1,[v3,#0]    ; break is end of DA
  202.     LDR    v3,[pc,#|__dynamic_num_ptr|-.-8]
  203.     STR    a2,[v3,#0]
  204.  
  205.     ; set lower stack limit to __rwlimit
  206.     LDR    v3,[pc,#|__rwlimit_ptr|-.-8]
  207.     LDR    a1,[v3,#0]
  208.     LDR    v3,[pc,#|__stack_limit_ptr|-.-8]
  209.     STR    a1,[v3,#0]
  210.  
  211.     ; if current size == passed in size, then delete DA at exit
  212.     ; this means a spawning program must ensure that some of area is used
  213.     ; which is always true, since 8K of heap is initially allocated
  214.     ; FIXME - if we record the initial DA limit, then we can shrink the
  215.     ; dynamic area when the spawned program exits.
  216.     CMP    a3,v6
  217.     MOVEQ    v5,#1
  218.     MOVNE    v5,#0
  219.     LDR    v3,[pc,#|__dynamic_deletion_ptr|-.-8]
  220.     STR    v5,[v3,#0]
  221.  
  222. |__no_dynamic_area|
  223.     ADD    sl,sl,#256
  224.     MOV    fp,#0
  225.     LDR    a1,[pc,#|__alloca_list_ptr|-.-8]
  226.     CMP    a1,#0
  227.     STRNE    fp,[a1,#0]
  228.  
  229.     ; This line is needed for the GNU Objective-C runtime system.
  230.     ; We need a safe 128 bytes of stack space to prevent a program
  231.     ; crashing when the library does a direct copy off the stack.
  232.     SUB    sp, sp, #128
  233.     ; Find out whether we are executing within a TaskWindow or not.
  234.     MOV    a1, #0
  235.     SWI    XTaskWindow_TaskInfo
  236.     LDR    a2, [pc, #|__taskwindow_ptr| - . - 8]
  237.     MOVVS    a1, #0
  238.     STR    a1, [a2, #0]
  239.     B    |_main|
  240.  
  241. |__exit_no_memory|
  242.     SWI    OS_WriteS
  243.     DCB    "Insufficient memory for application", 0
  244.     ALIGN
  245.     SWI    OS_NewLine
  246.     MOV    a1,#0
  247.     LDR    a2,[pc,#|__exit_word|-.-8]
  248.     MOV    a3,#1
  249.     SWI    OS_Exit
  250.  
  251. |__dynamic_area_name_end_ptr|
  252.     DCD    |__dynamic_area_name_end|
  253.  
  254.     IMPORT    |Image$$RO$$Base|
  255.     IMPORT    |Image$$RW$$Base|
  256.     IMPORT    |Image$$RW$$Limit|
  257.  
  258.     EXPORT    |__svccli|    ; copy CLI in SVC mode
  259.  
  260.     NAME    __svccli
  261. |__svccli|
  262.     LDR    a2,[pc,#|__cli_ptr|-.-8]
  263.     LDR    a2,[a2,#0]
  264.     MOV    a4,lr
  265.     SWI    OS_EnterOS
  266. |__svccli_l0|
  267.     LDRBT    a3,[a2],#1
  268.     STRBT    a3,[a1],#1
  269.     CMP    a3,#0
  270.     BNE    |__svccli_l0|
  271.     MOVS    pc,a4        ; return to USR mode
  272.  
  273. |__taskwindow_ptr|
  274.     DCD    |__taskwindow|
  275.  
  276.     IMPORT    |__dynamic_no_da|,WEAK
  277. |__dynamic_no_da_ptr|
  278.     DCD    |__dynamic_no_da|
  279. |__dynamic_num_ptr|
  280.     DCD    |__dynamic_num|
  281. |__dynamic_deletion_ptr|
  282.     DCD    |__dynamic_deletion|
  283.  
  284. |__cli_ptr|
  285.     DCD    |__cli|
  286.  
  287. |__robase_ptr|
  288.     DCD    |__robase|
  289. |__base_ptr|
  290.     DCD    |__base|
  291. |__rwbase_ptr|
  292.     DCD    |__rwbase|
  293. |__rwlimit_ptr|
  294.     DCD    |__rwlimit|
  295. |__himem_ptr|
  296.     DCD    |__himem|
  297. |__lomem_ptr|
  298.     DCD    |__lomem|
  299.  
  300. |__break_ptr|
  301.     DCD    |__break|
  302. |__stack_ptr|
  303.     DCD    |__stack|
  304. |__stack_limit_ptr|
  305.     DCD    |__stack_limit|
  306.  
  307. |__time_ptr|
  308.     DCD    |__time|
  309.  
  310.     IMPORT    |__alloca_list|,WEAK
  311. |__alloca_list_ptr|
  312.     DCD    |__alloca_list|
  313.  
  314.     IMPORT    |__uname_dont_pack|,WEAK
  315.     EXPORT    |__uname_dont_pack_ptr|
  316. |__uname_dont_pack_ptr|
  317.     DCD    |__uname_dont_pack|
  318.  
  319.     EXPORT    |__dynamic_area_exit|
  320. |__dynamic_area_exit|
  321.     LDR    a2,[pc,#|__dynamic_deletion_ptr|-.-8]
  322.     LDR    a2,[a2,#0]
  323.     TEQ    a2,#1
  324.     MOVNES    pc,lr
  325.     MOV    a4,lr
  326.     LDR    a2,[pc,#|__dynamic_num_ptr|-.-8]
  327.     LDR    a2,[a2,#0]
  328.     MOV    a1,#1
  329.     CMP    a2,#-1
  330.     SWINE    XOS_DynamicArea
  331.     MOVS    pc,a4
  332.  
  333.     EXPORT    |__exit|
  334.  
  335.     NAME    __exit
  336. |__exit|
  337.     MOV    v1,a1
  338.     BL    |__dynamic_area_exit|
  339.     ; re-enable Escape (in case SIGINT handler fired in ttyicanon)
  340.     MOV    a1,#229
  341.     MOV    a2,#0
  342.     MOV    a3,#0
  343.     SWI    XOS_Byte
  344.     MOV    a3,v1
  345.     LDR    a2,[pc,#|__exit_word|-.-8]
  346.     MOV    a1,#0
  347.  
  348.     SWI    OS_Exit ; - never returns
  349.  
  350. |__exit_word|
  351.     DCD    &58454241
  352.  
  353.     EXPORT    |__exit_no_code|
  354.  
  355. |__exit_no_code|
  356.     BL    |__dynamic_area_exit|
  357.     MOV    a1,#0
  358.     MOV    a2,#0
  359.     MOV    a3,#0
  360.     SWI    OS_Exit ; - never returns
  361.  
  362.     IMPORT    |__vret|,WEAK
  363.     EXPORT    |___vret|
  364. |___vret|
  365.     DCD    |__vret|
  366.  
  367.     IMPORT    |__stdioinit|,WEAK
  368.     EXPORT    |___stdioinit|
  369. |___stdioinit|
  370.     DCD    |__stdioinit|
  371.  
  372.     IMPORT    |__stdioexit|,WEAK
  373.     EXPORT    |___stdioexit|
  374. |___stdioexit|
  375.     DCD    |__stdioexit|
  376.  
  377.     IMPORT    |___main|, WEAK
  378.     EXPORT    |___do_global_ctors|
  379. |___do_global_ctors|
  380.     DCD    |___main|
  381.  
  382.  
  383.     EXPORT    |__rdenv|
  384.  
  385.     NAME    __rdenv
  386. |__rdenv|
  387.     MOV    ip,a2
  388.     MOV    a2,#0
  389.     MOV    a3,#0
  390.     MOV    a4,#0
  391.  
  392.     SWI    XOS_ChangeEnvironment
  393.  
  394.     STMVCIA ip,{a2,a3,a4}
  395.     MOVVC    a1,#0
  396.  
  397.     MOVS    pc,lr
  398.  
  399.     EXPORT    |__wrenv|
  400.  
  401.     NAME    __wrenv
  402. |__wrenv|
  403.     LDMIA    a2,{a2,a3,a4}
  404.     SWI    XOS_ChangeEnvironment
  405.     MOVVC    a1,#0
  406.     MOVS    pc,lr
  407.  
  408.  
  409.     EXPORT    |x$divtest|
  410. ; The following symbols are added so we can use UnixLib with C v.5
  411.     EXPORT    |__rt_divtest|
  412. |x$divtest|
  413. |__rt_divtest|
  414.     MOVS    pc,lr
  415.  
  416.     EXPORT    |x$remainder|
  417.  
  418.     NAME    x$remainder
  419. |x$remainder|
  420.     STMFD    sp!,{lr}
  421.     BL    |x$divide|
  422.     MOV    a1,a2
  423.     LDMFD    sp!,{pc}^
  424.  
  425.     EXPORT    |x$uremainder|
  426.  
  427.     NAME    x$uremainder
  428. |x$uremainder|
  429.     STMFD    sp!,{lr}
  430.     BL    |x$udivide|
  431.     MOV    a1,a2
  432.     LDMFD    sp!,{pc}^
  433.  
  434. |x$overflow|
  435.     MVN    a1,#0
  436.     MOVS    pc,lr
  437.  
  438. ; Veneer to x$udivide to cater for C v.5 code generation
  439.     EXPORT    |__rt_udiv10|    ; a1 = a1 / 10; a2 = a1 % 10
  440.  
  441.     NAME    __rt_udiv10
  442. |__rt_udiv10|
  443.     MOV    a2,a1
  444.     MOV    a1,#10
  445.     B    |x$udiv10|    ; let x$udivide return for us
  446.  
  447.     EXPORT    |x$udivide|    ; a1 = a2 / a1; a2 = a2 % a1
  448. ; The following symbols are added so we can use UnixLib with C v.5
  449.     EXPORT    |__rt_udiv|
  450.     EXPORT    |_kernel_udiv|
  451.  
  452.     NAME    x$udivide
  453. |x$udivide|
  454. |__rt_udiv|
  455. |_kernel_udiv|
  456.     CMP    a1,#1
  457.     BLO    |x$overflow|
  458.     BEQ    |x$divide_l0|
  459. |x$udiv10|
  460.     MOV    ip,#0
  461.     MOVS    a2,a2
  462.     BPL    |x$divide_l1|
  463.     ORR    ip,ip,#&20000000; ip bit &20000000 = -ve a2
  464.     MOVS    a2,a2,LSR #1
  465.     ORRCS    ip,ip,#&10000000; ip bit &10000000 = bit 0 of a2
  466.     B    |x$divide_l1|
  467.  
  468. |x$divide_l0|            ; a1 == 1
  469.     MOV    a1,a2
  470.     MOV    a2,#0
  471.     MOVS    pc,lr
  472.  
  473. ; Veneer to x$divide to cater for C v.5 code generation
  474.     EXPORT    |__rt_sdiv10|    ; a1 = a1 / 10; a2 = a1 % 10
  475.  
  476.     NAME    __rt_sdiv10
  477. |__rt_sdiv10|
  478.     MOV    a2,a1
  479.     MOV    a1,#10
  480.     B    |x$sdiv10|    ; let x$divide return for us
  481.  
  482.     EXPORT    |x$divide|    ; a1 = a2 / a1; a2 = a2 % a1
  483. ; The following symbols are added so we can use UnixLib with C v.5
  484.     EXPORT    |__rt_sdiv|
  485.     EXPORT    |_kernel_sdiv|
  486.  
  487.     NAME    x$divide
  488. |x$divide|
  489. |__rt_sdiv|
  490. |_kernel_sdiv|
  491.     CMP    a1,#1
  492.     BLO    |x$overflow|
  493.     BEQ    |x$divide_l0|
  494. |x$sdiv10|
  495.     ANDS    ip,a1,#&80000000
  496.     RSBMI    a1,a1,#0
  497.     ANDS    a3,a2,#&80000000
  498.     EOR    ip,ip,a3
  499.     RSBMI    a2,a2,#0
  500.     ORR    ip,a3,ip,LSR #1 ; ip bit &40000000 = -ve division
  501.                 ; ip bit &80000000 = -ve remainder
  502.  
  503. |x$divide_l1|
  504.     MOV    a3,#1
  505.     MOV    a4,#0
  506.  
  507.     CMP    a2,a1
  508.     BLO    |x$divide_b0|
  509.     CMP    a2,a1,LSL #1
  510.     BLO    |x$divide_b1|
  511.     CMP    a2,a1,LSL #2
  512.     BLO    |x$divide_b2|
  513.     CMP    a2,a1,LSL #3
  514.     BLO    |x$divide_b3|
  515.     CMP    a2,a1,LSL #4
  516.     BLO    |x$divide_b4|
  517.     CMP    a2,a1,LSL #5
  518.     BLO    |x$divide_b5|
  519.     CMP    a2,a1,LSL #6
  520.     BLO    |x$divide_b6|
  521.     CMP    a2,a1,LSL #7
  522.     BLO    |x$divide_b7|
  523.     CMP    a2,a1,LSL #8
  524.     BLO    |x$divide_b8|
  525.     CMP    a2,a1,LSL #9
  526.     BLO    |x$divide_b9|
  527.     CMP    a2,a1,LSL #10
  528.     BLO    |x$divide_b10|
  529.     CMP    a2,a1,LSL #11
  530.     BLO    |x$divide_b11|
  531.     CMP    a2,a1,LSL #12
  532.     BLO    |x$divide_b12|
  533.     CMP    a2,a1,LSL #13
  534.     BLO    |x$divide_b13|
  535.     CMP    a2,a1,LSL #14
  536.     BLO    |x$divide_b14|
  537.     CMP    a2,a1,LSL #15
  538.     BLO    |x$divide_b15|
  539.     CMP    a2,a1,LSL #16
  540.     BLO    |x$divide_b16|
  541.     CMP    a2,a1,LSL #17
  542.     BLO    |x$divide_b17|
  543.     CMP    a2,a1,LSL #18
  544.     BLO    |x$divide_b18|
  545.     CMP    a2,a1,LSL #19
  546.     BLO    |x$divide_b19|
  547.     CMP    a2,a1,LSL #20
  548.     BLO    |x$divide_b20|
  549.     CMP    a2,a1,LSL #21
  550.     BLO    |x$divide_b21|
  551.     CMP    a2,a1,LSL #22
  552.     BLO    |x$divide_b22|
  553.     CMP    a2,a1,LSL #23
  554.     BLO    |x$divide_b23|
  555.     CMP    a2,a1,LSL #24
  556.     BLO    |x$divide_b24|
  557.     CMP    a2,a1,LSL #25
  558.     BLO    |x$divide_b25|
  559.     CMP    a2,a1,LSL #26
  560.     BLO    |x$divide_b26|
  561.     CMP    a2,a1,LSL #27
  562.     BLO    |x$divide_b27|
  563.     CMP    a2,a1,LSL #28
  564.     BLO    |x$divide_b28|
  565.     CMP    a2,a1,LSL #29
  566.     BLO    |x$divide_b29|
  567.     CMP    a2,a1,LSL #30
  568.     BLO    |x$divide_b30|
  569.     CMP    a2,a1,LSL #31
  570.     SUBHS    a2,a2,a1,LSL #31
  571.     ADDHS    a4,a4,a3,LSL #31
  572.     CMP    a2,a1,LSL #30
  573.     SUBHS    a2,a2,a1,LSL #30
  574.     ADDHS    a4,a4,a3,LSL #30
  575. |x$divide_b30|
  576.     CMP    a2,a1,LSL #29
  577.     SUBHS    a2,a2,a1,LSL #29
  578.     ADDHS    a4,a4,a3,LSL #29
  579. |x$divide_b29|
  580.     CMP    a2,a1,LSL #28
  581.     SUBHS    a2,a2,a1,LSL #28
  582.     ADDHS    a4,a4,a3,LSL #28
  583. |x$divide_b28|
  584.     CMP    a2,a1,LSL #27
  585.     SUBHSS    a2,a2,a1,LSL #27
  586.     ADDHS    a4,a4,a3,LSL #27
  587. |x$divide_b27|
  588.     CMP    a2,a1,LSL #26
  589.     SUBHS    a2,a2,a1,LSL #26
  590.     ADDHS    a4,a4,a3,LSL #26
  591. |x$divide_b26|
  592.     CMP    a2,a1,LSL #25
  593.     SUBHS    a2,a2,a1,LSL #25
  594.     ADDHS    a4,a4,a3,LSL #25
  595. |x$divide_b25|
  596.     CMP    a2,a1,LSL #24
  597.     SUBHS    a2,a2,a1,LSL #24
  598.     ADDHS    a4,a4,a3,LSL #24
  599. |x$divide_b24|
  600.     CMP    a2,a1,LSL #23
  601.     SUBHS    a2,a2,a1,LSL #23
  602.     ADDHS    a4,a4,a3,LSL #23
  603. |x$divide_b23|
  604.     CMP    a2,a1,LSL #22
  605.     SUBHS    a2,a2,a1,LSL #22
  606.     ADDHS    a4,a4,a3,LSL #22
  607. |x$divide_b22|
  608.     CMP    a2,a1,LSL #21
  609.     SUBHS    a2,a2,a1,LSL #21
  610.     ADDHS    a4,a4,a3,LSL #21
  611. |x$divide_b21|
  612.     CMP    a2,a1,LSL #20
  613.     SUBHS    a2,a2,a1,LSL #20
  614.     ADDHS    a4,a4,a3,LSL #20
  615. |x$divide_b20|
  616.     CMP    a2,a1,LSL #19
  617.     SUBHS    a2,a2,a1,LSL #19
  618.     ADDHS    a4,a4,a3,LSL #19
  619. |x$divide_b19|
  620.     CMP    a2,a1,LSL #18
  621.     SUBHS    a2,a2,a1,LSL #18
  622.     ADDHS    a4,a4,a3,LSL #18
  623. |x$divide_b18|
  624.     CMP    a2,a1,LSL #17
  625.     SUBHS    a2,a2,a1,LSL #17
  626.     ADDHS    a4,a4,a3,LSL #17
  627. |x$divide_b17|
  628.     CMP    a2,a1,LSL #16
  629.     SUBHS    a2,a2,a1,LSL #16
  630.     ADDHS    a4,a4,a3,LSL #16
  631. |x$divide_b16|
  632.     CMP    a2,a1,LSL #15
  633.     SUBHS    a2,a2,a1,LSL #15
  634.     ADDHS    a4,a4,a3,LSL #15
  635. |x$divide_b15|
  636.     CMP    a2,a1,LSL #14
  637.     SUBHS    a2,a2,a1,LSL #14
  638.     ADDHS    a4,a4,a3,LSL #14
  639. |x$divide_b14|
  640.     CMP    a2,a1,LSL #13
  641.     SUBHS    a2,a2,a1,LSL #13
  642.     ADDHS    a4,a4,a3,LSL #13
  643. |x$divide_b13|
  644.     CMP    a2,a1,LSL #12
  645.     SUBHS    a2,a2,a1,LSL #12
  646.     ADDHS    a4,a4,a3,LSL #12
  647. |x$divide_b12|
  648.     CMP    a2,a1,LSL #11
  649.     SUBHS    a2,a2,a1,LSL #11
  650.     ADDHS    a4,a4,a3,LSL #11
  651. |x$divide_b11|
  652.     CMP    a2,a1,LSL #10
  653.     SUBHS    a2,a2,a1,LSL #10
  654.     ADDHS    a4,a4,a3,LSL #10
  655. |x$divide_b10|
  656.     CMP    a2,a1,LSL #9
  657.     SUBHS    a2,a2,a1,LSL #9
  658.     ADDHS    a4,a4,a3,LSL #9
  659. |x$divide_b9|
  660.     CMP    a2,a1,LSL #8
  661.     SUBHS    a2,a2,a1,LSL #8
  662.     ADDHS    a4,a4,a3,LSL #8
  663. |x$divide_b8|
  664.     CMP    a2,a1,LSL #7
  665.     SUBHS    a2,a2,a1,LSL #7
  666.     ADDHS    a4,a4,a3,LSL #7
  667. |x$divide_b7|
  668.     CMP    a2,a1,LSL #6
  669.     SUBHS    a2,a2,a1,LSL #6
  670.     ADDHS    a4,a4,a3,LSL #6
  671. |x$divide_b6|
  672.     CMP    a2,a1,LSL #5
  673.     SUBHS    a2,a2,a1,LSL #5
  674.     ADDHS    a4,a4,a3,LSL #5
  675. |x$divide_b5|
  676.     CMP    a2,a1,LSL #4
  677.     SUBHS    a2,a2,a1,LSL #4
  678.     ADDHS    a4,a4,a3,LSL #4
  679. |x$divide_b4|
  680.     CMP    a2,a1,LSL #3
  681.     SUBHS    a2,a2,a1,LSL #3
  682.     ADDHS    a4,a4,a3,LSL #3
  683. |x$divide_b3|
  684.     CMP    a2,a1,LSL #2
  685.     SUBHS    a2,a2,a1,LSL #2
  686.     ADDHS    a4,a4,a3,LSL #2
  687. |x$divide_b2|
  688.     CMP    a2,a1,LSL #1
  689.     SUBHS    a2,a2,a1,LSL #1
  690.     ADDHS    a4,a4,a3,LSL #1
  691. |x$divide_b1|
  692.     CMP    a2,a1
  693.     SUBHS    a2,a2,a1
  694.     ADDHS    a4,a4,a3
  695. |x$divide_b0|
  696.  
  697.     TST    ip,#&20000000
  698.     BNE    |x$udivide_l1|
  699.     MOV    a1,a4
  700.     CMP    ip,#0
  701.     RSBMI    a2,a2,#0
  702.     MOVS    ip,ip,LSL #1
  703.     RSBMI    a1,a1,#0
  704.     MOVS    pc,lr
  705.  
  706. |x$udivide_l1|
  707.     TST    ip,#&10000000
  708.     MOV    a2,a2,LSL #1
  709.     ORRNE    a2,a2,#1
  710.     MOV    a4,a4,LSL #1
  711.     CMP    a2,a1
  712.     SUBHS    a2,a2,a1
  713.     ADDHS    a4,a4,a3
  714.     MOV    a1,a4
  715.     MOVS    pc,lr
  716.  
  717.  
  718.     IMPORT    raise
  719.  
  720.     EXPORT    |x$stack_overflow|    ; allocate 512 bytes more stack
  721. ; The following symbols are added so we can use UnixLib with C v.5
  722.     EXPORT    |__rt_stkovf_split_small|
  723.  
  724.     NAME    x$stack_overflow
  725. |x$stack_overflow|
  726. |__rt_stkovf_split_small|
  727.     STMFD    sp!,{a1,a2,lr}
  728.     LDR    a1,[pc,#|__stack_limit_ptr|-.-8]
  729.     LDR    a1,[a1,#0]
  730.     LDR    lr,[pc,#|__stack_ptr|-.-8]
  731.     LDR    a2,[lr,#0]
  732.     SUB    a2,a2,#512
  733.     CMP    a2,a1
  734.     STR    a2,[lr,#0]
  735.     ADD    sl,a2,#256
  736.     LDMCSFD sp!,{a1,a2,pc}^
  737.     STMFD    sp!,{a3,a4,ip}
  738.     MOV    a1,#SIGEMT
  739.     BL    raise
  740.     LDMFD    sp!,{a3,a4,ip}
  741.     LDMFD    sp!,{a1,a2,pc}^
  742.  
  743.     EXPORT    |x$stack_overflow_1|    ; allocate stack to below <ip>
  744. ; The following symbols are added so we can use UnixLib with C v.5
  745.     EXPORT    |__rt_stkovf_split_big|
  746.  
  747.     NAME    x$stack_overflow_1
  748. |x$stack_overflow_1|
  749. |__rt_stkovf_split_big|
  750.     CMP    ip,sl            ; sanity check
  751.     MOVCSS    pc,lr
  752.     STMFD    sp!,{a1,a2,lr}
  753.     LDR    a1,[pc,#|__stack_limit_ptr|-.-8]
  754.     LDR    a1,[a1,#0]
  755.     LDR    lr,[pc,#|__stack_ptr|-.-8]
  756.     SUB    a2,ip,#512
  757.     CMP    a2,a1
  758.     STR    a2,[lr,#0]
  759.     ADD    sl,a2,#256
  760.     LDMCSFD sp!,{a1,a2,pc}^
  761.     STMFD    sp!,{a3,a4,ip}
  762.     MOV    a1,#SIGEMT
  763.     BL    raise
  764.     LDMFD    sp!,{a3,a4,ip}
  765.     LDMFD    sp!,{a1,a2,pc}^
  766.  
  767.  
  768.     EXPORT    |_wr1chk|
  769.     EXPORT    |_wr2chk|
  770.     EXPORT    |_wr4chk|
  771. ; The following symbols are added so we can use UnixLib with C v.5
  772.     EXPORT    |__rt_wr1chk|
  773.     EXPORT    |__rt_wr2chk|
  774.     EXPORT    |__rt_wr4chk|
  775. |__rt_wr1chk|
  776. |_wr1chk|
  777.     BIC    a1,a1,#1    ; Ensure address is half word aligned
  778. |__rt_wr2chk|
  779. |_wr2chk|
  780.     TST    a1,#1
  781.     BNE    |__rwNsegv|
  782.     BIC    a1,a1,#2    ; Ensure address is full word aligned
  783.  
  784. |__rt_wr4chk|
  785. |_wr4chk|
  786.     TST    a1,#2
  787.     BNE    |__rwNsegv|
  788.  
  789.     LDR    a2,[pc,#|__rwbase_ptr|-.-8]
  790.     LDR    a2,[a2,#0]
  791.     B    |__rwNchk|
  792.  
  793.     EXPORT    |_rd1chk|
  794.     EXPORT    |_rd2chk|
  795.     EXPORT    |_rd4chk|
  796. ; The following symbols are added so we can use UnixLib with C v.5
  797.     EXPORT    |__rt_rd1chk|
  798.     EXPORT    |__rt_rd2chk|
  799.     EXPORT    |__rt_rd4chk|
  800.  
  801. |__rt_rd1chk|
  802. |_rd1chk|
  803.     BIC    a1,a1,#1 ; Ensure address is half word aligned
  804. |__rt_rd2chk|
  805. |_rd2chk|
  806.     TST    a1,#1
  807.     BNE    |__rwNsegv|
  808.     BIC    a1,a1,#2 ; Ensure address is full word aligned
  809. |__rt_rd4chk|
  810. |_rd4chk|
  811.     TST    a1,#2
  812.     BNE    |__rwNsegv|
  813.  
  814.     LDR    a2,[pc,#|__base_ptr|-.-8]
  815.     LDR    a2,[a2,#0]
  816. |__rwNchk|
  817.     CMP    a1,a2
  818.     BLO    |__rwNsegv|
  819.     LDR    a2,[pc,#|__break_ptr|-.-8]
  820.     LDR    a2,[a2,#0]
  821.     CMP    a1,a2
  822.     MOVLOS    pc,lr
  823.     LDR    a2,[pc,#|__stack_ptr|-.-8]
  824.     LDR    a2,[a2,#0]
  825.     CMP    a1,a2
  826.     BLO    |__rwNsegv|
  827.     LDR    a2,[pc,#|__himem_ptr|-.-8]
  828.     LDR    a2,[a2,#0]
  829.     CMP    a1,a2
  830.     MOVLOS    pc,lr
  831. |__rwNsegv|
  832.     MOV    a1,#SIGSEGV
  833.     B    raise
  834.  
  835.     EXPORT    |_count|
  836.  
  837.     NAME    _count
  838. |_count|
  839.     ADD    lr,lr,#8
  840.     MOVS    pc,lr
  841.  
  842.     EXPORT    |_count1|
  843.  
  844.     NAME    _count1
  845. |_count1|
  846.     ADD    lr,lr,#8
  847.     MOVS    pc,lr
  848.  
  849.     EXPORT    |__fptest|
  850. |__fptest|
  851.     ; Recognise the Floating Point facility by determining whether
  852.     ; the SWI FPEmulator_Version actually exists (and works).
  853.     ; If it does, then there is a floating point ability.
  854.     SWI    XFPEmulator_Version
  855.     MOVVS    a1, #0
  856.     MOVVC    a1, #1
  857.     LDR    a2, [pc, #|__fpflag_ptr| - . - 8]
  858.     STR    a1, [a2, #0]
  859.     MOVS    pc, lr
  860.  
  861. |__fpflag_ptr|
  862.     DCD    |__fpflag|
  863.  
  864.     AREA    |C$$data|,DATA
  865.  
  866.     EXPORT    |__dynamic_num|
  867. |__dynamic_num|
  868.     DCD    -1
  869. |__dynamic_deletion|
  870.     DCD    0
  871.     DCB    "XXXXXXXXXX"
  872. |__dynamic_area_name_end|
  873.     DCB    "_Heap", 0
  874.     ALIGN
  875.  
  876.     EXPORT    |__cli|        ; CLI from OS_GetEnv
  877. |__cli|
  878.     DCD    0
  879.  
  880.     EXPORT    |__base|    ; BASE (application = 0x8000)
  881. |__robase|
  882.     DCD    |Image$$RO$$Base|
  883. |__base|
  884.     DCD    0
  885.     EXPORT    |__lomem|    ; LOMEM
  886.     EXPORT    |__rwlimit|
  887. |__rwbase|
  888.     DCD    |Image$$RW$$Base|
  889. |__rwlimit|
  890.     DCD    |Image$$RW$$Limit|
  891. |__lomem|
  892.     DCD    0
  893.  
  894.     EXPORT    |__himem|    ; HIMEM from OS_GetEnv
  895. |__himem|
  896.     DCD    0
  897.  
  898.     EXPORT    |__break|    ; the 'break'
  899. |__break|
  900.     DCD    0
  901.  
  902.     EXPORT    |__stack|    ; stack limit
  903. |__stack|
  904.     DCD    0
  905.  
  906.     EXPORT    |__stack_limit|    ; lower stack limit
  907. |__stack_limit|
  908.     DCD    0
  909.  
  910.     EXPORT    |__time|    ; start time - 5 byte format
  911. |__time|
  912.     DCD    0        ; low word
  913.     DCD    0        ; high byte
  914.  
  915.     EXPORT    |__fpflag|
  916. |__fpflag|
  917.     DCD    0
  918.  
  919.     EXPORT    |__taskwindow|
  920.     ; Not zero if we are executing within a TaskWindow.
  921.     ; Set to 0 if we are not executing within a TaskWindow
  922. |__taskwindow|
  923.     DCD    0
  924.  
  925.     END
  926.