* device/include/pic16/pic18f248.h,
[fw/sdcc] / device / lib / ds400 / ds400rom.c
index 219d367e453dd78ed23b9b03225fc8e7bfd8e47c..b3b9cf57f4627c076caefa0a0c211c2de057ed14 100644 (file)
 #include <stdio.h>
 #include <ds400rom.h>
 
+// ROM globals, taken from startup400.a51
+__data unsigned char __at (0x68) DSS_wos_crit_count;
+__data unsigned int  __at (0x6b) DSS_timerReload;
+__data unsigned char __at (0x6d) DSS_curr_pc[3];
+__data unsigned char __at (0x72) DSS_sched[3];
+__data unsigned char __at (0x74) DSS_ms_count[5];
+__data unsigned char __at (0x7b) DSS_hb_chandle[5];
+    
 // Register bank 3 equates.
 #define R0_B3     0x18
 #define R1_B3     0x19
@@ -41,6 +49,9 @@
 #define R7_B3     0x1F
 
 
+// The top of the redirect function table in RAM.
+#define CALL_TABLE_TOP 256
+    
 // The bank the ROM is stored in.  Should be 0FFh for production
 // 400's.  Change this value when running with a debug ROM.
 
 #define ROMXT_AUTOBAUD                  (99 * ROMXT_ENTRYSIZE)
 #define ROMXT_TFTP_CLOSE                (100 * ROMXT_ENTRYSIZE)
 
+
+#define ROMRT_ENTRYSIZE  3
+
+//
+// ROM REDIRECT TABLE FUNCTIONS (denoted with ROMRT)
+//
+#define ROMRT_KERNELMALLOC                  ( 1 * ROMRT_ENTRYSIZE)
+#define ROMRT_KERNELFREE                    ( 2 * ROMRT_ENTRYSIZE)
+#define ROMRT_MALLOC                        ( 3 * ROMRT_ENTRYSIZE)
+#define ROMRT_FREE                          ( 4 * ROMRT_ENTRYSIZE)
+#define ROMRT_MALLOCDIRTY                   ( 5 * ROMRT_ENTRYSIZE)
+#define ROMRT_DEREF                         ( 6 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETFREERAM                    ( 7 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETTIMEMILLIS                 ( 8 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETTHREADID                   ( 9 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADRESUME                  (10 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADIOSLEEP                 (11 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADIOSLEEPNC               (12 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADSAVE                    (13 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADRESTORE                 (14 * ROMRT_ENTRYSIZE)
+#define ROMRT_SLEEP                         (15 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETTASKID                     (16 * ROMRT_ENTRYSIZE)
+#define ROMRT_INFOSENDCHAR                  (17 * ROMRT_ENTRYSIZE)
+#define ROMRT_IP_COMPUTECHECKSUM_SOFTWARE   (18 * ROMRT_ENTRYSIZE)
+#define ROMRT_0                             (19 * ROMRT_ENTRYSIZE) // undefined
+#define ROMRT_DHCPNOTIFY                    (20 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_CREATE               (21 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_DUPLICATE            (22 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_DESTROY              (23 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_SWITCH_IN            (24 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_SWITCH_OUT           (25 * ROMRT_ENTRYSIZE)
+#define ROMRT_OWIP_READCONFIG               (26 * ROMRT_ENTRYSIZE)
+#define ROMRT_SETMACID                      (27 * ROMRT_ENTRYSIZE)
+#define ROMRT_UNDEREF                       (28 * ROMRT_ENTRYSIZE)
+
+
 #define GETC           \
     clr  a             \
     movc a, @a+dptr
     
 
 // expects function number in R6_B3 (low byte) & R7_B3 (high byte)
-void _romcall(void) _naked
+void _romcall(void) __naked
 {
-_asm    
+__asm    
       push  dpx                               ; dptr0 preserved here
       push  dph
       push  dpl
@@ -239,9 +286,47 @@ _asm
       ret                                     ; this is not a ret, it is a call!
        
       ; the called function ends with a ret which will return to our original caller.
-_endasm ;
+__endasm ;
 }
 
+// expects function number in R6_B3 (low byte) & R7_B3 (high byte)
+void _romredirect(void) __naked
+{
+__asm
+      push  dpx
+      push  dph
+      push  dpl
+      push  acc
+      ; dptr = CALL_TABLE_TOP + function offset.
+      mov   a, #(CALL_TABLE_TOP & 0xff)
+      add   a, R6_B3                          ; add function offset to the table
+      mov   dpl, a
+      mov   a, #((CALL_TABLE_TOP >> 8) & 0xff)
+      addc  a, R7_B3
+      mov   dph, a
+      mov   dpx, #((CALL_TABLE_TOP >> 16) & 0xff)
+      movx  a, @dptr                      ; read high byte
+      mov   R5_B3, a
+      inc   dptr
+      movx  a, @dptr                      ; read mid byte
+      mov   R4_B3, a
+      inc   dptr
+      movx  a, @dptr                      ; read low byte
+      mov   R3_B3, a
+      pop   acc                 ; restore acc and dptr
+      pop   dpl
+      pop   dph
+      pop   dpx
+      push  R3_B3               ; push low byte of target address
+      push  R4_B3
+      push  R5_B3               ; push high byte of target address
+      ret                       ; this is not a ret, it is a call!
+
+      ; the called function ends with a ret which will return to our original caller.
+__endasm;      
+}
+
+
 // This macro is invalid for the standard C preprocessor, since it
 // includes a hash character in the expansion, hence the SDCC specific
 // pragma.
@@ -251,23 +336,28 @@ _endasm ;
        mov     R7_B3, #((x >> 8) & 0xff)       \
        lcall   __romcall
 
+#define ROMREDIRECT(x) \
+       mov     R6_B3, #(x & 0xff)              \
+       mov     R7_B3, #((x >> 8) & 0xff)       \
+       lcall   __romredirect
+
 
-// rom_init: the ds400 ROM_INIT ROM function.
-unsigned char rom_init(void xdata *loMem,
-                      void xdata *hiMem) _naked
+// init_rom: the ds400 ROM_INIT ROM function.
+unsigned char init_rom(void __xdata *loMem,
+                      void __xdata *hiMem) __naked
 {    
     // shut compiler up about unused parameters.
     loMem;
     hiMem;
     
-_asm
+__asm
        ; load params.
        ; loMem is already in DPTR.
        mov     r2, dpx
        mov     r1, dph
        mov     r0, dpl
-       ; hiMem is in _rom_init_PARM_2
-       mov     dptr, #_rom_init_PARM_2
+       ; hiMem is in _init_rom_PARM_2
+       mov     dptr, #_init_rom_PARM_2
        mov     r5, dpx
        mov     r4, dph
        mov     r3, dpl
@@ -277,90 +367,43 @@ _asm
        ; result is in acc, move to dpl for C convention.
        mov     dpl, a
        ret
-_endasm        ;
+__endasm       ;
 }
 
-// all other ROM functions should go here, using rom_init as a template...
-
-// Various utility functions.
-
-// Return the start of the XI_SEG. Really just a workaround for the
-// fact that the linker defined symbol (s_XISEG) isn't directly accessible
-// from C due to the lack of a leading underscore, and I'm too lazy to hack 
-// the linker.
-static void xdata *_xisegStart(void) _naked
+// DSS_gettimemillis: note that the ROM actually returns 5 bytes of time,
+// we're discarding the high byte here.
+unsigned long task_gettimemillis_long(void) __naked
 {
-_asm    
-       mov     dptr, #(s_XISEG)
-       ret
-_endasm;
+__asm    
+    ; no parameters to load. 
+    ROMREDIRECT(ROMRT_GETTIMEMILLIS)
+   ; results in r4 - r0, return in DPTR/B
+   mov dpl, r0
+   mov dph, r1
+   mov dpx, r2
+   mov b, r3
+   ret
+__endasm;
 }
 
-// Return the length of the XI_SEG. Really just a workaround for the
-// fact that the linker defined symbol (l_XISEG) isn't directly accessible
-// from C due to the lack of a leading underscore, and I'm too lazy to hack 
-// the linker.
-static unsigned  _xisegLen(void) _naked
+unsigned char task_getthreadID(void) __naked
 {
-_asm    
-       mov     dptr, #(l_XISEG)
-       ret
-_endasm;
+__asm    
+    ; no parameters to load. 
+    ROMREDIRECT(ROMRT_GETTHREADID)
+   ; results in acc, return in dpl
+   mov dpl, a
+   ret
+__endasm;    
 }
 
-// Returns the address of the first byte available for heap memory, 
-// i.e. the first byte following the XI_SEG.
-static void xdata *_firstHeapByte(void)
+unsigned int task_gettickreload(void)
 {
-    unsigned char xdata *start;
-    
-    start = (unsigned char xdata *) _xisegStart();     
-    start += _xisegLen();
-
-    return (void xdata *)start;
+    return DSS_timerReload;
 }
 
-// A simple wrapper for ROM_INIT which allocates all available RAM in the CE0 area
-// to the heap.
-
-// The last addressible byte of the CE0 area. 
-#define CE0_END 0xfffff
-
-unsigned char romInit(unsigned char noisy)
+void task_settickreload(unsigned int rl)
 {
-    void xdata *heapStart;
-    void xdata *heapEnd;
-    unsigned long heapLen; 
-    unsigned char rc;
-    
-    heapStart = _firstHeapByte();
-    heapEnd = (void xdata *)CE0_END;
-
-    rc = rom_init(heapStart, heapEnd);
-    
-    if (noisy)
-    {
-       if (rc)
-       {
-           printf("error: rom_init returns %d\n", (int)rc);
-       }
-       else
-       {
-           heapLen = CE0_END - (unsigned long)heapStart;
-           printf("Heap starts at %p, length %luK\n", heapStart, heapLen / 1024);
-       }
-    }
-    return rc;
+    DSS_timerReload = rl;
 }
 
-// Install an interrupt handler.
-void installInterrupt(void (*isrPtr)(void), unsigned char offset)
-{
-    unsigned char xdata * vectPtr = (unsigned char xdata *) offset;
-    unsigned long isr = (unsigned long)isrPtr;
-
-    *vectPtr++ = 0x02;
-    *vectPtr++ = (unsigned char)(isr >> 16);
-    *vectPtr++ = (unsigned char)(isr >> 8);
-    *vectPtr = (unsigned char)isr;
-}