diff options
Diffstat (limited to 'tmk_core/common/avr/xprintf.S')
| -rw-r--r-- | tmk_core/common/avr/xprintf.S | 1000 |
1 files changed, 500 insertions, 500 deletions
diff --git a/tmk_core/common/avr/xprintf.S b/tmk_core/common/avr/xprintf.S index 0cec70ce2..06434b98d 100644 --- a/tmk_core/common/avr/xprintf.S +++ b/tmk_core/common/avr/xprintf.S | |||
| @@ -1,500 +1,500 @@ | |||
| 1 | ;---------------------------------------------------------------------------; | 1 | ;---------------------------------------------------------------------------; |
| 2 | ; Extended itoa, puts, printf and atoi (C)ChaN, 2011 | 2 | ; Extended itoa, puts, printf and atoi (C)ChaN, 2011 |
| 3 | ;---------------------------------------------------------------------------; | 3 | ;---------------------------------------------------------------------------; |
| 4 | 4 | ||
| 5 | // Base size is 152 bytes | 5 | // Base size is 152 bytes |
| 6 | #define CR_CRLF 0 // Convert \n to \r\n (+10 bytes) | 6 | #define CR_CRLF 0 // Convert \n to \r\n (+10 bytes) |
| 7 | #define USE_XPRINTF 1 // Enable xprintf function (+194 bytes) | 7 | #define USE_XPRINTF 1 // Enable xprintf function (+194 bytes) |
| 8 | #define USE_XSPRINTF 0 // Add xsprintf function (+78 bytes) | 8 | #define USE_XSPRINTF 0 // Add xsprintf function (+78 bytes) |
| 9 | #define USE_XFPRINTF 0 // Add xfprintf function (+54 bytes) | 9 | #define USE_XFPRINTF 0 // Add xfprintf function (+54 bytes) |
| 10 | #define USE_XATOI 0 // Enable xatoi function (+182 bytes) | 10 | #define USE_XATOI 0 // Enable xatoi function (+182 bytes) |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | #if FLASHEND > 0x1FFFF | 13 | #if FLASHEND > 0x1FFFF |
| 14 | #error xitoa module does not support 256K devices | 14 | #error xitoa module does not support 256K devices |
| 15 | #endif | 15 | #endif |
| 16 | 16 | ||
| 17 | .nolist | 17 | .nolist |
| 18 | #include <avr/io.h> // Include device specific definitions. | 18 | #include <avr/io.h> // Include device specific definitions. |
| 19 | .list | 19 | .list |
| 20 | 20 | ||
| 21 | #ifdef SPM_PAGESIZE // Recent devices have "lpm Rd,Z+" and "movw". | 21 | #ifdef SPM_PAGESIZE // Recent devices have "lpm Rd,Z+" and "movw". |
| 22 | .macro _LPMI reg | 22 | .macro _LPMI reg |
| 23 | lpm \reg, Z+ | 23 | lpm \reg, Z+ |
| 24 | .endm | 24 | .endm |
| 25 | .macro _MOVW dh,dl, sh,sl | 25 | .macro _MOVW dh,dl, sh,sl |
| 26 | movw \dl, \sl | 26 | movw \dl, \sl |
| 27 | .endm | 27 | .endm |
| 28 | #else // Earlier devices do not have "lpm Rd,Z+" nor "movw". | 28 | #else // Earlier devices do not have "lpm Rd,Z+" nor "movw". |
| 29 | .macro _LPMI reg | 29 | .macro _LPMI reg |
| 30 | lpm | 30 | lpm |
| 31 | mov \reg, r0 | 31 | mov \reg, r0 |
| 32 | adiw ZL, 1 | 32 | adiw ZL, 1 |
| 33 | .endm | 33 | .endm |
| 34 | .macro _MOVW dh,dl, sh,sl | 34 | .macro _MOVW dh,dl, sh,sl |
| 35 | mov \dl, \sl | 35 | mov \dl, \sl |
| 36 | mov \dh, \sh | 36 | mov \dh, \sh |
| 37 | .endm | 37 | .endm |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | 41 | ||
| 42 | ;--------------------------------------------------------------------------- | 42 | ;--------------------------------------------------------------------------- |
| 43 | ; Stub function to forward to user output function | 43 | ; Stub function to forward to user output function |
| 44 | ; | 44 | ; |
| 45 | ;Prototype: void xputc (char chr // a character to be output | 45 | ;Prototype: void xputc (char chr // a character to be output |
| 46 | ; ); | 46 | ; ); |
| 47 | ;Size: 12/12 words | 47 | ;Size: 12/12 words |
| 48 | 48 | ||
| 49 | .section .bss | 49 | .section .bss |
| 50 | .global xfunc_out ; xfunc_out must be initialized before using this module. | 50 | .global xfunc_out ; xfunc_out must be initialized before using this module. |
| 51 | xfunc_out: .ds.w 1 | 51 | xfunc_out: .ds.w 1 |
| 52 | .section .text | 52 | .section .text |
| 53 | 53 | ||
| 54 | 54 | ||
| 55 | .func xputc | 55 | .func xputc |
| 56 | .global xputc | 56 | .global xputc |
| 57 | xputc: | 57 | xputc: |
| 58 | #if CR_CRLF | 58 | #if CR_CRLF |
| 59 | cpi r24, 10 ;LF --> CRLF | 59 | cpi r24, 10 ;LF --> CRLF |
| 60 | brne 1f ; | 60 | brne 1f ; |
| 61 | ldi r24, 13 ; | 61 | ldi r24, 13 ; |
| 62 | rcall 1f ; | 62 | rcall 1f ; |
| 63 | ldi r24, 10 ;/ | 63 | ldi r24, 10 ;/ |
| 64 | 1: | 64 | 1: |
| 65 | #endif | 65 | #endif |
| 66 | push ZH | 66 | push ZH |
| 67 | push ZL | 67 | push ZL |
| 68 | lds ZL, xfunc_out+0 ;Pointer to the registered output function. | 68 | lds ZL, xfunc_out+0 ;Pointer to the registered output function. |
| 69 | lds ZH, xfunc_out+1 ;/ | 69 | lds ZH, xfunc_out+1 ;/ |
| 70 | sbiw ZL, 0 ;Skip if null | 70 | sbiw ZL, 0 ;Skip if null |
| 71 | breq 2f ;/ | 71 | breq 2f ;/ |
| 72 | icall | 72 | icall |
| 73 | 2: pop ZL | 73 | 2: pop ZL |
| 74 | pop ZH | 74 | pop ZH |
| 75 | ret | 75 | ret |
| 76 | .endfunc | 76 | .endfunc |
| 77 | 77 | ||
| 78 | 78 | ||
| 79 | 79 | ||
| 80 | ;--------------------------------------------------------------------------- | 80 | ;--------------------------------------------------------------------------- |
| 81 | ; Direct ROM string output | 81 | ; Direct ROM string output |
| 82 | ; | 82 | ; |
| 83 | ;Prototype: void xputs (const char *str_p // rom string to be output | 83 | ;Prototype: void xputs (const char *str_p // rom string to be output |
| 84 | ; ); | 84 | ; ); |
| 85 | 85 | ||
| 86 | .func xputs | 86 | .func xputs |
| 87 | .global xputs | 87 | .global xputs |
| 88 | xputs: | 88 | xputs: |
| 89 | _MOVW ZH,ZL, r25,r24 ; Z = pointer to rom string | 89 | _MOVW ZH,ZL, r25,r24 ; Z = pointer to rom string |
| 90 | 1: _LPMI r24 | 90 | 1: _LPMI r24 |
| 91 | cpi r24, 0 | 91 | cpi r24, 0 |
| 92 | breq 2f | 92 | breq 2f |
| 93 | rcall xputc | 93 | rcall xputc |
| 94 | rjmp 1b | 94 | rjmp 1b |
| 95 | 2: ret | 95 | 2: ret |
| 96 | .endfunc | 96 | .endfunc |
| 97 | 97 | ||
| 98 | 98 | ||
| 99 | ;--------------------------------------------------------------------------- | 99 | ;--------------------------------------------------------------------------- |
| 100 | ; Extended direct numeral string output (32bit version) | 100 | ; Extended direct numeral string output (32bit version) |
| 101 | ; | 101 | ; |
| 102 | ;Prototype: void xitoa (long value, // value to be output | 102 | ;Prototype: void xitoa (long value, // value to be output |
| 103 | ; char radix, // radix | 103 | ; char radix, // radix |
| 104 | ; char width); // minimum width | 104 | ; char width); // minimum width |
| 105 | ; | 105 | ; |
| 106 | 106 | ||
| 107 | .func xitoa | 107 | .func xitoa |
| 108 | .global xitoa | 108 | .global xitoa |
| 109 | xitoa: | 109 | xitoa: |
| 110 | ;r25:r22 = value, r20 = base, r18 = digits | 110 | ;r25:r22 = value, r20 = base, r18 = digits |
| 111 | clr r31 ;r31 = stack level | 111 | clr r31 ;r31 = stack level |
| 112 | ldi r30, ' ' ;r30 = sign | 112 | ldi r30, ' ' ;r30 = sign |
| 113 | ldi r19, ' ' ;r19 = filler | 113 | ldi r19, ' ' ;r19 = filler |
| 114 | sbrs r20, 7 ;When base indicates signd format and the value | 114 | sbrs r20, 7 ;When base indicates signd format and the value |
| 115 | rjmp 0f ;is minus, add a '-'. | 115 | rjmp 0f ;is minus, add a '-'. |
| 116 | neg r20 ; | 116 | neg r20 ; |
| 117 | sbrs r25, 7 ; | 117 | sbrs r25, 7 ; |
| 118 | rjmp 0f ; | 118 | rjmp 0f ; |
| 119 | ldi r30, '-' ; | 119 | ldi r30, '-' ; |
| 120 | com r22 ; | 120 | com r22 ; |
| 121 | com r23 ; | 121 | com r23 ; |
| 122 | com r24 ; | 122 | com r24 ; |
| 123 | com r25 ; | 123 | com r25 ; |
| 124 | adc r22, r1 ; | 124 | adc r22, r1 ; |
| 125 | adc r23, r1 ; | 125 | adc r23, r1 ; |
| 126 | adc r24, r1 ; | 126 | adc r24, r1 ; |
| 127 | adc r25, r1 ;/ | 127 | adc r25, r1 ;/ |
| 128 | 0: sbrs r18, 7 ;When digits indicates zero filled, | 128 | 0: sbrs r18, 7 ;When digits indicates zero filled, |
| 129 | rjmp 1f ;filler is '0'. | 129 | rjmp 1f ;filler is '0'. |
| 130 | neg r18 ; | 130 | neg r18 ; |
| 131 | ldi r19, '0' ;/ | 131 | ldi r19, '0' ;/ |
| 132 | ;----- string conversion loop | 132 | ;----- string conversion loop |
| 133 | 1: ldi r21, 32 ;r26 = r25:r22 % r20 | 133 | 1: ldi r21, 32 ;r26 = r25:r22 % r20 |
| 134 | clr r26 ;r25:r22 /= r20 | 134 | clr r26 ;r25:r22 /= r20 |
| 135 | 2: lsl r22 ; | 135 | 2: lsl r22 ; |
| 136 | rol r23 ; | 136 | rol r23 ; |
| 137 | rol r24 ; | 137 | rol r24 ; |
| 138 | rol r25 ; | 138 | rol r25 ; |
| 139 | rol r26 ; | 139 | rol r26 ; |
| 140 | cp r26, r20 ; | 140 | cp r26, r20 ; |
| 141 | brcs 3f ; | 141 | brcs 3f ; |
| 142 | sub r26, r20 ; | 142 | sub r26, r20 ; |
| 143 | inc r22 ; | 143 | inc r22 ; |
| 144 | 3: dec r21 ; | 144 | 3: dec r21 ; |
| 145 | brne 2b ;/ | 145 | brne 2b ;/ |
| 146 | cpi r26, 10 ;r26 is a numeral digit '0'-'F' | 146 | cpi r26, 10 ;r26 is a numeral digit '0'-'F' |
| 147 | brcs 4f ; | 147 | brcs 4f ; |
| 148 | subi r26, -7 ; | 148 | subi r26, -7 ; |
| 149 | 4: subi r26, -'0' ;/ | 149 | 4: subi r26, -'0' ;/ |
| 150 | push r26 ;Stack it | 150 | push r26 ;Stack it |
| 151 | inc r31 ;/ | 151 | inc r31 ;/ |
| 152 | cp r22, r1 ;Repeat until r25:r22 gets zero | 152 | cp r22, r1 ;Repeat until r25:r22 gets zero |
| 153 | cpc r23, r1 ; | 153 | cpc r23, r1 ; |
| 154 | cpc r24, r1 ; | 154 | cpc r24, r1 ; |
| 155 | cpc r25, r1 ; | 155 | cpc r25, r1 ; |
| 156 | brne 1b ;/ | 156 | brne 1b ;/ |
| 157 | 157 | ||
| 158 | cpi r30, '-' ;Minus sign if needed | 158 | cpi r30, '-' ;Minus sign if needed |
| 159 | brne 5f ; | 159 | brne 5f ; |
| 160 | push r30 ; | 160 | push r30 ; |
| 161 | inc r31 ;/ | 161 | inc r31 ;/ |
| 162 | 5: cp r31, r18 ;Filler | 162 | 5: cp r31, r18 ;Filler |
| 163 | brcc 6f ; | 163 | brcc 6f ; |
| 164 | push r19 ; | 164 | push r19 ; |
| 165 | inc r31 ; | 165 | inc r31 ; |
| 166 | rjmp 5b ;/ | 166 | rjmp 5b ;/ |
| 167 | 167 | ||
| 168 | 6: pop r24 ;Flush stacked digits and exit | 168 | 6: pop r24 ;Flush stacked digits and exit |
| 169 | rcall xputc ; | 169 | rcall xputc ; |
| 170 | dec r31 ; | 170 | dec r31 ; |
| 171 | brne 6b ;/ | 171 | brne 6b ;/ |
| 172 | 172 | ||
| 173 | ret | 173 | ret |
| 174 | .endfunc | 174 | .endfunc |
| 175 | 175 | ||
| 176 | 176 | ||
| 177 | 177 | ||
| 178 | ;---------------------------------------------------------------------------; | 178 | ;---------------------------------------------------------------------------; |
| 179 | ; Formatted string output (16/32bit version) | 179 | ; Formatted string output (16/32bit version) |
| 180 | ; | 180 | ; |
| 181 | ;Prototype: | 181 | ;Prototype: |
| 182 | ; void __xprintf (const char *format_p, ...); | 182 | ; void __xprintf (const char *format_p, ...); |
| 183 | ; void __xsprintf(char*, const char *format_p, ...); | 183 | ; void __xsprintf(char*, const char *format_p, ...); |
| 184 | ; void __xfprintf(void(*func)(char), const char *format_p, ...); | 184 | ; void __xfprintf(void(*func)(char), const char *format_p, ...); |
| 185 | ; | 185 | ; |
| 186 | 186 | ||
| 187 | #if USE_XPRINTF | 187 | #if USE_XPRINTF |
| 188 | 188 | ||
| 189 | .func xvprintf | 189 | .func xvprintf |
| 190 | xvprintf: | 190 | xvprintf: |
| 191 | ld ZL, Y+ ;Z = pointer to format string | 191 | ld ZL, Y+ ;Z = pointer to format string |
| 192 | ld ZH, Y+ ;/ | 192 | ld ZH, Y+ ;/ |
| 193 | 193 | ||
| 194 | 0: _LPMI r24 ;Get a format char | 194 | 0: _LPMI r24 ;Get a format char |
| 195 | cpi r24, 0 ;End of format string? | 195 | cpi r24, 0 ;End of format string? |
| 196 | breq 90f ;/ | 196 | breq 90f ;/ |
| 197 | cpi r24, '%' ;Is format? | 197 | cpi r24, '%' ;Is format? |
| 198 | breq 20f ;/ | 198 | breq 20f ;/ |
| 199 | 1: rcall xputc ;Put a normal character | 199 | 1: rcall xputc ;Put a normal character |
| 200 | rjmp 0b ;/ | 200 | rjmp 0b ;/ |
| 201 | 90: ret | 201 | 90: ret |
| 202 | 202 | ||
| 203 | 20: ldi r18, 0 ;r18: digits | 203 | 20: ldi r18, 0 ;r18: digits |
| 204 | clt ;T: filler | 204 | clt ;T: filler |
| 205 | _LPMI r21 ;Get flags | 205 | _LPMI r21 ;Get flags |
| 206 | cpi r21, '%' ;Is a %? | 206 | cpi r21, '%' ;Is a %? |
| 207 | breq 1b ;/ | 207 | breq 1b ;/ |
| 208 | cpi r21, '0' ;Zero filled? | 208 | cpi r21, '0' ;Zero filled? |
| 209 | brne 23f ; | 209 | brne 23f ; |
| 210 | set ;/ | 210 | set ;/ |
| 211 | 22: _LPMI r21 ;Get width | 211 | 22: _LPMI r21 ;Get width |
| 212 | 23: cpi r21, '9'+1 ; | 212 | 23: cpi r21, '9'+1 ; |
| 213 | brcc 24f ; | 213 | brcc 24f ; |
| 214 | subi r21, '0' ; | 214 | subi r21, '0' ; |
| 215 | brcs 90b ; | 215 | brcs 90b ; |
| 216 | lsl r18 ; | 216 | lsl r18 ; |
| 217 | mov r0, r18 ; | 217 | mov r0, r18 ; |
| 218 | lsl r18 ; | 218 | lsl r18 ; |
| 219 | lsl r18 ; | 219 | lsl r18 ; |
| 220 | add r18, r0 ; | 220 | add r18, r0 ; |
| 221 | add r18, r21 ; | 221 | add r18, r21 ; |
| 222 | rjmp 22b ;/ | 222 | rjmp 22b ;/ |
| 223 | 223 | ||
| 224 | 24: brtc 25f ;get value (low word) | 224 | 24: brtc 25f ;get value (low word) |
| 225 | neg r18 ; | 225 | neg r18 ; |
| 226 | 25: ld r24, Y+ ; | 226 | 25: ld r24, Y+ ; |
| 227 | ld r25, Y+ ;/ | 227 | ld r25, Y+ ;/ |
| 228 | cpi r21, 'c' ;Is type character? | 228 | cpi r21, 'c' ;Is type character? |
| 229 | breq 1b ;/ | 229 | breq 1b ;/ |
| 230 | cpi r21, 's' ;Is type RAM string? | 230 | cpi r21, 's' ;Is type RAM string? |
| 231 | breq 50f ;/ | 231 | breq 50f ;/ |
| 232 | cpi r21, 'S' ;Is type ROM string? | 232 | cpi r21, 'S' ;Is type ROM string? |
| 233 | breq 60f ;/ | 233 | breq 60f ;/ |
| 234 | _MOVW r23,r22,r25,r24 ;r25:r22 = value | 234 | _MOVW r23,r22,r25,r24 ;r25:r22 = value |
| 235 | clr r24 ; | 235 | clr r24 ; |
| 236 | clr r25 ; | 236 | clr r25 ; |
| 237 | clt ;/ | 237 | clt ;/ |
| 238 | cpi r21, 'l' ;Is long int? | 238 | cpi r21, 'l' ;Is long int? |
| 239 | brne 26f ; | 239 | brne 26f ; |
| 240 | ld r24, Y+ ;get value (high word) | 240 | ld r24, Y+ ;get value (high word) |
| 241 | ld r25, Y+ ; | 241 | ld r25, Y+ ; |
| 242 | set ; | 242 | set ; |
| 243 | _LPMI r21 ;/ | 243 | _LPMI r21 ;/ |
| 244 | 26: cpi r21, 'd' ;Is type signed decimal? | 244 | 26: cpi r21, 'd' ;Is type signed decimal? |
| 245 | brne 27f ;/ | 245 | brne 27f ;/ |
| 246 | ldi r20, -10 ; | 246 | ldi r20, -10 ; |
| 247 | brts 40f ; | 247 | brts 40f ; |
| 248 | sbrs r23, 7 ; | 248 | sbrs r23, 7 ; |
| 249 | rjmp 40f ; | 249 | rjmp 40f ; |
| 250 | ldi r24, -1 ; | 250 | ldi r24, -1 ; |
| 251 | ldi r25, -1 ; | 251 | ldi r25, -1 ; |
| 252 | rjmp 40f ;/ | 252 | rjmp 40f ;/ |
| 253 | 27: cpi r21, 'u' ;Is type unsigned decimal? | 253 | 27: cpi r21, 'u' ;Is type unsigned decimal? |
| 254 | ldi r20, 10 ; | 254 | ldi r20, 10 ; |
| 255 | breq 40f ;/ | 255 | breq 40f ;/ |
| 256 | cpi r21, 'X' ;Is type hexdecimal? | 256 | cpi r21, 'X' ;Is type hexdecimal? |
| 257 | ldi r20, 16 ; | 257 | ldi r20, 16 ; |
| 258 | breq 40f ;/ | 258 | breq 40f ;/ |
| 259 | cpi r21, 'b' ;Is type binary? | 259 | cpi r21, 'b' ;Is type binary? |
| 260 | ldi r20, 2 ; | 260 | ldi r20, 2 ; |
| 261 | breq 40f ;/ | 261 | breq 40f ;/ |
| 262 | ret ;abort | 262 | ret ;abort |
| 263 | 40: push ZH ;Output the value | 263 | 40: push ZH ;Output the value |
| 264 | push ZL ; | 264 | push ZL ; |
| 265 | rcall xitoa ; | 265 | rcall xitoa ; |
| 266 | 42: pop ZL ; | 266 | 42: pop ZL ; |
| 267 | pop ZH ; | 267 | pop ZH ; |
| 268 | rjmp 0b ;/ | 268 | rjmp 0b ;/ |
| 269 | 269 | ||
| 270 | 50: push ZH ;Put a string on the RAM | 270 | 50: push ZH ;Put a string on the RAM |
| 271 | push ZL | 271 | push ZL |
| 272 | _MOVW ZH,ZL, r25,r24 | 272 | _MOVW ZH,ZL, r25,r24 |
| 273 | 51: ld r24, Z+ | 273 | 51: ld r24, Z+ |
| 274 | cpi r24, 0 | 274 | cpi r24, 0 |
| 275 | breq 42b | 275 | breq 42b |
| 276 | rcall xputc | 276 | rcall xputc |
| 277 | rjmp 51b | 277 | rjmp 51b |
| 278 | 278 | ||
| 279 | 60: push ZH ;Put a string on the ROM | 279 | 60: push ZH ;Put a string on the ROM |
| 280 | push ZL | 280 | push ZL |
| 281 | rcall xputs | 281 | rcall xputs |
| 282 | rjmp 42b | 282 | rjmp 42b |
| 283 | .endfunc | 283 | .endfunc |
| 284 | 284 | ||
| 285 | 285 | ||
| 286 | .func __xprintf | 286 | .func __xprintf |
| 287 | .global __xprintf | 287 | .global __xprintf |
| 288 | __xprintf: | 288 | __xprintf: |
| 289 | push YH | 289 | push YH |
| 290 | push YL | 290 | push YL |
| 291 | in YL, _SFR_IO_ADDR(SPL) | 291 | in YL, _SFR_IO_ADDR(SPL) |
| 292 | #ifdef SPH | 292 | #ifdef SPH |
| 293 | in YH, _SFR_IO_ADDR(SPH) | 293 | in YH, _SFR_IO_ADDR(SPH) |
| 294 | #else | 294 | #else |
| 295 | clr YH | 295 | clr YH |
| 296 | #endif | 296 | #endif |
| 297 | adiw YL, 5 ;Y = pointer to arguments | 297 | adiw YL, 5 ;Y = pointer to arguments |
| 298 | rcall xvprintf | 298 | rcall xvprintf |
| 299 | pop YL | 299 | pop YL |
| 300 | pop YH | 300 | pop YH |
| 301 | ret | 301 | ret |
| 302 | .endfunc | 302 | .endfunc |
| 303 | 303 | ||
| 304 | 304 | ||
| 305 | #if USE_XSPRINTF | 305 | #if USE_XSPRINTF |
| 306 | 306 | ||
| 307 | .func __xsprintf | 307 | .func __xsprintf |
| 308 | putram: | 308 | putram: |
| 309 | _MOVW ZH,ZL, r15,r14 | 309 | _MOVW ZH,ZL, r15,r14 |
| 310 | st Z+, r24 | 310 | st Z+, r24 |
| 311 | _MOVW r15,r14, ZH,ZL | 311 | _MOVW r15,r14, ZH,ZL |
| 312 | ret | 312 | ret |
| 313 | .global __xsprintf | 313 | .global __xsprintf |
| 314 | __xsprintf: | 314 | __xsprintf: |
| 315 | push YH | 315 | push YH |
| 316 | push YL | 316 | push YL |
| 317 | in YL, _SFR_IO_ADDR(SPL) | 317 | in YL, _SFR_IO_ADDR(SPL) |
| 318 | #ifdef SPH | 318 | #ifdef SPH |
| 319 | in YH, _SFR_IO_ADDR(SPH) | 319 | in YH, _SFR_IO_ADDR(SPH) |
| 320 | #else | 320 | #else |
| 321 | clr YH | 321 | clr YH |
| 322 | #endif | 322 | #endif |
| 323 | adiw YL, 5 ;Y = pointer to arguments | 323 | adiw YL, 5 ;Y = pointer to arguments |
| 324 | lds ZL, xfunc_out+0 ;Save registered output function | 324 | lds ZL, xfunc_out+0 ;Save registered output function |
| 325 | lds ZH, xfunc_out+1 ; | 325 | lds ZH, xfunc_out+1 ; |
| 326 | push ZL ; | 326 | push ZL ; |
| 327 | push ZH ;/ | 327 | push ZH ;/ |
| 328 | ldi ZL, lo8(pm(putram));Set local output function | 328 | ldi ZL, lo8(pm(putram));Set local output function |
| 329 | ldi ZH, hi8(pm(putram)); | 329 | ldi ZH, hi8(pm(putram)); |
| 330 | sts xfunc_out+0, ZL ; | 330 | sts xfunc_out+0, ZL ; |
| 331 | sts xfunc_out+1, ZH ;/ | 331 | sts xfunc_out+1, ZH ;/ |
| 332 | push r15 ;Initialize pointer to string buffer | 332 | push r15 ;Initialize pointer to string buffer |
| 333 | push r14 ; | 333 | push r14 ; |
| 334 | ld r14, Y+ ; | 334 | ld r14, Y+ ; |
| 335 | ld r15, Y+ ;/ | 335 | ld r15, Y+ ;/ |
| 336 | rcall xvprintf | 336 | rcall xvprintf |
| 337 | _MOVW ZH,ZL, r15,r14 ;Terminate string | 337 | _MOVW ZH,ZL, r15,r14 ;Terminate string |
| 338 | st Z, r1 ; | 338 | st Z, r1 ; |
| 339 | pop r14 ; | 339 | pop r14 ; |
| 340 | pop r15 ;/ | 340 | pop r15 ;/ |
| 341 | pop ZH ;Restore registered output function | 341 | pop ZH ;Restore registered output function |
| 342 | pop ZL ; | 342 | pop ZL ; |
| 343 | sts xfunc_out+0, ZL ; | 343 | sts xfunc_out+0, ZL ; |
| 344 | sts xfunc_out+1, ZH ;/ | 344 | sts xfunc_out+1, ZH ;/ |
| 345 | pop YL | 345 | pop YL |
| 346 | pop YH | 346 | pop YH |
| 347 | ret | 347 | ret |
| 348 | .endfunc | 348 | .endfunc |
| 349 | #endif | 349 | #endif |
| 350 | 350 | ||
| 351 | 351 | ||
| 352 | #if USE_XFPRINTF | 352 | #if USE_XFPRINTF |
| 353 | .func __xfprintf | 353 | .func __xfprintf |
| 354 | .global __xfprintf | 354 | .global __xfprintf |
| 355 | __xfprintf: | 355 | __xfprintf: |
| 356 | push YH | 356 | push YH |
| 357 | push YL | 357 | push YL |
| 358 | in YL, _SFR_IO_ADDR(SPL) | 358 | in YL, _SFR_IO_ADDR(SPL) |
| 359 | #ifdef SPH | 359 | #ifdef SPH |
| 360 | in YH, _SFR_IO_ADDR(SPH) | 360 | in YH, _SFR_IO_ADDR(SPH) |
| 361 | #else | 361 | #else |
| 362 | clr YH | 362 | clr YH |
| 363 | #endif | 363 | #endif |
| 364 | adiw YL, 5 ;Y = pointer to arguments | 364 | adiw YL, 5 ;Y = pointer to arguments |
| 365 | lds ZL, xfunc_out+0 ;Save registered output function | 365 | lds ZL, xfunc_out+0 ;Save registered output function |
| 366 | lds ZH, xfunc_out+1 ; | 366 | lds ZH, xfunc_out+1 ; |
| 367 | push ZL ; | 367 | push ZL ; |
| 368 | push ZH ;/ | 368 | push ZH ;/ |
| 369 | ld ZL, Y+ ;Set output function | 369 | ld ZL, Y+ ;Set output function |
| 370 | ld ZH, Y+ ; | 370 | ld ZH, Y+ ; |
| 371 | sts xfunc_out+0, ZL ; | 371 | sts xfunc_out+0, ZL ; |
| 372 | sts xfunc_out+1, ZH ;/ | 372 | sts xfunc_out+1, ZH ;/ |
| 373 | rcall xvprintf | 373 | rcall xvprintf |
| 374 | pop ZH ;Restore registered output function | 374 | pop ZH ;Restore registered output function |
| 375 | pop ZL ; | 375 | pop ZL ; |
| 376 | sts xfunc_out+0, ZL ; | 376 | sts xfunc_out+0, ZL ; |
| 377 | sts xfunc_out+1, ZH ;/ | 377 | sts xfunc_out+1, ZH ;/ |
| 378 | pop YL | 378 | pop YL |
| 379 | pop YH | 379 | pop YH |
| 380 | ret | 380 | ret |
| 381 | .endfunc | 381 | .endfunc |
| 382 | #endif | 382 | #endif |
| 383 | 383 | ||
| 384 | #endif | 384 | #endif |
| 385 | 385 | ||
| 386 | 386 | ||
| 387 | 387 | ||
| 388 | ;--------------------------------------------------------------------------- | 388 | ;--------------------------------------------------------------------------- |
| 389 | ; Extended numeral string input | 389 | ; Extended numeral string input |
| 390 | ; | 390 | ; |
| 391 | ;Prototype: | 391 | ;Prototype: |
| 392 | ; char xatoi ( /* 1: Successful, 0: Failed */ | 392 | ; char xatoi ( /* 1: Successful, 0: Failed */ |
| 393 | ; const char **str, /* pointer to pointer to source string */ | 393 | ; const char **str, /* pointer to pointer to source string */ |
| 394 | ; long *res /* result */ | 394 | ; long *res /* result */ |
| 395 | ; ); | 395 | ; ); |
| 396 | ; | 396 | ; |
| 397 | 397 | ||
| 398 | 398 | ||
| 399 | #if USE_XATOI | 399 | #if USE_XATOI |
| 400 | .func xatoi | 400 | .func xatoi |
| 401 | .global xatoi | 401 | .global xatoi |
| 402 | xatoi: | 402 | xatoi: |
| 403 | _MOVW r1, r0, r23, r22 | 403 | _MOVW r1, r0, r23, r22 |
| 404 | _MOVW XH, XL, r25, r24 | 404 | _MOVW XH, XL, r25, r24 |
| 405 | ld ZL, X+ | 405 | ld ZL, X+ |
| 406 | ld ZH, X+ | 406 | ld ZH, X+ |
| 407 | clr r18 ;r21:r18 = 0; | 407 | clr r18 ;r21:r18 = 0; |
| 408 | clr r19 ; | 408 | clr r19 ; |
| 409 | clr r20 ; | 409 | clr r20 ; |
| 410 | clr r21 ;/ | 410 | clr r21 ;/ |
| 411 | clt ;T = 0; | 411 | clt ;T = 0; |
| 412 | 412 | ||
| 413 | ldi r25, 10 ;r25 = 10; | 413 | ldi r25, 10 ;r25 = 10; |
| 414 | rjmp 41f ;/ | 414 | rjmp 41f ;/ |
| 415 | 40: adiw ZL, 1 ;Z++; | 415 | 40: adiw ZL, 1 ;Z++; |
| 416 | 41: ld r22, Z ;r22 = *Z; | 416 | 41: ld r22, Z ;r22 = *Z; |
| 417 | cpi r22, ' ' ;if(r22 == ' ') continue | 417 | cpi r22, ' ' ;if(r22 == ' ') continue |
| 418 | breq 40b ;/ | 418 | breq 40b ;/ |
| 419 | brcs 70f ;if(r22 < ' ') error; | 419 | brcs 70f ;if(r22 < ' ') error; |
| 420 | cpi r22, '-' ;if(r22 == '-') { | 420 | cpi r22, '-' ;if(r22 == '-') { |
| 421 | brne 42f ; T = 1; | 421 | brne 42f ; T = 1; |
| 422 | set ; continue; | 422 | set ; continue; |
| 423 | rjmp 40b ;} | 423 | rjmp 40b ;} |
| 424 | 42: cpi r22, '9'+1 ;if(r22 > '9') error; | 424 | 42: cpi r22, '9'+1 ;if(r22 > '9') error; |
| 425 | brcc 70f ;/ | 425 | brcc 70f ;/ |
| 426 | cpi r22, '0' ;if(r22 < '0') error; | 426 | cpi r22, '0' ;if(r22 < '0') error; |
| 427 | brcs 70f ;/ | 427 | brcs 70f ;/ |
| 428 | brne 51f ;if(r22 > '0') cv_start; | 428 | brne 51f ;if(r22 > '0') cv_start; |
| 429 | ldi r25, 8 ;r25 = 8; | 429 | ldi r25, 8 ;r25 = 8; |
| 430 | adiw ZL, 1 ;r22 = *(++Z); | 430 | adiw ZL, 1 ;r22 = *(++Z); |
| 431 | ld r22, Z ;/ | 431 | ld r22, Z ;/ |
| 432 | cpi r22, ' '+1 ;if(r22 <= ' ') exit; | 432 | cpi r22, ' '+1 ;if(r22 <= ' ') exit; |
| 433 | brcs 80f ;/ | 433 | brcs 80f ;/ |
| 434 | cpi r22, 'b' ;if(r22 == 'b') { | 434 | cpi r22, 'b' ;if(r22 == 'b') { |
| 435 | brne 43f ; r25 = 2; | 435 | brne 43f ; r25 = 2; |
| 436 | ldi r25, 2 ; cv_start; | 436 | ldi r25, 2 ; cv_start; |
| 437 | rjmp 50f ;} | 437 | rjmp 50f ;} |
| 438 | 43: cpi r22, 'x' ;if(r22 != 'x') error; | 438 | 43: cpi r22, 'x' ;if(r22 != 'x') error; |
| 439 | brne 51f ;/ | 439 | brne 51f ;/ |
| 440 | ldi r25, 16 ;r25 = 16; | 440 | ldi r25, 16 ;r25 = 16; |
| 441 | 441 | ||
| 442 | 50: adiw ZL, 1 ;Z++; | 442 | 50: adiw ZL, 1 ;Z++; |
| 443 | ld r22, Z ;r22 = *Z; | 443 | ld r22, Z ;r22 = *Z; |
| 444 | 51: cpi r22, ' '+1 ;if(r22 <= ' ') break; | 444 | 51: cpi r22, ' '+1 ;if(r22 <= ' ') break; |
| 445 | brcs 80f ;/ | 445 | brcs 80f ;/ |
| 446 | cpi r22, 'a' ;if(r22 >= 'a') r22 =- 0x20; | 446 | cpi r22, 'a' ;if(r22 >= 'a') r22 =- 0x20; |
| 447 | brcs 52f ; | 447 | brcs 52f ; |
| 448 | subi r22, 0x20 ;/ | 448 | subi r22, 0x20 ;/ |
| 449 | 52: subi r22, '0' ;if((r22 -= '0') < 0) error; | 449 | 52: subi r22, '0' ;if((r22 -= '0') < 0) error; |
| 450 | brcs 70f ;/ | 450 | brcs 70f ;/ |
| 451 | cpi r22, 10 ;if(r22 >= 10) { | 451 | cpi r22, 10 ;if(r22 >= 10) { |
| 452 | brcs 53f ; r22 -= 7; | 452 | brcs 53f ; r22 -= 7; |
| 453 | subi r22, 7 ; if(r22 < 10) | 453 | subi r22, 7 ; if(r22 < 10) |
| 454 | cpi r22, 10 ; | 454 | cpi r22, 10 ; |
| 455 | brcs 70f ;} | 455 | brcs 70f ;} |
| 456 | 53: cp r22, r25 ;if(r22 >= r25) error; | 456 | 53: cp r22, r25 ;if(r22 >= r25) error; |
| 457 | brcc 70f ;/ | 457 | brcc 70f ;/ |
| 458 | 60: ldi r24, 33 ;r21:r18 *= r25; | 458 | 60: ldi r24, 33 ;r21:r18 *= r25; |
| 459 | sub r23, r23 ; | 459 | sub r23, r23 ; |
| 460 | 61: brcc 62f ; | 460 | 61: brcc 62f ; |
| 461 | add r23, r25 ; | 461 | add r23, r25 ; |
| 462 | 62: lsr r23 ; | 462 | 62: lsr r23 ; |
| 463 | ror r21 ; | 463 | ror r21 ; |
| 464 | ror r20 ; | 464 | ror r20 ; |
| 465 | ror r19 ; | 465 | ror r19 ; |
| 466 | ror r18 ; | 466 | ror r18 ; |
| 467 | dec r24 ; | 467 | dec r24 ; |
| 468 | brne 61b ;/ | 468 | brne 61b ;/ |
| 469 | add r18, r22 ;r21:r18 += r22; | 469 | add r18, r22 ;r21:r18 += r22; |
| 470 | adc r19, r24 ; | 470 | adc r19, r24 ; |
| 471 | adc r20, r24 ; | 471 | adc r20, r24 ; |
| 472 | adc r21, r24 ;/ | 472 | adc r21, r24 ;/ |
| 473 | rjmp 50b ;repeat | 473 | rjmp 50b ;repeat |
| 474 | 474 | ||
| 475 | 70: ldi r24, 0 | 475 | 70: ldi r24, 0 |
| 476 | rjmp 81f | 476 | rjmp 81f |
| 477 | 80: ldi r24, 1 | 477 | 80: ldi r24, 1 |
| 478 | 81: brtc 82f | 478 | 81: brtc 82f |
| 479 | clr r22 | 479 | clr r22 |
| 480 | com r18 | 480 | com r18 |
| 481 | com r19 | 481 | com r19 |
| 482 | com r20 | 482 | com r20 |
| 483 | com r21 | 483 | com r21 |
| 484 | adc r18, r22 | 484 | adc r18, r22 |
| 485 | adc r19, r22 | 485 | adc r19, r22 |
| 486 | adc r20, r22 | 486 | adc r20, r22 |
| 487 | adc r21, r22 | 487 | adc r21, r22 |
| 488 | 82: st -X, ZH | 488 | 82: st -X, ZH |
| 489 | st -X, ZL | 489 | st -X, ZL |
| 490 | _MOVW XH, XL, r1, r0 | 490 | _MOVW XH, XL, r1, r0 |
| 491 | st X+, r18 | 491 | st X+, r18 |
| 492 | st X+, r19 | 492 | st X+, r19 |
| 493 | st X+, r20 | 493 | st X+, r20 |
| 494 | st X+, r21 | 494 | st X+, r21 |
| 495 | clr r1 | 495 | clr r1 |
| 496 | ret | 496 | ret |
| 497 | .endfunc | 497 | .endfunc |
| 498 | #endif | 498 | #endif |
| 499 | 499 | ||
| 500 | 500 | ||
