Low memory ends at 640kB, not 1MB.
[AROS.git] / arch / m68k-all / dos / bcpl_writef.S
blobf1663d15d666e53634c0a02e28c1dc0845394964
1 /*
2     Copyright © 1995-2009, The AROS Development Team. All rights reserved.
3     $Id$
5     Desc: BCPL stubs that call into Exec and Dos libraries.
6     Lang: english
7 */
8 #define DEBUG 0
9 #include <aros/m68k/asm.h>
11 #include "bcpl.h"
13 #define BCPL(id,name)   .equ GV_##name, id
14 #include "bcpl.inc"
15 #undef BCPL
17 #define MAXARGS (1 + 26)        /* Up to 26 arguments to the format */
19         /* BCPL writef format strings:
20          * (case insensitive!)
21          *
22          * %S   - Send argument       to writes(BSTR)
23          * %Tn  - Send argument and n to writet(BSTR, n)
24          * %C   - Send argument       to wrch(LONG)
25          * %Bn  - Send argument and n to writebin(LONG, n)
26          * %On  - Send argument and n to writeoct(LONG, n)
27          * %Xn  - Send argument and n to writehex(LONG, n)
28          * %In  - Send argument and n to writei(LONG, n)
29          * %N   - Send argument       to writei(LONG, 0)
30          * %%   - Call wrch('%')
31          */
32         .text
33         .balign 4
34         .globl BCPL_writef
35 BCPL_writef:
36         /* Entry:
37          *   A0      - 0x00000000
38          *   A1[0]   - BSTR Format (also in D1)
39          *   A1[1..] - LONG Arguments
40          *   A2      - GlobVec
41          *   A5      - BCPL JSR
42          *   A6      - BCPL RTS
43          *   A7      - C stack pointer
44          */
45         movem.l %d2-%d7,%sp@-
47         move.l  %d1, %d6        /* D6 = Format pointer - 1 */
49 #if DEBUG
50         /* Dump format */
51         moveq   #'\'',%d1
52         move.l  #(3*4 + MAXARGS*4),%d0
53         move.l  %a2@(GV_wrch),%a4
54         jsr     (%a5)
55         move.l  %d6,%d1
56         move.l  #(3*4 + MAXARGS*4),%d0
57         move.l  %a2@(GV_writes),%a4
58         jsr     (%a5)
59         moveq   #'\'',%d1
60         move.l  #(3*4 + MAXARGS*4),%d0
61         move.l  %a2@(GV_wrch),%a4
62         jsr     (%a5)
63         move.l  #(3*4 + MAXARGS*4),%d0
64         move.l  %a2@(GV_newline),%a4
65         jsr     (%a5)
66 #endif
67      
68         lsl.l   #2, %d6
69         clr.l   %d5             /* D5 = Format Length */
70         move.b  %a0@(%d6), %d5
72     /* Zero length format - nothing to do */
73         tst     %d5             /* Done already? */
74         beq     .Lformat_exit
76         clr.l   %d4             /* D4 = Arg Index */
77 .Lformat_loop:
78         addq.l  #1, %d6         /* D6 = Format Pointer */
79         clr.l   %d7             /* D7 = Current char to test */
80         move.b  %a0@(%d6),%d7
81         cmp.b   #'%',%d7
82         bne     .Lformat_loop_wrch
84 .Lformat_loop_perc:     /* Seen a '%' sign */
85         addq.l  #1, %d6         /* D6 = Address of char after the '%' */
86         subq.l  #1, %d5         /* D5 = length - 1 */
87         move.b  %a0@(%d6),%d7   /* D7 = char after the '%' */
89         cmp.b   #'%',%d7        /* Handle '%%' */
90         beq     .Lformat_loop_wrch
92         bclr    #5,%d7          /* To Upper */
93 .Lformat_loop_switch:
95 .Lformat_loop_string:
96         cmp.b   #'S', %d7       /* Handle '%S' */
97         bne     0f
98         addq.l  #4,%d4
99         move.l  %a1@(%d4), %d1
100         move.l  #(3*4 + MAXARGS*4),%d0
101         move.l  %a2@(GV_writes),%a4
102         jsr     (%a5)
103         jmp     .Lformat_loop_next
106 .Lformat_loop_text:
107         cmp.b   #'T', %d7       /* Handle '%Tn' */
108         bne     0f
109         addq.l  #1, %d6         /* D6 = Address of char after the 'T' */
110         subq.l  #1, %d5         /* D5 = length - 1 */
111         addq.l  #4,%d4          /* D4 = Next argument */
112         move.l  %a1@(%d4), %d1  /* D1 = BSTR to print */
114         move.b  %a0@(%d6),%d7   /* D7 = char after the 'T' */
115         jsr     BCPL_writef_de36/* D2 = Base36 of D7 */
117         move.l  #(3*4 + MAXARGS*4),%d0
118         move.l  %a2@(GV_writet),%a4
119         jsr     (%a5)
120         jmp     .Lformat_loop_next
123 .Lformat_loop_char:
124         cmp.b   #'C', %d7       /* Handle '%C' */
125         bne     0f
126         addq.l  #4,%d4
127         move.l  %a1@(%d4), %d1
128         move.l  #(3*4 + MAXARGS*4),%d0
129         move.l  %a2@(GV_wrch),%a4
130         jsr     (%a5)
131         jmp     .Lformat_loop_next
134 .Lformat_loop_oct:
135         cmp.b   #'O', %d7       /* Handle '%On' */
136         bne     0f
137         addq.l  #1, %d6         /* D6 = Address of char after the '%' */
138         subq.l  #1, %d5         /* D5 = length - 1 */
139         move.b  %a0@(%d6),%d7   /* D7 = char after the 'O' */
140         jsr     BCPL_writef_de36/* D2 = Field width */
142         addq.l  #4,%d4          /* D4 = Next argument */
143         move.l  %a1@(%d4), %d1  /* D1 = LONG to print */
145         move.l  #(3*4 + MAXARGS*4),%d0
146         move.l  %a2@(GV_writeoct),%a4
147         jsr     (%a5)
148         jmp     .Lformat_loop_next
151 .Lformat_loop_hex:
152         cmp.b   #'X', %d7       /* Handle '%Xn' */
153         bne     0f
154         addq.l  #1, %d6         /* D6 = Address of char after the '%' */
155         subq.l  #1, %d5         /* D5 = length - 1 */
156         move.b  %a0@(%d6),%d7   /* D7 = char after the 'X' */
157         jsr     BCPL_writef_de36/* D2 = Field width */
159         addq.l  #4,%d4          /* D4 = Next argument */
160         move.l  %a1@(%d4), %d1  /* D1 = LONG to print */
162         move.l  #(3*4 + MAXARGS*4),%d0
163         move.l  %a2@(GV_writehex),%a4
164         jsr     (%a5)
165         jmp     .Lformat_loop_next
168 .Lformat_loop_integer:
169         cmp.b   #'I', %d7       /* Handle '%In' */
170         bne     0f
171         addq.l  #1, %d6         /* D6 = Address of char after the '%' */
172         subq.l  #1, %d5         /* D5 = length - 1 */
173         move.b  %a0@(%d6),%d7   /* D7 = char after the 'I' */
174         jsr     BCPL_writef_de36/* D2 = Field width */
176         addq.l  #4,%d4          /* D4 = Next argument */
177         move.l  %a1@(%d4), %d1  /* D1 = LONG to print */
179         move.l  #(3*4 + MAXARGS*4),%d0
180         move.l  %a2@(GV_writei),%a4
181         jsr     (%a5)
182         jmp     .Lformat_loop_next
185 .Lformat_loop_natural:
186         cmp.b   #'N', %d7       /* Handle '%N' */
187         bne     0f
188         addq.l  #4,%d4
189         move.l  %a1@(%d4), %d1
190         move.l  #(3*4 + MAXARGS*4),%d0
191         clr.l   %d2
192         move.l  %a2@(GV_writei),%a4
193         jsr     (%a5)
194         jmp     .Lformat_loop_next
197         /* Default: Write D7 via wrch */
198 .Lformat_loop_wrch:
199         move.l  %d7, %d1
200         move.l  #(3*4 + MAXARGS*4),%d0
201         move.l  %a2@(GV_wrch),%a4
202         jsr     (%a5)
203         jmp     .Lformat_loop_next
205 .Lformat_loop_next:
206         subq.l #1,%d5
207         bne .Lformat_loop
209 .Lformat_exit:
210         movem.l %sp@+,%d2-%d7
211         jmp     (%a6)
214 /* Helper functions */
216 /* In:  D7 '0'..'9','A'..'Z','a'..'z'
217    Out: D2 0..35
218  */
219 BCPL_writef_de36:
220         clr.l   %d2
221         move.b  %d7, %d2
222         subi.b  #'0',%d2
223         blt     .LBCPL_writef_de36_invalid
224         cmp.b   #9,%d2
225         ble     .LBCPL_writef_de36_exit
226         subi.b  #(('A'-'0')-10),%d2
227         blt     .LBCPL_writef_de36_invalid
228         cmp.b   #35,%d2
229         ble     .LBCPL_writef_de36_exit
230 .LBCPL_writef_de36_invalid:
231         clr.l   %d2
232 .LBCPL_writef_de36_exit:
233         rts