1 |
;------------------------------------------------------------------------------- |
2 |
;$Header: /home/dashley/cvsrep/uculib01/uculib01/src/stm8/cosmic/modx0/bas8absdiffboundedrxx/src/bas8absdiffboundedrxx.s,v 1.6 2010/03/21 04:50:34 dashley Exp $ |
3 |
;------------------------------------------------------------------------------- |
4 |
;Copyright (c)2010 David T. Ashley |
5 |
; |
6 |
;Permission is hereby granted, free of charge, to any person obtaining a copy |
7 |
;of this software source code and associated documentation files (the |
8 |
;"Software"), to deal in the Software without restriction, including without |
9 |
;limitation the rights to use, copy, modify, merge, publish, distribute, |
10 |
;sublicense, and/or sell copies of the Software, and to permit persons to whom |
11 |
;the Software is furnished to do so, subject to the following conditions: |
12 |
; |
13 |
;The above copyright notice and this permission notice shall be included in |
14 |
;all copies or substantial portions of the Software. |
15 |
; |
16 |
;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 |
;IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 |
;FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 |
;AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 |
;LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
21 |
;OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
22 |
;THE SOFTWARE. |
23 |
;------------------------------------------------------------------------------- |
24 |
;This function doesn't use any static storage, so it is OK for either mods0 or |
25 |
;modsl0 memory models. However, it does assume call/ret (rather than callf/retf) |
26 |
;which affects both instructions used, stack offsets, and numerical values in |
27 |
;the .dcall directive. For this reason, must error out if being assembled |
28 |
;for the wrong memory model. |
29 |
#ifndef UCU_BD_MMBP |
30 |
#error "Program memory model define not provided on command line (UCU_BD_MMBP)." |
31 |
#endif |
32 |
#if (UCU_BD_MMBP != 1) |
33 |
#error "Attempt to assemble module for wrong program memory model (UCU_BD_MMBP != 1)." |
34 |
#endif |
35 |
; |
36 |
switch .text |
37 |
xdef _UcuBaS8AbsDiffBoundedRxx |
38 |
; |
39 |
;Per discussion with Cosmic, the first integer is the stack space used by the |
40 |
;call instruction plus any automatic storage used by the function. The second integer |
41 |
;is the number of bytes stacked by the caller. Haven't yet discussed the scenario |
42 |
;of one assembly-language function called by another. I've noticed that some |
43 |
;assembly-language functions have a larger first integer than the stack they |
44 |
;used, so there may be a special convention if C calls .S which then calls .S, |
45 |
;as maybe the tools don't detect the .S calling the .S. Will need to investigate |
46 |
;further with Cosmic. |
47 |
; |
48 |
;2 bytes pushed on the stack by the CALL, 2 additional bytes pushed on the |
49 |
;stack by this function. |
50 |
.dcall "4,0,_UcuBaS8AbsDiffBoundedRxx" |
51 |
; |
52 |
_UcuBaS8AbsDiffBoundedRxx: |
53 |
;ARG1 is in XH, ARG2 is in XL. |
54 |
pushw x ;Must get X on the stack because SUB won't allow accumulator/register |
55 |
;subtracts, and there is no single-byte PUSH instruction to cover XL only. |
56 |
;After this, ARG1 is at (1,SP) and ARG2 is at (2,SP). |
57 |
ld a,xh ;Get ARG1 into A. |
58 |
sub a,(2,sp) ;Subtract ARG2. |
59 |
jrnv no_overflow ;No signed overflow, but it still might be -128. |
60 |
;---------- |
61 |
;Overflow. Overflow of a signed operation means the result is <-128 or >127. |
62 |
;In either case, the returned value must be 127. |
63 |
ld a,#127 |
64 |
popw x |
65 |
ret |
66 |
;---------- |
67 |
no_overflow: |
68 |
;---------- |
69 |
;If we have -128, this is too big to complement, so we have to map it to |
70 |
;127. |
71 |
cp a,#128 |
72 |
jrne in_range ;Not -128. |
73 |
ld a,#127 |
74 |
popw x |
75 |
ret |
76 |
;---------- |
77 |
;The difference is in [-127, 127]. We can use it as is if in [0,127], or safely |
78 |
;form the 2's complement. |
79 |
in_range: |
80 |
tnz a |
81 |
jrpl already_nonnegative ;Branch around if already nonnegative. |
82 |
neg a ;Forms the 2's complement. |
83 |
already_nonnegative: |
84 |
;Result is now in [0,127]. Just return it. |
85 |
popw x |
86 |
ret |
87 |
; |
88 |
end |
89 |
; |
90 |
;------------------------------------------------------------------------------- |
91 |
;End of $Id: bas8absdiffboundedrxx.s,v 1.6 2010/03/21 04:50:34 dashley Exp $ |
92 |
;------------------------------------------------------------------------------- |
93 |
;$Log: bas8absdiffboundedrxx.s,v $ |
94 |
;Revision 1.6 2010/03/21 04:50:34 dashley |
95 |
;Comments corrected. |
96 |
; |
97 |
;Revision 1.5 2010/03/18 15:08:15 dashley |
98 |
;Function renamed. |
99 |
; |
100 |
;Revision 1.4 2010/03/18 01:49:29 dashley |
101 |
;Cosmetic change. |
102 |
; |
103 |
;Revision 1.3 2010/03/17 21:49:08 dashley |
104 |
;Speed increased slightly at the expense of FLASH consumption by |
105 |
;eliminating branches. |
106 |
; |
107 |
;Revision 1.2 2010/03/17 21:41:23 dashley |
108 |
;Extra line removed. |
109 |
; |
110 |
;Revision 1.1 2010/03/17 21:40:58 dashley |
111 |
;Initial checkin. |
112 |
;------------------------------------------------------------------------------- |
113 |
|