DS800C400 fun, improved ROM interface and tinibios
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 1 Jul 2003 21:12:35 +0000 (21:12 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 1 Jul 2003 21:12:35 +0000 (21:12 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2718 4a8a32a2-be11-0410-ad9d-d568d2c75423

17 files changed:
ChangeLog
device/examples/ds400/monitor400/mon400.c
device/include/ds400rom.h
device/include/tinibios.h
device/lib/ds400/ds400rom.c
device/lib/ds400/tinibios.c
src/SDCCglue.c
src/SDCCmain.c
src/avr/main.c
src/ds390/main.c
src/mcs51/main.c
src/pic/main.c
src/pic16/main.c
src/port.h
src/xa51/main.c
src/z80/main.c
support/tests/dhrystone/dhry.c

index c3451510f36ecd6591b02e49b5b8dcfb93aba7a1..0976fe1383e52f3c6cb5fdb5de6dc8b75cf94090 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-07-01 Kevin Vigor <kevin@vigor.nu>
+
+        * DS800C400 fun, improved ROM interface and tinibios.
+
 2003-06-27 Kevin Vigor <kevin@vigor.nu>
 
        * More support for DS80C400. Now includes beginning of interface to ROM.
index 5f39556e3d1e7d92ad4d6a35c0d118c21aa0bf8d..c0060ded8355cf1f9051825e476969638354789d 100644 (file)
@@ -47,35 +47,14 @@ void main(void)
 {
     char buffer[80];
     
-    // At this stage, the rom isn't initalized. We do have polled serial I/O, though.
+    // At this stage, the rom isn't initalized. We do have polled serial I/O, but that's
+    // about the only functional library service.
     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))
-    {
-       // We're hosed. romInit will have printed an error, nothing more to do.
-       return;
-    }
-    
-    P5 &= ~4; // LED on.
 
-    // Switch to interrupt driven serial I/O now that the rom is initialized.
-    Serial0SwitchToBuffered();
+    romInit(1, SPEED_2X);
 
+    // Now we're cooking with gas.
+    
     while (1)
     {
        // monitor prompt.
@@ -99,7 +78,7 @@ void main(void)
        }
        else if (!strcmp(buffer, "thread"))
        {
-           printf("Thread ID: %d\n", (int)DSS_getthreadID());
+           printf("Thread ID: %d\n", (int)task_getthreadID());
        }
        else if (!strcmp(buffer, "sleep"))
        {
index 86d0f5317389491056b929a12a8b78a55020e013..d96cd9f770a33d32558351fc6fa7ba0cda77b681 100644 (file)
@@ -3,20 +3,33 @@
 #ifndef DS400ROM_H_
 #define DS400ROM_H_
 
-extern unsigned char DSS_rom_init(void xdata *loMem,
-                                 void xdata *hiMem) _naked;
+extern unsigned char init_rom(void xdata *loMem,
+                             void xdata *hiMem) _naked;
 
-extern unsigned long DSS_gettimemillis(void) _naked;
+extern unsigned long task_gettimemillis_long(void) _naked;
 
-extern unsigned char DSS_getthreadID(void) _naked;
+extern unsigned char task_getthreadID(void) _naked;
 
-// Utility functions.
+/** Timer reload value for 14.746 MHz crystal. */
+#define RELOAD_14_746 0xfb33
 
-// A wrapper which calls rom_init allocating all available RAM in CE0
-// to the heap.
-unsigned char romInit(unsigned char noisy);
+/** Timer reload value for 18.432 MHz crystal. */
+#define RELOAD_18_432 0xfa00
 
-// Install an interrupt handler.
-void installInterrupt(void (*isrPtr)(void), unsigned char offset);
+/** Timer reload value for 29.491 MHz crystal. */
+#define RELOAD_29_491 0xfd99
+
+/** Timer reload value for 36.864 MHz crystal. */
+#define RELOAD_36_864 0xfd00
+
+/** Timer reload value for 58.982 MHz crystal. */
+#define RELOAD_58_982 0xfecc
+
+/** Timer reload value for 73.728 MHz crystal. */
+#define RELOAD_73_728 0xfe80
+
+extern unsigned int task_gettickreload(void);
+
+extern void task_settickreload(unsigned);
 
 #endif
index 2bc544a7fd9dfbbb7420e3203509b976c2684f86..c27837b63eed3c446571321bd9e694be1e99f509 100755 (executable)
@@ -38,7 +38,11 @@ void ClockMicroSecondsDelay(unsigned int us);
 #define SERIAL_1_RECEIVE_BUFFER_SIZE 64
 
 // I know someone is fooling with the crystals
-#define OSCILLATOR 18432000L
+#if defined(SDCC_ds400)
+# define OSCILLATOR 14745600L
+#else
+# define OSCILLATOR 18432000L
+#endif
 
 /* Set the cpu speed in clocks per machine cycle, valid values are:
    1024: Divide-by-1024 (power management) mode (screws ALL timers and serial)
@@ -95,7 +99,30 @@ extern char i2cReceiveBuffer[I2C_BUFSIZE];
 unsigned char _sdcc_external_startup(void);
 void Serial0IrqHandler (void) interrupt 4;
 void Serial1IrqHandler (void) interrupt 7;
+
+#if !defined(SDCC_ds400)
 void ClockInit();
 void ClockIrqHandler (void) interrupt 1 _naked;
+#endif
+
+#if defined(SDCC_ds400)
+// functions for dealing with the ds400 ROM firmware.
+
+// A wrapper which calls rom_init allocating all available RAM in CE0
+// to the heap, sets the serial port to SERIAL_0_BAUD, sets up the 
+// millisecond timer, and diddles the clock multiplier.
+
+// Values for the romInit "speed" parameter.
+#define SPEED_1X       0 /* no clock multiplier, normal speed. */
+#define SPEED_2X       1 /* 2x clock multiplier. */
+#define SPEED_4X       2 /* 4x clock, DOESN'T WORK ON TINIm400! */
+
+unsigned char romInit(unsigned char noisy,
+                     char speed);
+
+// Install an interrupt handler.
+void installInterrupt(void (*isrPtr)(void), unsigned char offset);
+#endif
+
 
 #endif /* TINIBIOS_H */
index 0a91d1df4417c3a736549c8b68bacef0ffb1897a..7bba973a8fb7807c097b8e3774ce0dfc66c49682 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
@@ -334,8 +342,8 @@ _endasm;
        lcall   __romredirect
 
 
-// DSS_rom_init: the ds400 ROM_INIT ROM function.
-unsigned char DSS_rom_init(void xdata *loMem,
+// 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.
@@ -348,8 +356,8 @@ _asm
        mov     r2, dpx
        mov     r1, dph
        mov     r0, dpl
-       ; hiMem is in _DSS_rom_init_PARM_2
-       mov     dptr, #_DSS_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
@@ -364,7 +372,7 @@ _endasm     ;
 
 // 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
+unsigned long task_gettimemillis_long(void) _naked
 {
 _asm    
     ; no parameters to load. 
@@ -378,7 +386,7 @@ _asm
 _endasm;
 }
 
-unsigned char DSS_getthreadID(void) _naked
+unsigned char task_getthreadID(void) _naked
 {
 _asm    
     ; no parameters to load. 
@@ -389,87 +397,13 @@ _asm
 _endasm;    
 }
 
-
-
-// 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
-{
-_asm    
-       mov     dptr, #(s_XISEG)
-       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
-{
-_asm    
-       mov     dptr, #(l_XISEG)
-       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 = DSS_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;
-}
index eefc203836b8484d2a7d2f7914518c53e45b4436..1c059cf19c0cda000ca8fdd11daa1d938dd8701c 100755 (executable)
@@ -31,9 +31,6 @@
 
 #define TIMED_ACCESS(sfr,value) { TA=0xaa; TA=0x55; sfr=value; }
 
-#undef OSCILLATOR
-#define OSCILLATOR 14745600
-
 unsigned char _sdcc_external_startup(void)
 {
     IE = 0; // Disable all interrupts.
@@ -89,8 +86,7 @@ static data unsigned char serial0Buffered;
 */
 
 
-#define SERIAL0_BAUDRATE 115200
-#define TIMER_RELOAD (65536 - ((OSCILLATOR) / (32 * SERIAL0_BAUDRATE)))
+#define TIMER_RELOAD (65536 - ((OSCILLATOR) / (32 * SERIAL_0_BAUD)))
 
 void Serial0Init (unsigned long baud, unsigned char buffered) {
   
@@ -224,12 +220,125 @@ void ClockInit() {
 
 // we can't just use milliSeconds
 unsigned long ClockTicks(void) {
-    return DSS_gettimemillis();
+    return task_gettimemillis_long();
 }
 
 void ClockMilliSecondsDelay(unsigned long delay) {
-  unsigned long ms = DSS_gettimemillis() + delay;
+  unsigned long ms = task_gettimemillis_long() + delay;
 
-    while (ms > DSS_gettimemillis())
+    while (ms > task_gettimemillis_long())
         ;
 }
+
+// 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
+{
+_asm    
+       mov     dptr, #(s_XISEG)
+       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
+{
+_asm    
+       mov     dptr, #(l_XISEG)
+       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 char xdata *start;
+    
+    start = (unsigned char xdata *) _xisegStart();     
+    start += _xisegLen();
+
+    return (void xdata *)start;
+}
+
+// TINIm400 specific startup.
+
+// The last addressible byte of the CE0 area. 
+#define CE0_END 0xfffff
+
+unsigned char romInit(unsigned char noisy,
+                     char           speed)
+{
+    void xdata *heapStart;
+    void xdata *heapEnd;
+    unsigned long heapLen; 
+    unsigned char rc;
+
+    if (speed == SPEED_2X)
+    {
+       PMR = 0x82;
+        PMR = 0x92;
+
+        while (!(EXIF & 8))
+            ;
+
+        PMR = 0x12;
+    }
+    else if (speed == SPEED_4X)
+    {
+       // Hangs on TINIm400!
+       PMR = 0x82;
+       PMR = 0x8a;
+        PMR = 0x9a;
+
+        while (!(EXIF & 8))
+            ;
+
+        PMR = 0x1a;
+    }
+    
+    heapStart = _firstHeapByte();
+    heapEnd = (void xdata *)CE0_END;
+
+    rc = init_rom(heapStart, heapEnd);
+    
+    if (noisy)
+    {
+       if (rc)
+       {
+           printf("error: rom_init returns %d\n", (int)rc);
+           return rc;
+       }
+       else
+       {
+           heapLen = CE0_END - (unsigned long)heapStart;
+           printf("Heap starts at %p, length %luK\n", heapStart, heapLen / 1024);
+       }
+    }
+    
+    task_settickreload(RELOAD_14_746);
+    
+    // Switch to interrupt driven serial I/O now that the rom is initialized.
+    Serial0SwitchToBuffered();
+    
+    P5 &= ~4; // LED on.
+    
+    return 0;
+}
+
+// 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;
+}
index c317fffcbece14dc441cfde531d84bf06d7c8e52..7d7cda458072f8696311a3439d7de74f7b009a29 100644 (file)
@@ -1668,6 +1668,13 @@ glue (void)
   fprintf (asmFile, "%s", iComments2);
   copyFile (asmFile, xidata->oFile);
 
+  /* If the port wants to generate any extra areas, let it do so. */
+  if (port->extraAreas.genExtraAreaDeclaration)
+  {
+      port->extraAreas.genExtraAreaDeclaration(asmFile, 
+                                              mainf && IFFUNC_HASBODY(mainf->type));
+  }
+    
   /* copy the interrupt vector table */
   if (mainf && IFFUNC_HASBODY(mainf->type))
     {
index abcd1bab0ce5e5b8704fee51dce4bf34cbaa6e10..bda73ad70187bff57ee89ea517fdc64ac9792a1a 100644 (file)
@@ -1349,6 +1349,12 @@ linkEdit (char **envp)
   if ( (options.stack_loc) && (options.stack_loc<0x100) ) {
        WRITE_SEG_LOC ("SSEG", options.stack_loc);
   }
+  
+  /* If the port has any special linker area declarations, get 'em */
+  if (port->extraAreas.genExtraAreaLinkOptions)
+  {
+       port->extraAreas.genExtraAreaLinkOptions(lnkfile);
+  }
 
   /* add the extra linker options */
   fputStrSet(lnkfile, linkOptionsSet);
index 9b377b50c4e477d2aa7c18d55e8af545a6f5332d..73eb0ba6b652aca3a3d71016bb6b62affcff3b48 100644 (file)
@@ -194,6 +194,7 @@ PORT avr_port = {
         NULL,
         0,
         },
+        { NULL, NULL },
        {
         -1, 1, 4, 1, 1, 0},
        /* avr has an 8 bit mul */
index de5d91e8b5fc2cadb6aa65aa69727304599c1b7b..285862e36830cc60ed71706f78da2e41ad98b220 100644 (file)
@@ -384,6 +384,7 @@ PORT ds390_port =
     NULL,
     1
   },
+  { NULL, NULL },
   {
     +1, 1, 4, 1, 1, 0
   },
@@ -673,6 +674,7 @@ PORT tininative_port =
     NULL,
     1
   },
+  { NULL, NULL },
   {
     +1, 1, 4, 1, 1, 0
   },
@@ -806,6 +808,27 @@ _ds400_finaliseOptions (void)
   }  /* MODEL_FLAT24 */
 }
 
+extern char * iComments2;
+
+static void _ds400_generateRomDataArea(FILE *fp, bool isMain)
+{
+    /* Only do this for the file containing main() */
+    if (isMain)
+    {
+       fprintf(fp, "%s", iComments2);
+       fprintf(fp, "; the direct data area used by the DS80c400 ROM code.\n");
+       fprintf(fp, "%s", iComments2);
+       fprintf(fp, ".area ROMSEG (ABS,CON,DATA)\n\n");
+       fprintf(fp, ".ds 24 ; 24 bytes of directs used starting at 0x68\n\n");
+    }
+}
+
+static void _ds400_linkRomDataArea(FILE *fp)
+{
+    fprintf(fp, "-b ROMSEG = 0x0068\n");
+}
+
+
 PORT ds400_port =
 {
   TARGET_ID_DS400,
@@ -858,6 +881,7 @@ PORT ds400_port =
     NULL,
     1
   },
+  { _ds400_generateRomDataArea, _ds400_linkRomDataArea },
   {
     +1, 1, 4, 1, 1, 0
   },
index 52048d1bf52d69cbb0e6f8c4cd776ae9082df085..3857a4e52e899af576c4831293a07d10609516e9 100644 (file)
@@ -277,6 +277,7 @@ PORT mcs51_port =
     NULL,
     1
   },
+  { NULL, NULL },
   {
     +1, 0, 4, 1, 1, 0
   },
index 78cfda609d6d8e883a273c412219b05ee3d41b15..ff5bcd3d658d17955b313b49c9f3e64706760159 100644 (file)
@@ -395,6 +395,7 @@ PORT pic_port =
     NULL,
     1        // code is read only
   },
+  { NULL, NULL },
   {
     +1, 1, 4, 1, 1, 0
   },
index 4d2fb48f10ea46d05c934c277b65fe0e91e4f49c..d236fe6df74e292a2d2c8b4ee71e8ed4b3768349 100644 (file)
@@ -412,6 +412,7 @@ PORT pic16_port =
     NULL,
     1        // code is read only
   },
+  { NULL, NULL },
   {
     +1, 1, 4, 1, 1, 0
   },
index f3101ed6b75710099d1219fe82a8963adccb56e3..835b55fb5a73ab18631ff7a174b6a10a1a395a43 100644 (file)
@@ -149,6 +149,13 @@ typedef struct
       }
     mem;
 
+    struct
+      {
+         void (*genExtraAreaDeclaration)(FILE *, bool);
+         void (*genExtraAreaLinkOptions)(FILE *);
+      }
+    extraAreas;
+      
     /* stack related information */
     struct
       {
index d3aaa9ad384c347d3ed5d05b328bcb39e7858b60..53b54359adb1199e4ff6a724ef4424d4770f34f1 100755 (executable)
@@ -258,6 +258,7 @@ PORT xa51_port =
     NULL, // default global map
     1
   },
+  { NULL, NULL },
   {
     -1, // stack grows down
     0, // bank overhead NUY
index 147dbbb45b3aedfd64fa5317523d565cc8585355..2ff5b561c18e6f56090a3bdee189bb213aae4202 100644 (file)
@@ -542,6 +542,7 @@ PORT z80_port =
     NULL,
     1
   },
+  { NULL, NULL },
   {
     -1, 0, 0, 4, 0, 2
   },
@@ -636,6 +637,7 @@ PORT gbz80_port =
     NULL,
     1
   },
+  { NULL, NULL },
   {
     -1, 0, 0, 2, 0, 4
   },
index 7b6cff8b5dc95bcd213d6167ea56307ce2fc05f6..ad11ff831ac3eb80d46c1a10954f1fa12c74ae0e 100644 (file)
@@ -126,15 +126,11 @@ void main(void)
 
 #if defined(SDCC_ds400)
     // Intialize the ROM.
-    if (romInit(1))
+    if (romInit(1, SPEED_2X))
     {
         // We're hosed. romInit will have printed an error, nothing more to do.
         return;
     }
-
-    ClockInit();
-    
-    P5 &= ~4; // LED on.
 #endif    
     
     printf("[dhry]\n");
@@ -162,8 +158,11 @@ void main(void)
 #if DEBUG
     Number_Of_Runs = 1;
 #else
-    // Number_Of_Runs = 32766;
-    Number_Of_Runs = 2048;
+#if defined(SDCC_ds400)    
+    Number_Of_Runs = 10240;
+#else    
+    Number_Of_Runs = 32766;
+#endif    
 #endif    
 
     runTime = clock();