]> git.gag.com Git - fw/sdcc/blob - device/lib/ds400/ds400rom.c
More support for DS80C400
[fw/sdcc] / device / lib / ds400 / ds400rom.c
1 // Interface to the DS80C400 ROM functions. Largely based on code released
2 // by Dallas, hence the following copyright.
3
4 // ---------------------------------------------------------------------------
5 //  Copyright (C) 2003 Dallas Semiconductor Corporation, All Rights Reserved.
6 // 
7 //  Permission is hereby granted, free of charge, to any person obtaining a
8 //  copy of this software and associated documentation files (the "Software"),
9 //  to deal in the Software without restriction, including without limitation
10 //  the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 //  and/or sell copies of the Software, and to permit persons to whom the
12 //  Software is furnished to do so, subject to the following conditions:
13 //
14 //  The above copyright notice and this permission notice shall be included
15 //  in all copies or substantial portions of the Software.
16 //
17 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 //  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 //  MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 //  IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
21 //  OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 //  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 //  OTHER DEALINGS IN THE SOFTWARE.
24 //
25 //  Except as contained in this notice, the name of Dallas Semiconductor
26 //  shall not be used except as stated in the Dallas Semiconductor
27 //  Branding Policy.
28 // ---------------------------------------------------------------------------
29
30 #include <stdio.h>
31 #include <ds400rom.h>
32
33 // Register bank 3 equates.
34 #define R0_B3     0x18
35 #define R1_B3     0x19
36 #define R2_B3     0x1A
37 #define R3_B3     0x1B
38 #define R4_B3     0x1C
39 #define R5_B3     0x1D
40 #define R6_B3     0x1E
41 #define R7_B3     0x1F
42
43
44 // The bank the ROM is stored in.  Should be 0FFh for production
45 // 400's.  Change this value when running with a debug ROM.
46
47 #define ROM_BANK        0xFF
48
49 // The address of the ROM export table is stored
50 // at (ROM_BANK << 16) | ROM_EXPORTTABLE_OFFS
51
52 #define ROM_EXPORTTABLE_OFFS    2
53
54 //
55 // Each entry in the ROM export table is 3 bytes.
56 //
57 #define ROMXT_ENTRYSIZE      3
58
59 //
60 // The number of functions in the ROM export table is stored
61 // first in the export table.
62 //
63 #define ROMXT_NUMFUNCTIONS     (0 * ROMXT_ENTRYSIZE)
64
65 //
66 // ROM EXPORT TABLE FUNCTIONS (denoted with ROMXT)
67 //
68
69 // UTILITY functions 
70 #define ROMXT_CRC16                     (1 * ROMXT_ENTRYSIZE) //
71 #define ROMXT_MEM_CLEAR_16              (2 * ROMXT_ENTRYSIZE) //
72 #define ROMXT_MEM_COPY_16               (3 * ROMXT_ENTRYSIZE) //
73 #define ROMXT_MEM_COMPARE               (4 * ROMXT_ENTRYSIZE) //
74 #define ROMXT_ADD_DPTR1_16              (5 * ROMXT_ENTRYSIZE) // not implemented for C compiler
75 #define ROMXT_ADD_DPTR2_16              (6 * ROMXT_ENTRYSIZE) // not implemented for C compiler
76 #define ROMXT_SUB_DPTR1_16              (7 * ROMXT_ENTRYSIZE) // not implemented for C compiler
77 #define ROMXT_SUB_DPTR2_16              (8 * ROMXT_ENTRYSIZE) // not implemented for C compiler
78 #define ROMXT_GETPSEUDORANDOM           (9 * ROMXT_ENTRYSIZE) //
79
80 // MEMORY MGR
81 #define ROMXT_KERNELMALLOC              (10 * ROMXT_ENTRYSIZE) // not exposed
82 #define ROMXT_KERNELFREE                (11 * ROMXT_ENTRYSIZE) // not exposed
83 #define ROMXT_MM_MALLOC                 (12 * ROMXT_ENTRYSIZE) // exposed as redirected function
84 #define ROMXT_MM_MALLOC_DIRTY           (13 * ROMXT_ENTRYSIZE) // exposed as redirected function
85 #define ROMXT_MM_FREE                   (14 * ROMXT_ENTRYSIZE) // exposed as redirected function
86 #define ROMXT_MM_DEREF                  (15 * ROMXT_ENTRYSIZE) // exposed as redirected function
87 #define ROMXT_GETFREERAM                (16 * ROMXT_ENTRYSIZE) // exposed as redirected function
88
89 // SOCKET functions
90 #define ROMXT_ROM_SOCKET                (17 * ROMXT_ENTRYSIZE) //
91 #define ROMXT_ROM_CLOSESOCKET           (18 * ROMXT_ENTRYSIZE) //
92 #define ROMXT_ROM_SENDTO                (19 * ROMXT_ENTRYSIZE) //
93 #define ROMXT_ROM_RECVFROM              (20 * ROMXT_ENTRYSIZE) //
94 #define ROMXT_ROM_CONNECT               (21 * ROMXT_ENTRYSIZE) //
95 #define ROMXT_ROM_BIND                  (22 * ROMXT_ENTRYSIZE) //
96 #define ROMXT_ROM_LISTEN                (23 * ROMXT_ENTRYSIZE) //
97 #define ROMXT_ROM_ACCEPT                (24 * ROMXT_ENTRYSIZE) //
98 #define ROMXT_ROM_RECV                  (25 * ROMXT_ENTRYSIZE) //
99 #define ROMXT_ROM_SEND                  (26 * ROMXT_ENTRYSIZE) //
100 #define ROMXT_ROM_GETSOCKOPT            (27 * ROMXT_ENTRYSIZE) //
101 #define ROMXT_ROM_SETSOCKOPT            (28 * ROMXT_ENTRYSIZE) //
102 #define ROMXT_ROM_GETSOCKNAME           (29 * ROMXT_ENTRYSIZE) //
103 #define ROMXT_ROM_GETPEERNAME           (30 * ROMXT_ENTRYSIZE) //
104 #define ROMXT_ROM_CLEANUP               (31 * ROMXT_ENTRYSIZE) //
105 #define ROMXT_ROM_AVAIL                 (32 * ROMXT_ENTRYSIZE) //
106 #define ROMXT_ROM_JOIN                  (33 * ROMXT_ENTRYSIZE) //
107 #define ROMXT_ROM_LEAVE                 (34 * ROMXT_ENTRYSIZE) //
108 #define ROMXT_ROM_PING                  (35 * ROMXT_ENTRYSIZE) //
109 #define ROMXT_ROM_GETNETWORKPARAMS      (36 * ROMXT_ENTRYSIZE) //
110 #define ROMXT_ROM_SETNETWORKPARAMS      (37 * ROMXT_ENTRYSIZE) //
111 #define ROMXT_ROM_GETIPV6PARAMS         (38 * ROMXT_ENTRYSIZE) //
112 #define ROMXT_ROM_GETETHERNETSTATUS     (39 * ROMXT_ENTRYSIZE) //
113 #define ROMXT_ROM_GETTFTPSERVER         (40 * ROMXT_ENTRYSIZE) //
114 #define ROMXT_ROM_SETTFTPSERVER         (41 * ROMXT_ENTRYSIZE) //
115 #define ROMXT_ETH_PROCESSINTERRUPT      (42 * ROMXT_ENTRYSIZE) // not implemented for C compiler
116 #define ROMXT_ARP_GENERATEREQUEST       (43 * ROMXT_ENTRYSIZE) // not implemented for C compiler
117 #define ROMXT_NET_ETH0_MAC_ID           (44 * ROMXT_ENTRYSIZE) //
118
119 // DHCP functions
120 #define ROMXT_DHCP_INIT                 (45 * ROMXT_ENTRYSIZE) //
121 #define ROMXT_DHCP_SETUP                (46 * ROMXT_ENTRYSIZE) // not implemented for C compiler
122 #define ROMXT_DHCP_STARTUP              (47 * ROMXT_ENTRYSIZE) // not implemented for C compiler
123 #define ROMXT_DHCP_RUN                  (48 * ROMXT_ENTRYSIZE) // not implemented for C compiler
124 #define ROMXT_DHCP_STATUS               (49 * ROMXT_ENTRYSIZE) //
125 #define ROMXT_DHCP_STOP                 (50 * ROMXT_ENTRYSIZE) //
126 #define ROMXT_DHCPNOTIFY                (51 * ROMXT_ENTRYSIZE) // empty redirect stub, not implemented
127
128 // TFTP functions
129 #define ROMXT_TFTP_INIT                 (52 * ROMXT_ENTRYSIZE) //
130 #define ROMXT_TFTP_FIRST                (53 * ROMXT_ENTRYSIZE) //
131 #define ROMXT_TFTP_NEXT                 (54 * ROMXT_ENTRYSIZE) //
132 #define ROMXT_TFTP_MSG                  (55 * ROMXT_ENTRYSIZE) //
133
134 // SCHEDULER functions
135 #define ROMXT_TASK_GENESIS              (56 * ROMXT_ENTRYSIZE) //
136 #define ROMXT_TASK_GETCURRENT           (57 * ROMXT_ENTRYSIZE) //
137 #define ROMXT_TASK_GETPRIORITY          (58 * ROMXT_ENTRYSIZE) //
138 #define ROMXT_TASK_SETPRIORITY          (59 * ROMXT_ENTRYSIZE) //
139 #define ROMXT_TASK_FORK                 (60 * ROMXT_ENTRYSIZE) //
140 #define ROMXT_TASK_KILL                 (61 * ROMXT_ENTRYSIZE) //
141 #define ROMXT_TASK_SUSPEND              (62 * ROMXT_ENTRYSIZE) //
142 #define ROMXT_TASK_SLEEP                (63 * ROMXT_ENTRYSIZE) //
143 #define ROMXT_TASK_SIGNAL               (64 * ROMXT_ENTRYSIZE) //
144 #define ROMXT_ROM_TASK_SWITCH_IN        (65 * ROMXT_ENTRYSIZE) // empty redirect stub, not implemented
145 #define ROMXT_ROM_TASK_SWITCH_OUT       (66 * ROMXT_ENTRYSIZE) // empty redirect stub, not implemented
146 #define ROMXT_ENTERCRITSECTION          (67 * ROMXT_ENTRYSIZE) //
147 #define ROMXT_LEAVECRITSECTION          (68 * ROMXT_ENTRYSIZE) //
148
149 // INIT functions
150 #define ROMXT_ROM_INIT                  (69 * ROMXT_ENTRYSIZE) //
151 #define ROMXT_ROM_COPYIVT               (70 * ROMXT_ENTRYSIZE) //
152 #define ROMXT_ROM_REDIRECT_INIT         (71 * ROMXT_ENTRYSIZE) //
153 #define ROMXT_MM_INIT                   (72 * ROMXT_ENTRYSIZE) //
154 #define ROMXT_KM_INIT                   (73 * ROMXT_ENTRYSIZE) //
155 #define ROMXT_OW_INIT                   (74 * ROMXT_ENTRYSIZE) //
156 #define ROMXT_NETWORK_INIT              (75 * ROMXT_ENTRYSIZE) //
157 #define ROMXT_ETH_INIT                  (76 * ROMXT_ENTRYSIZE) //
158 #define ROMXT_INIT_SOCKETS              (77 * ROMXT_ENTRYSIZE) //
159 #define ROMXT_TICK_INIT                 (78 * ROMXT_ENTRYSIZE) //
160
161 // Timer Interrupt vectors
162 #define ROMXT_WOS_TICK                  (79 * ROMXT_ENTRYSIZE) // not implemented for C compiler
163 #define ROMXT_BLOB                      (80 * ROMXT_ENTRYSIZE) // not implemented for C compiler
164
165 // Maintenance functions
166 #define ROMXT_WOS_IOPOLL                (81 * ROMXT_ENTRYSIZE) // not implemented for C compiler
167 #define ROMXT_IP_PROCESSRECEIVEQUEUES   (82 * ROMXT_ENTRYSIZE) // not implemented for C compiler
168 #define ROMXT_IP_PROCESSOUTPUT          (83 * ROMXT_ENTRYSIZE) // not implemented for C compiler
169 #define ROMXT_TCP_RETRYTOP              (84 * ROMXT_ENTRYSIZE) // not implemented for C compiler
170 #define ROMXT_ETH_PROCESSOUTPUT         (85 * ROMXT_ENTRYSIZE) // not implemented for C compiler
171 #define ROMXT_IGMP_GROUPMAINTAINENCE    (86 * ROMXT_ENTRYSIZE) // not implemented for C compiler
172 #define ROMXT_IP6_PROCESSRECEIVEQUEUES  (87 * ROMXT_ENTRYSIZE) // not implemented for C compiler
173 #define ROMXT_IP6_PROCESSOUTPUT         (88 * ROMXT_ENTRYSIZE) // not implemented for C compiler
174 #define ROMXT_PARAMBUFFER               (89 * ROMXT_ENTRYSIZE) // not implemented for C compiler
175 #define ROMXT_RAM_TOP                   (90 * ROMXT_ENTRYSIZE) // not implemented for C compiler
176 #define ROMXT_BOOT_MEMBEGIN             (91 * ROMXT_ENTRYSIZE) // not implemented for C compiler
177 #define ROMXT_BOOT_MEMEND               (92 * ROMXT_ENTRYSIZE) // not implemented for C compiler
178
179 // 1-Wire
180 #define ROMXT_OWM_FIRST                 (93 * ROMXT_ENTRYSIZE) //
181 #define ROMXT_OWM_NEXT                  (94 * ROMXT_ENTRYSIZE) //
182 #define ROMXT_OWM_RESET                 (95 * ROMXT_ENTRYSIZE) //
183 #define ROMXT_OWM_BYTE                  (96 * ROMXT_ENTRYSIZE) //
184 #define ROMXT_OWM_SEARCH                (97 * ROMXT_ENTRYSIZE) // not implemented for C compiler
185 #define ROMXT_OW_ROMID                  (98 * ROMXT_ENTRYSIZE) //
186
187 // Misc, extras, late additions
188 #define ROMXT_AUTOBAUD                  (99 * ROMXT_ENTRYSIZE)
189 #define ROMXT_TFTP_CLOSE                (100 * ROMXT_ENTRYSIZE)
190
191 #define GETC            \
192     clr  a              \
193     movc a, @a+dptr
194     
195
196 // expects function number in R6_B3 (low byte) & R7_B3 (high byte)
197 void _romcall(void) _naked
198 {
199 _asm    
200       push  dpx                               ; dptr0 preserved here
201       push  dph
202       push  dpl
203
204       ; point to the address of the table               
205       mov   dptr, #(ROM_BANK << 16 | ROM_EXPORTTABLE_OFFS)
206
207       push  acc                               ; acc preserved here
208       push  b                                 ; b preserved here
209       inc   dptr
210       GETC                                    ; get the address of the table
211       push  acc
212       inc   dptr
213       GETC
214       add   a, R6_B3                          ; add function offset to the table
215       mov   dpl, a
216       pop   acc
217       addc  a, R7_B3
218       mov   dph, a
219
220       ;
221       ; dpx is the same, all in the same bank
222       ;
223       inc   dptr                              ; get the target address of the function we want
224       GETC
225       mov   b, a
226       inc   dptr
227       GETC
228       mov   R3_B3, a
229       mov   R4_B3, b
230       mov   R5_B3, dpx                        ; high byte does not change
231       pop   b                                 ; b restored here
232       pop   acc                               ; acc restored here
233       pop   dpl                               ; dptr0 preserved here
234       pop   dph
235       pop   dpx
236       push  R3_B3                             ; push the target address
237       push  R4_B3
238       push  R5_B3
239       ret                                     ; this is not a ret, it is a call!
240         
241       ; the called function ends with a ret which will return to our original caller.
242 _endasm ;
243 }
244
245 // This macro is invalid for the standard C preprocessor, since it
246 // includes a hash character in the expansion, hence the SDCC specific
247 // pragma.
248 #pragma sdcc_hash +
249 #define ROMCALL(x) \
250         mov     R6_B3, #(x & 0xff)              \
251         mov     R7_B3, #((x >> 8) & 0xff)       \
252         lcall   __romcall
253
254
255 // rom_init: the ds400 ROM_INIT ROM function.
256 unsigned char rom_init(void xdata *loMem,
257                        void xdata *hiMem) _naked
258 {    
259     // shut compiler up about unused parameters.
260     loMem;
261     hiMem;
262     
263 _asm
264         ; load params.
265         ; loMem is already in DPTR.
266         mov     r2, dpx
267         mov     r1, dph
268         mov     r0, dpl
269         ; hiMem is in _rom_init_PARM_2
270         mov     dptr, #_rom_init_PARM_2
271         mov     r5, dpx
272         mov     r4, dph
273         mov     r3, dpl
274
275         ROMCALL(ROMXT_ROM_INIT)
276
277         ; result is in acc, move to dpl for C convention.
278         mov     dpl, a
279         ret
280 _endasm ;
281 }
282
283 // all other ROM functions should go here, using rom_init as a template...
284
285 // Various utility functions.
286
287 // Return the start of the XI_SEG. Really just a workaround for the
288 // fact that the linker defined symbol (s_XISEG) isn't directly accessible
289 // from C due to the lack of a leading underscore, and I'm too lazy to hack 
290 // the linker.
291 static void xdata *_xisegStart(void) _naked
292 {
293 _asm    
294         mov     dptr, #(s_XISEG)
295         ret
296 _endasm;
297 }
298
299 // Return the length of the XI_SEG. Really just a workaround for the
300 // fact that the linker defined symbol (l_XISEG) isn't directly accessible
301 // from C due to the lack of a leading underscore, and I'm too lazy to hack 
302 // the linker.
303 static unsigned  _xisegLen(void) _naked
304 {
305 _asm    
306         mov     dptr, #(l_XISEG)
307         ret
308 _endasm;
309 }
310
311 // Returns the address of the first byte available for heap memory, 
312 // i.e. the first byte following the XI_SEG.
313 static void xdata *_firstHeapByte(void)
314 {
315     unsigned char xdata *start;
316     
317     start = (unsigned char xdata *) _xisegStart();      
318     start += _xisegLen();
319
320     return (void xdata *)start;
321 }
322
323 // A simple wrapper for ROM_INIT which allocates all available RAM in the CE0 area
324 // to the heap.
325
326 // The last addressible byte of the CE0 area. 
327 #define CE0_END 0xfffff
328
329 unsigned char romInit(unsigned char noisy)
330 {
331     void xdata *heapStart;
332     void xdata *heapEnd;
333     unsigned long heapLen; 
334     unsigned char rc;
335     
336     heapStart = _firstHeapByte();
337     heapEnd = (void xdata *)CE0_END;
338
339     rc = rom_init(heapStart, heapEnd);
340     
341     if (noisy)
342     {
343         if (rc)
344         {
345             printf("error: rom_init returns %d\n", (int)rc);
346         }
347         else
348         {
349             heapLen = CE0_END - (unsigned long)heapStart;
350             printf("Heap starts at %p, length %luK\n", heapStart, heapLen / 1024);
351         }
352     }
353     return rc;
354 }
355
356 // Install an interrupt handler.
357 void installInterrupt(void (*isrPtr)(void), unsigned char offset)
358 {
359     unsigned char xdata * vectPtr = (unsigned char xdata *) offset;
360     unsigned long isr = (unsigned long)isrPtr;
361
362     *vectPtr++ = 0x02;
363     *vectPtr++ = (unsigned char)(isr >> 16);
364     *vectPtr++ = (unsigned char)(isr >> 8);
365     *vectPtr = (unsigned char)isr;
366 }