ds390 library support
authorjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 23 Aug 2000 15:20:30 +0000 (15:20 +0000)
committerjohanknol <johanknol@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 23 Aug 2000 15:20:30 +0000 (15:20 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@334 4a8a32a2-be11-0410-ad9d-d568d2c75423

13 files changed:
device/include/serial390.h [new file with mode: 0644]
device/include/stdio.h
device/lib/Makefile.in
device/lib/clean.mk
device/lib/ds390/Makefile [new file with mode: 0755]
device/lib/ds390/serial390.c [new file with mode: 0644]
device/lib/ds390/startup390.c [new file with mode: 0755]
device/lib/gets.c [new file with mode: 0755]
device/lib/incl.mk
device/lib/libsdcc.lib
device/lib/printf_large.c
device/lib/vprintf.c
src/SDCCmain.c

diff --git a/device/include/serial390.h b/device/include/serial390.h
new file mode 100644 (file)
index 0000000..426379d
--- /dev/null
@@ -0,0 +1,61 @@
+/*-------------------------------------------------------------------------
+  Include file for serial390.c. You can change some default's here.
+  
+   Written By - Johan Knol, johan.knol@iduna.nl
+    
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  
+-------------------------------------------------------------------------*/
+
+#ifndef SERIAL390_H
+#define SERIAL390_H
+
+/* Here we have to decide whether or not to use interrupts for serial output.
+   If your debug messages (don't we use them all :), doesn't show up
+   like you expect (e.g. when you screwed up the stack or tilted the cpu 
+   otherwise) or if you're expecting a lot of them that might overflow 
+   the ring buffer, disable it. It will slow down other things you might be
+   doing, but will leave serial output synchronized with that. */
+#define USE_SERIAL_INTERRUPTS 1
+
+/* Define the size of the ring buffer.
+   This must be a binary number, since we shouldn't use mod (%) in
+   interrupt routines */
+#define SERIAL_RECEIVE_BUFFER_SIZE 1024
+
+/* I'd rather had this calculation be done in Serial390Init(),
+   but since the compiler generates e.g. _divuchar() calls
+   which aren't in the library yet, we do it here. */
+#define BAUD_RATE 115200
+#define OSCILLATOR 18432000L
+#define TIMER1_RELOAD_VALUE -(OSCILLATOR/(32L*BAUD_RATE))
+
+/* there shouldn't be any reason to change anything below this line.
+   If there is, please let me know */
+
+extern void Serial390Init (void);
+
+#if USE_SERIAL_INTERRUPTS
+
+/* the interrupt vector will be automaticly set when the 
+   main program #include-s this file */
+extern void Serial390Handler (void) interrupt 4;
+
+#endif
+
+#endif SERIAL390_H
index 14b575affb32f92203aa6a13d8d6f6e0b3b0f5d4..6449820c5a083e790da3f6b93d3cfa503a6de75d 100644 (file)
 
 #include <stdarg.h>
 
+#if defined(SDCC_MODEL_LARGE) || defined(SDCC_MODEL_FLAT24)
+#define XSPEC xdata
+#else
+#define XSPEC
+#endif
+
 extern printf_small (char *,...) reentrant;
-extern printf (const char *,...) reentrant;
+extern printf (XSPEC const char *,...) reentrant;
 extern int vprintf (const char *, va_list);
-extern int sprintf (const char *, const char *, ...) reentrant;
+extern int sprintf (const char *, XSPEC const char *, ...) reentrant;
 extern int vsprintf (const char *, const char *, va_list);
 extern int puts(const char *);
+extern char *gets(char *);
+extern char getchar(void);
+extern void putchar(char);
 #endif
 
 
index 3ac885b206b75644200243bf9af974791244ffae..d73ff859681a9809adbe3d48b7cab9c299a85232 100644 (file)
@@ -50,14 +50,15 @@ OBJECTS             = _atoi.rel _atol.rel _autobaud.rel _bp.rel _char2fs.rel \
                  _strncpy.rel _strpbrk.rel _strrchr.rel _strspn.rel \
                  _strstr.rel _strtok.rel _uchar2fs.rel _uint2fs.rel \
                  _ulong2fs.rel malloc.rel serial.rel ser_ir.rel printfl.rel \
-                 printf_large.rel vprintf.rel puts.rel assert.rel _strcat.rel
+                 printf_large.rel vprintf.rel puts.rel gets.rel \
+                 assert.rel _strcat.rel
 SOURCES                = $(patsubst %.rel,%.c,$(OBJECTS))
 
 include incl.mk
 
 # Compiling entire program or any subproject
 # ------------------------------------------
-all: checkconf models
+all: checkconf models modelDS390
 
 objects: $(OBJECTS)
 
@@ -70,6 +71,14 @@ models:
          mv *.cdb $$model; \
        done
 
+modelDS390:
+       test -d ds390 || mkdir ds390
+       $(MAKE) CFLAGS="$(CFLAGS) -mds390 --model-flat24 \
+               --stack-10bit" objects
+       cd ds390; $(MAKE)
+       cp *.lib ds390
+       mv *.rel *.asm *.cdb ds390
+
 # Compiling and installing everything and runing test
 # ---------------------------------------------------
 install: installdirs
@@ -80,6 +89,8 @@ install: installdirs
         $(CP) $$model/*.asm $(datadir)/lib/$$model/; \
         $(CP) $$model/*.cdb $(datadir)/lib/$$model/; \
        done
+       $(MAKE) modelDS390 
+       $(CP) ds390/*.lib ds390/*.rel ds390/*.asm ds390/*.cbd $(datadir)/lib/ds390
 
 
 # Deleting all the installed files
@@ -89,6 +100,7 @@ uninstall:
        for model i $(MODELS); do \
          rm -rf $(datadir)/lib/$$model; \
        done
+       rm -rf $(datadir)/lib/ds390
 
 
 # Performing self-test
@@ -109,7 +121,7 @@ installdirs:
         [ -d $(datadir)/lib/$$model ] || \
         mkdir -p $(datadir)/lib/$$model; \
        done
-
+       [ -d $(datadir)/lib/ds390 ] || mkdir -p $(datadir)/lib/ds390
 
 # Creating dependencies
 # ---------------------
index c3d26ea6a8cffbf5283a56223b8a8ce53c096597..6b4e3c15a3e039dd183dabd5acf1b629e58562dc 100644 (file)
@@ -9,13 +9,14 @@ clean:
        for model in $(MODELS); do \
          rm -rf $$model; \
        done
+       cd ds390; make clean
 
 
 # Deleting all files created by configuring or building the program
 # -----------------------------------------------------------------
 distclean: clean
        rm -f Makefile *.dep
-
+       rm -f ds390/*.dep
 
 # Like clean but some files may still exist
 # -----------------------------------------
diff --git a/device/lib/ds390/Makefile b/device/lib/ds390/Makefile
new file mode 100755 (executable)
index 0000000..e33674b
--- /dev/null
@@ -0,0 +1,47 @@
+CC = ../../../bin/sdcc
+
+#VERBOSE = --verbose
+
+OBJECTS = startup390.rel serial390.rel 
+
+SOURCES = $(patsubst %.rel,%.c,$(OBJECTS))
+
+CPPFLAGS = -I../../include
+CFLAGS = -mds390 \
+        --model-flat24 \
+        --stack-10bit \
+        $(CPPFLAGS) $(VERBOSE)
+
+all: $(OBJECTS) libds390.lib
+
+clean:
+       rm -f *.lst *.rel *.sym *.cdb *.asm \#* *~ *.rst *.hex 
+       rm -f *.ihx temp.lnk *.map *.lib
+
+superclean:
+       make clean ; rm Makefile.dep
+
+libds390.lib: $(OBJECTS)
+       rm -f $@; \
+       for libfile in $(OBJECTS); do \
+               echo $$libfile >>$@; \
+       done;
+
+%.rel: %.c
+       $(CC) -c $(CFLAGS) $<
+
+# Creating dependencies
+# ---------------------
+depend: Makefile.dep
+
+Makefile.dep: $(SOURCES)
+       rm -f Makefile.dep
+       for i in $(SOURCES); do \
+         $(CC) -M $(CPPFLAGS) $$i >$${i}.dep; \
+         cat $${i}.dep >>Makefile.dep; \
+         rm $${i}.dep; \
+       done
+
+include Makefile.dep
+
+
diff --git a/device/lib/ds390/serial390.c b/device/lib/ds390/serial390.c
new file mode 100644 (file)
index 0000000..ffe7aed
--- /dev/null
@@ -0,0 +1,150 @@
+/*-------------------------------------------------------------------------
+  serial390.c - serial routines for the DS80C390 (tested on TINI)
+  
+   Written By - Johan Knol, johan.knol@iduna.nl
+    
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 2, or (at your option) any
+   later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  
+-------------------------------------------------------------------------*/
+
+// make sure that no int (16 bit) and long (32 bit) integer division, 
+// multiplication & modulus operations are used unless the lib-s are
+// compiled reentrant !!!!
+
+// if you want to changed defaults, do so in serial390.h
+
+#include <stdio.h>
+#include <ds80c390.h>
+#include <serial390.h>
+
+#if USE_SERIAL_INTERRUPTS
+
+// this is a ring buffer and can overflow at anytime!
+static volatile unsigned char receiveBuffer[SERIAL_RECEIVE_BUFFER_SIZE];
+static volatile int receiveBufferHead=0;
+static volatile int receiveBufferTail=0;
+// no buffering for transmit
+static volatile char transmitIsBusy=0;
+#endif
+
+void Serial390Init (void) {
+  
+  ES0 = 0; // disable serial channel 0 interrupt
+  TR1 = 0; // stop timer 1
+  
+  // set 8 bit uart with variable baud from timer 1
+  // enable receiver and clear RI and TI
+  SCON0 = 0x50;
+  
+  PCON |= 0x80; // clock is 16x bitrate
+  
+  TMOD = (TMOD&0x0f) | 0x20; // timer 1 is an 8bit auto-reload counter
+  
+  TL1 = TH1 = TIMER1_RELOAD_VALUE;
+  
+  TF1=0; // clear timer 1 overflow flag
+  TR1=1; // start timer 1
+  
+#if USE_SERIAL_INTERRUPTS
+  RI_0=TI_0=0; // clear "pending" interrupts
+  ES0 = 1; // enable serial channel 0 interrupt
+#else
+  RI_0=0; // receive buffer empty
+  TI_0=1; // transmit buffer empty
+#endif
+}
+
+#if USE_SERIAL_INTERRUPTS
+
+void Serial390Handler (void) interrupt 4 {
+  if (RI_0) {
+    receiveBuffer[receiveBufferHead]=SBUF0;
+    //receiveBufferHead=(receiveBufferHead+1)%SERIAL_RECEIVE_BUFFER_SIZE;
+    receiveBufferHead=(receiveBufferHead+1)&(SERIAL_RECEIVE_BUFFER_SIZE-1);
+    if (receiveBufferHead==receiveBufferTail) /* buffer overrun, sorry :) */
+      //receiveBufferTail=(receiveBufferTail+1)%SERIAL_RECEIVE_BUFFER_SIZE;
+      receiveBufferTail=(receiveBufferTail+1)&(SERIAL_RECEIVE_BUFFER_SIZE-1);
+    RI_0=0;
+  }
+  if (TI_0) {
+    TI_0=0;
+    transmitIsBusy=0;
+  }
+}
+
+void putchar (char c)
+{
+  while (transmitIsBusy)
+    ;
+  transmitIsBusy=1;
+  SBUF0=c;
+    _asm
+      cpl P3.5 ; toggle the TINI led
+    _endasm;
+}
+
+char getchar (void)
+{
+  char c;
+  while (receiveBufferHead==receiveBufferTail)
+    ;
+  c=receiveBuffer[receiveBufferTail];
+  ES0=0; // disable serial interrupts
+  //receiveBufferTail=(receiveBufferTail+1)%SERIAL_RECEIVE_BUFFER_SIZE;
+  receiveBufferTail=(receiveBufferTail+1)&(SERIAL_RECEIVE_BUFFER_SIZE-1);
+  ES0=1; // enable serial interrupts
+  return c;
+}
+
+#else //ifdef USE_SERIALINTERRUPTS
+
+// dummy interupt handler
+void Serial390Handler (void) interrupt 4 {
+  // how did we got here?
+  ES0=0; // disable serial interrupts
+}
+
+void putchar (char c) {
+  while (!TI_0)
+    ;
+  TI_0=0;
+  SBUF0=c;
+}
+
+char getchar (void) {
+  char c;
+  while (!RI_0)
+    ;
+  c=SBUF0;
+  RI_0=0;
+  return c;
+}
+
+#endif // ifdef USE_SERIALINTERRUPTS
+
+#if 0
+static char hex[]="0123456789abcdef";
+
+void putint (unsigned int i) {
+  putchar (hex[(i>>12)&0x0f]);
+  putchar (hex[(i>> 8)&0x0f]);
+  putchar (hex[(i>> 4)&0x0f]);
+  putchar (hex[(i    )&0x0f]);
+}
+
+#endif
diff --git a/device/lib/ds390/startup390.c b/device/lib/ds390/startup390.c
new file mode 100755 (executable)
index 0000000..63d2c55
--- /dev/null
@@ -0,0 +1,92 @@
+#include <ds80c390.h>
+#include <serial390.h>
+
+/* This routine is intended to setup the DS80C390 in contiguous addressing
+   mode, using a 10-bit stack (mapped to 0x400000).
+   It can be called from _sdcc_gs_init_startup in ANY mode.
+   Since it reinitializes the stack, it does a "ljmp" back to
+   __sdcc_init_data instead of returning. */
+
+
+unsigned char _sdcc_external_startup(void)
+{
+
+  // Let us assume we got here because the reset vector pointed to
+  // _sdcc_gsinit_startup. So, we are in 16-bit mode, 8051 stack.
+  // (not tested yet)
+  // 
+  // But it could as well have been a bootloader calling _sdcc_gsinit_startup
+  // at 0x10000 in 22-bit Contiguous Addressing Mode, 8051 or whatever stack.
+  // Hey :) that is a TINI!
+  // (tested "TINI loader 08-24-99 09:34" and "TINI loader 05-15-00 17:45")
+
+  // disable ALL interrupts
+  IE=0;
+
+  // use A19..16 and !CE3..0, no CAN
+  TA = 0xaa; // timed access
+  TA = 0x55;
+  P4CNT = 0x3f;
+  
+  // use !PCE3..0, serial 1 at P5.2/3
+  TA = 0xaa; // timed access
+  TA = 0x55;
+  P5CNT = 0x27;
+  
+  // disable watchdog
+  EWT=0;
+
+  // watchdog set to 9.1 seconds
+  // timers at 1/4 xtal
+  // no stretch-cycles for movx
+  CKCON = 0xf9;
+  
+  // use internal 4k RAM as stack memory at 0x400000 and
+  // move CANx Memory access to 0x401000 and upwards
+  TA = 0xaa; // timed access
+  TA = 0x55;
+  //MCON = 0xef; // program and/or data memory access
+  MCON = 0xaf; // data memory access only
+
+  PMR = 0x82; // two clocks per cycle
+  PMR = 0x92; // enable multiplier
+  while (!(EXIF&0x08))
+    // wait for multiplier to be ready
+    ;
+  PMR = 0x12; // one clock per cycle, xtal*2 
+
+  // Never mind port 2. If external hardware sets !MUX, it should take care
+  // of demultiplexing port 0 using !ALE as well, but we do not care...
+
+  // switch to: 
+  //   22-bit Contiguous Addressing Mode
+  //   10-bit Stack Mode
+  TA = 0xaa; // timed access
+  TA = 0x55;
+  ACON = 0x06;
+
+  // Set the stack to 0, although it is now mapped to 0x400000
+  // So be aware when accessing the stack !
+  ESP=SP=0; // note: we can not return from here anymore :)
+
+  // global interrupt enable, all masks cleared
+  // let the Gods be with you :)
+  IE = 0x80; 
+
+  // now that the stack is initialized, we can safely call
+  Serial390Init();
+
+  // I HATE this, but:
+  // We can do this safely because either AP is zero-ed when called from
+  // the reset vector, or should have been set by the bootloader to the bank
+  // in which we were called. We did not change it, so it will work as 
+  // long as we stay within the same (64k) bank.
+
+_asm
+  ljmp __sdcc_init_data
+_endasm;
+
+  // the compiler _SHOULD_ warn us if we did not do a:
+// return 0;
+}
+
diff --git a/device/lib/gets.c b/device/lib/gets.c
new file mode 100755 (executable)
index 0000000..7f4d0c0
--- /dev/null
@@ -0,0 +1,31 @@
+#include <stdio.h>
+
+char * gets(char *s) {
+  char c;
+  unsigned int count=0;
+  
+  while (1) {
+    c=getchar();
+    switch(c) {
+    case '\b': // backspace
+      if (count) {
+       putchar ('\b');
+       putchar (' ');
+       putchar ('\b');
+       s--;
+       count--;
+      }
+      break;
+    case '\n':
+    case '\r': // CR or LF
+      putchar('\r');
+      putchar('\n');
+      *s=0;
+      return s;
+    default:
+      *s++=c;
+      putchar(c);
+      break;
+    }
+  }
+}
index 18caa5eb5b34e21b08cdde7b33d9a792e87a673e..6f2231e72b6a2e3be3511b7cbf69c7613380777e 100644 (file)
@@ -1 +1 @@
-MODELS         = small large flat24
+MODELS         = small large flat24 
index 42aa85d9afc6aa1978281c3359cc41582d8eabef..8a95b82efe757597e473ae1655508d43e6db5229 100644 (file)
@@ -36,6 +36,8 @@ serial
 _autobaud
 _startup
 _ser
+puts
+gets
 printfl
 printf_large
 vprintf
index ce799a3397e8b9218dce2e9537777846c32cbf68..6697ca96e0cc6b51b8139fdf6de1be708af5b023 100644 (file)
 #include <stdarg.h>
 #include <stdio.h>
 
-int printf (const char *format, ...) reentrant
+#if defined(SDCC_MODEL_LARGE) || defined(SDCC_MODEL_FLAT24)
+#define XSPEC xdata
+#else
+#define XSPEC
+#endif
+
+int printf (XSPEC const char *format, ...) reentrant
 {
   va_list arg;
   int done;
@@ -37,7 +43,7 @@ int printf (const char *format, ...) reentrant
   return done;
 }
 
-int sprintf (const char *buf, const char *format, ...) reentrant
+int sprintf (const char *buf, XSPEC const char *format, ...) reentrant
 {
   va_list arg;
   int done;
index 9977d8abbc827dfffb1ec9e23fbdafd27935158c..88ac993bae9f3d39892b3cdaafec596ce0e90ec9 100644 (file)
@@ -27,8 +27,6 @@
 #include <ctype.h>
 #include <stdio.h>
 
-extern void putchar(const char);
-
 #define PTR value.p 
 
 /****************************************************************************/
index 9f42bb5dc0ca6e2c046b97927dcd2359c895fbd2..be3101f9266bc5132a4ac2c28b480a2d0db2129b 100644 (file)
@@ -1165,21 +1165,25 @@ static void linkEdit (char **envp)
        fprintf(lnkfile,"%s\n",linkOptions[i]);
 
     /* standard library path */
-    switch(options.model)
-    {
+    if (strcmp(port->target,"ds390")==0) {
+      c="ds390";
+    } else {
+      switch(options.model)
+       {
         case MODEL_SMALL:
-                   c = "small";
-                   break;
+         c = "small";
+         break;
                case MODEL_LARGE:
-                   c = "large";
-                   break;
+         c = "large";
+         break;
                case MODEL_FLAT24:
-                   c = "flat24";
-                   break;
+         c = "flat24";
+         break;
         default:
-            werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
-            c = "unknown";
-            break;
+         werror(W_UNKNOWN_MODEL, __FILE__, __LINE__);
+         c = "unknown";
+         break;
+       }
     }
     fprintf (lnkfile,"-k %s/%s\n",SDCC_LIB_DIR/*STD_LIB_PATH*/,c);
            
@@ -1188,6 +1192,9 @@ static void linkEdit (char **envp)
        fprintf (lnkfile,"-k %s\n",libPaths[i]);
         
     /* standard library files */
+    if (strcmp(port->target, "ds390")==0) {
+      fprintf (lnkfile,"-l %s\n",STD_DS390_LIB);
+    }
     fprintf (lnkfile,"-l %s\n",STD_LIB);
     fprintf (lnkfile,"-l %s\n",STD_INT_LIB);
     fprintf (lnkfile,"-l %s\n",STD_LONG_LIB);