Get tinibios clock timer interface working on ds400
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 27 Jun 2003 22:44:48 +0000 (22:44 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 27 Jun 2003 22:44:48 +0000 (22:44 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2716 4a8a32a2-be11-0410-ad9d-d568d2c75423

device/examples/ds400/monitor400/mon400.c
device/lib/ds400/tinibios.c
support/tests/dhrystone/dhry.c
support/tests/dhrystone/tini400.mak [new file with mode: 0644]

index 15b05fb2d7827906f482c4fc9404fcfe8f9ce71f..478c592792d9f8134cf8f364870e2ac0f62e065a 100644 (file)
@@ -11,6 +11,9 @@ 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 main(void)
@@ -49,6 +52,24 @@ 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, "sleep"))
+       {
+           printf("Sleeping for 10 seconds...\n");
+           
+           ClockMilliSecondsDelay(10 * 1000);
+           
+           printf("Back.\n");
+       }
+       
        else if (buffer[0])
        {
            printf("Unknown command \"%s\".\n", buffer);
index 0e3bdbcb66c318a882629ffc547255f6e1144d21..259b06d4211c59d50111173adda78921da85bcb8 100755 (executable)
@@ -29,6 +29,9 @@
 
 #define TIMED_ACCESS(sfr,value) { TA=0xaa; TA=0x55; sfr=value; }
 
+#undef OSCILLATOR
+#define OSCILLATOR 14725600
+
 unsigned char _sdcc_external_startup(void)
 {
     IE = 0; // Disable all interrupts.
@@ -208,3 +211,78 @@ void Serial0Flush() {
     TI_0=1;
   }
 }
+
+// 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;
+
+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;
+}
+#endif
+
+// we can't just use milliSeconds
+unsigned long ClockTicks(void) {
+  unsigned long ms;
+  ET0=0;
+  ms=milliSeconds;
+  ET0=1;
+  return ms;
+}
+
+void ClockMilliSecondsDelay(unsigned long delay) {
+  long ms=ClockTicks()+delay;
+
+  while (ms>ClockTicks())
+    ;
+}
index 30088a2677cc20e89b31971876fe66371b3ec321..7b6cff8b5dc95bcd213d6167ea56307ce2fc05f6 100644 (file)
 #define CLOCKS_PER_SEC 1000
 #define memcpy(d,s,l) memcpyx(d,s,l)
 
+# if defined(SDCC_ds400)
+# include <ds400rom.h>
+# endif
+
 #elif defined(__z80) || defined(__gbz80)
 unsigned int _clock(void);
 
@@ -107,7 +111,7 @@ Boolean Func_3 (Enumeration Enum_Par_Val);
 
 unsigned getsp(void);
 
-int main(void)
+void main(void)
 {
     One_Fifty       Int_1_Loc;
     REG   One_Fifty       Int_2_Loc;
@@ -120,6 +124,19 @@ int main(void)
     REG   int             Number_Of_Runs;
     unsigned  long runTime;
 
+#if defined(SDCC_ds400)
+    // Intialize the ROM.
+    if (romInit(1))
+    {
+        // We're hosed. romInit will have printed an error, nothing more to do.
+        return;
+    }
+
+    ClockInit();
+    
+    P5 &= ~4; // LED on.
+#endif    
+    
     printf("[dhry]\n");
 
     Next_Ptr_Glob = &_r[0];
@@ -145,7 +162,8 @@ int main(void)
 #if DEBUG
     Number_Of_Runs = 1;
 #else
-    Number_Of_Runs = 32766;
+    // Number_Of_Runs = 32766;
+    Number_Of_Runs = 2048;
 #endif    
 
     runTime = clock();
diff --git a/support/tests/dhrystone/tini400.mak b/support/tests/dhrystone/tini400.mak
new file mode 100644 (file)
index 0000000..47ba4a4
--- /dev/null
@@ -0,0 +1,21 @@
+CC = ../../../bin/sdcc
+
+MFLAGS = -mds400 --model-flat24 --stack-10bit
+MFLAGS += -DREG= -DNOSTRUCTASSIGN -DNOENUM
+LFLAGS = --xram-loc 0x10000 --code-loc 0x400000 -Wl-r
+
+OBJECTS = dhry.rel
+
+all: dhry.hex
+
+clean:
+       rm -f *~ \#* *.asm *.cdb *.rel *.hex *.ihx *.lst *.map *.rst *.sym *.lnk
+
+dhry.hex: dhry.ihx
+       packihx dhry.ihx >dhry.hex
+
+dhry.ihx: $(OBJECTS)
+       $(CC) $(MFLAGS) $(LFLAGS) $(OBJECTS)
+
+%.rel: %.c
+       $(CC) -c $(MFLAGS) $<