More DS400 support
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 30 Jun 2003 21:57:29 +0000 (21:57 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 30 Jun 2003 21:57:29 +0000 (21:57 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2717 4a8a32a2-be11-0410-ad9d-d568d2c75423

device/examples/ds400/monitor400/mon400.c
device/include/ds400rom.h
device/lib/ds400/ds400rom.c
device/lib/ds400/tinibios.c
src/ds390/gen.c

index 478c592792d9f8134cf8f364870e2ac0f62e065a..5f39556e3d1e7d92ad4d6a35c0d118c21aa0bf8d 100644 (file)
@@ -11,18 +11,59 @@ void usage(void)
     puts("Available commands:\n");
     puts("ledon: turns LED on.");
     puts("ledoff: turns LED off.");
-    puts("startclock: starts millisecond timer.");
     puts("clock: reports millisecond timer.");
     puts("sleep: sleeps for 10 seconds (or forever if you didn't startclock first).");
 }
 
+void blinker(void)
+{
+    int i, j;
+    
+    while (1)
+    {
+       P5 |= 4;
+       for (j = 0; j < 10; j++)
+       {
+           for (i = 0; i < 32767; i++)
+           {
+               ;
+           }
+       }
+       
+       P5 &= ~4;
+       
+       for (j = 0; j < 10; j++)
+       {
+           for (i = 0; i < 32767; i++)
+           {
+               ;
+           }
+       }       
+    }
+}
+
+
 void main(void)
 {
     char buffer[80];
     
     // At this stage, the rom isn't initalized. We do have polled serial I/O, though.
     printf("TINIm400 monitor rev 0.0\n");
-
+    
+    P5 |= 4; // LED off.
+    
+    // double the cpu speed.
+    if (1)
+    {
+       PMR = 0x82;
+       PMR = 0x92;
+       
+       while (!(EXIF & 8))
+           ;
+       
+       PMR = 0x12;
+    }
+    
     // Intialize the ROM.
     if (romInit(1))
     {
@@ -52,15 +93,14 @@ void main(void)
            P5 |= 4;
            printf("LED off.\n");
        }
-       else if (!strcmp(buffer, "startclock"))
-       {
-           printf("Starting clock...\n");
-           ClockInit();
-       }
        else if (!strcmp(buffer, "clock"))
        {
            printf("Clock: %ld\n", ClockTicks());
        }
+       else if (!strcmp(buffer, "thread"))
+       {
+           printf("Thread ID: %d\n", (int)DSS_getthreadID());
+       }
        else if (!strcmp(buffer, "sleep"))
        {
            printf("Sleeping for 10 seconds...\n");
@@ -69,7 +109,46 @@ void main(void)
            
            printf("Back.\n");
        }
-       
+       else if (!strcmp(buffer, "pmr"))
+       {
+           printf("PMR: %x\n", PMR);
+       }
+       else if (!strcmp(buffer, "exif"))
+       {
+           printf("EXIF: %x\n", EXIF);
+       }
+       else if (!strcmp(buffer, "blink"))
+       {
+           blinker();
+       }
+       else if (!strcmp(buffer, "t0"))
+       {
+           printf("TH0:TL0 %x:%x\n", TH0, TL0);
+       }
+       else if (!strcmp(buffer, "t2"))
+       {
+           printf("TH2:TL2 %x:%x\n", TH2, TH2);
+       }       
+       else if (!strcmp(buffer, "faster"))
+       {
+           printf("going really fast...\n");
+           P5 |= 4; // LED off.
+
+           PMR = 0x82; 
+           PMR = 0x8a; // 8a for REAL fast
+           PMR = 0x9a; // 9a for REAL fast.
+           
+           while (!(EXIF & 8))
+               ;
+
+           PMR = 0x1a; // 1a for REAL fast.
+           
+_asm
+               nop
+_endasm;               
+           
+           P5 &= ~5; // LED on.
+       }
        else if (buffer[0])
        {
            printf("Unknown command \"%s\".\n", buffer);
index 20a679b71ca22c79715bb350ec27de2c4324b07c..86d0f5317389491056b929a12a8b78a55020e013 100644 (file)
@@ -3,8 +3,12 @@
 #ifndef DS400ROM_H_
 #define DS400ROM_H_
 
-extern unsigned char rom_init(void xdata *loMem,
-                             void xdata *hiMem) _naked;
+extern unsigned char DSS_rom_init(void xdata *loMem,
+                                 void xdata *hiMem) _naked;
+
+extern unsigned long DSS_gettimemillis(void) _naked;
+
+extern unsigned char DSS_getthreadID(void) _naked;
 
 // Utility functions.
 
index 219d367e453dd78ed23b9b03225fc8e7bfd8e47c..0a91d1df4417c3a736549c8b68bacef0ffb1897a 100644 (file)
@@ -41,6 +41,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
@@ -242,6 +281,44 @@ _asm
 _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,9 +328,14 @@ _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,
+// DSS_rom_init: the ds400 ROM_INIT ROM function.
+unsigned char DSS_rom_init(void xdata *loMem,
                       void xdata *hiMem) _naked
 {    
     // shut compiler up about unused parameters.
@@ -266,8 +348,8 @@ _asm
        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 _DSS_rom_init_PARM_2
+       mov     dptr, #_DSS_rom_init_PARM_2
        mov     r5, dpx
        mov     r4, dph
        mov     r3, dpl
@@ -280,7 +362,34 @@ _asm
 _endasm        ;
 }
 
-// all other ROM functions should go here, using rom_init as a template...
+// DSS_gettimemillis: note that the ROM actually returns 5 bytes of time,
+// we're discarding the high byte here.
+unsigned long DSS_gettimemillis(void) _naked
+{
+_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;
+}
+
+unsigned char DSS_getthreadID(void) _naked
+{
+_asm    
+    ; no parameters to load. 
+    ROMREDIRECT(ROMRT_GETTHREADID)
+   ; results in acc, return in dpl
+   mov dpl, a
+   ret
+_endasm;    
+}
+
+
 
 // Various utility functions.
 
@@ -336,7 +445,7 @@ unsigned char romInit(unsigned char noisy)
     heapStart = _firstHeapByte();
     heapEnd = (void xdata *)CE0_END;
 
-    rc = rom_init(heapStart, heapEnd);
+    rc = DSS_rom_init(heapStart, heapEnd);
     
     if (noisy)
     {
index 259b06d4211c59d50111173adda78921da85bcb8..eefc203836b8484d2a7d2f7914518c53e45b4436 100755 (executable)
 #include <tinibios.h>
 #include <ds400rom.h>
 
+#include <stdio.h>
+
 #define TIMED_ACCESS(sfr,value) { TA=0xaa; TA=0x55; sfr=value; }
 
 #undef OSCILLATOR
-#define OSCILLATOR 14725600
+#define OSCILLATOR 14745600
 
 unsigned char _sdcc_external_startup(void)
 {
@@ -86,13 +88,26 @@ static data unsigned char serial0Buffered;
    If buffered!=0, characters received are buffered using an interrupt
 */
 
+
+#define SERIAL0_BAUDRATE 115200
+#define TIMER_RELOAD (65536 - ((OSCILLATOR) / (32 * SERIAL0_BAUDRATE)))
+
 void Serial0Init (unsigned long baud, unsigned char buffered) {
   
   ES0 = 0; // disable serial channel 0 interrupt
 
+#if 0    
   // Need no port setup, done by boot rom.
-  
   baud;
+#else
+    SCON0 = 0x5A; // 10 bit serial 0, use timer baud rate, enable recieving
+    RCAP2H = (TIMER_RELOAD >> 8) & 0xff;
+    RCAP2L = TIMER_RELOAD & 0xff;
+    T2CON = 0x30; // Enable timer 2 for serial port
+    TR2 = 1; // Set timer 2 to run
+    
+    baud;
+#endif    
 
   serial0Buffered=buffered;
  
@@ -106,16 +121,6 @@ void Serial0Init (unsigned long baud, unsigned char buffered) {
   }
 }
 
-void Serial0Baud(unsigned long baud) {
-  TR2=0; // stop timer
-  baud=-((long)OSCILLATOR/(32*baud));
-  TL2=RCAP2L= baud;
-  TH2=RCAP2H= baud>>8;
-  TF2=0; // clear overflow flag
-  TR2=1; // start timer
-}  
-
-
 void Serial0SwitchToBuffered(void)
 {
     IE &= ~0x80;
@@ -128,7 +133,6 @@ void Serial0SwitchToBuffered(void)
     IE |= 0x80;
 }
 
-
 void Serial0IrqHandler (void) interrupt 4 {
   if (RI_0) {
     receive0Buffer[receive0BufferHead]=SBUF0;
@@ -168,7 +172,6 @@ void Serial0PutChar (char c)
       ;
     TI_0 = 0;
     SBUF0=c;
-    // TI_0=0;
   }
 }
 
@@ -191,14 +194,11 @@ char Serial0GetChar (void)
   return c;
 }
 
-#if 0 
-// FIXME: no ClockMilliSecondsDelay yet.
 void Serial0SendBreak() {
   P3 &= ~0x02;
   ClockMilliSecondsDelay(2);
   P3 |= 0x02;
 }
-#endif
 
 void Serial0Flush() {
   ES0=0; // disable interrupts
@@ -212,77 +212,24 @@ void Serial0Flush() {
   }
 }
 
-// now let's go for the clock stuff
-
-// these REALLY need to be in data space for the irq routine!
-static data unsigned long milliSeconds=0;
-static data unsigned int timer0ReloadValue;
+// now let's go for the clock stuff - on the DS400, we can just
+// use the ROM's millisecond timer, running off timer 0.
+// 
+// for now, this timer runs too fast by about 20%. We need an implementation of
+// task_settickreload to fix this.
 
 void ClockInit() {
-  unsigned long timerReloadValue= OSCILLATOR / 1000 / 4;
-
-  timer0ReloadValue=~timerReloadValue;
-  // initialise timer 0
-  ET0=0; // disable timer interrupts initially
-  
-  TCON = (TCON&0xcc)|0x00; // stop timer, clear overflow
-  TMOD = (TMOD&0xf0)|0x01; // 16 bit counter
-  CKCON|=0x08; // timer uses xtal/4
-  
-  TL0=timer0ReloadValue&0xff;
-  TH0=timer0ReloadValue>>8;
-  
-  installInterrupt(ClockIrqHandler, 0xB);
-    
-  ET0=1; // enable timer interrupts
-  TR0=1; // start timer
-}
-
-// This needs to be SUPER fast. What we really want is:
-
-#if 0
-void junk_ClockIrqHandler (void) interrupt 10 {
-  TL0=timer0ReloadValue&0xff;
-  TH0=timer0ReloadValue>>8;
-  milliSeconds++;
-}
-#else
-// but look at the code, and the pushes and pops, so:
-void ClockIrqHandler (void) interrupt 1 _naked
-{
-  _asm
-    push acc
-    push psw
-    mov _TL0,_timer0ReloadValue
-    mov _TH0,_timer0ReloadValue+1
-    clr a
-    inc _milliSeconds+0
-    cjne a,_milliSeconds+0,_ClockIrqHandlerDone
-    inc _milliSeconds+1
-    cjne a,_milliSeconds+1,_ClockIrqHandlerDone
-    inc _milliSeconds+2
-    cjne a,_milliSeconds+2,_ClockIrqHandlerDone
-    inc _milliSeconds+3
-   _ClockIrqHandlerDone:
-    pop psw
-    pop acc
-    reti
-  _endasm;
+    // nada, all done by DSS_rom_init
 }
-#endif
 
 // we can't just use milliSeconds
 unsigned long ClockTicks(void) {
-  unsigned long ms;
-  ET0=0;
-  ms=milliSeconds;
-  ET0=1;
-  return ms;
+    return DSS_gettimemillis();
 }
 
 void ClockMilliSecondsDelay(unsigned long delay) {
-  long ms=ClockTicks()+delay;
+  unsigned long ms = DSS_gettimemillis() + delay;
 
-  while (ms>ClockTicks())
-    ;
+    while (ms > DSS_gettimemillis())
+        ;
 }
index 2adeded37d96058b67a1eb1c00ceae38e650e985..f697a3b1e045ba3e3c4c0f9f1d8511289b772b89 100644 (file)
@@ -2045,8 +2045,8 @@ saveRegisters (iCode * lic)
 
   /* if the registers have been saved already then
      do nothing */
-  if (ic->regsSaved || 
-      (IS_SYMOP(IC_LEFT(ic)) && IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic)))))
+  if (ic->regsSaved 
+      || (IS_SYMOP(IC_LEFT(ic)) && IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT(ic))) && !TARGET_IS_DS400) )
     return ;
 
   /* special case if DPTR alive across a function call then must save it 
@@ -2549,7 +2549,7 @@ genCall (iCode * ic)
      the same register bank then we need to save the
      destination registers on the stack */
   dtype = operandType (IC_LEFT (ic));
-  if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
+  if (currFunc && dtype && (!IFFUNC_ISNAKED(dtype) || TARGET_IS_DS400) &&
       (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype)) &&
       IFFUNC_ISISR (currFunc->type))
   {
@@ -2705,7 +2705,7 @@ genPcall (iCode * ic)
      the same register bank then we need to save the
      destination registers on the stack */
   dtype = operandType (IC_LEFT (ic));
-  if (currFunc && dtype && !IFFUNC_ISNAKED(dtype) &&
+  if (currFunc && dtype && (!IFFUNC_ISNAKED(dtype) || TARGET_IS_DS400) &&
       IFFUNC_ISISR (currFunc->type) &&
       (FUNC_REGBANK (currFunc->type) != FUNC_REGBANK (dtype))) {
     saveRBank (FUNC_REGBANK (dtype), ic, TRUE);