From 604f0a48a1db36000a837cfd490010ae3795e237 Mon Sep 17 00:00:00 2001 From: johanknol Date: Wed, 23 Aug 2000 15:20:30 +0000 Subject: [PATCH] ds390 library support git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@334 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- device/include/serial390.h | 61 ++++++++++++++ device/include/stdio.h | 13 ++- device/lib/Makefile.in | 18 +++- device/lib/clean.mk | 3 +- device/lib/ds390/Makefile | 47 +++++++++++ device/lib/ds390/serial390.c | 150 ++++++++++++++++++++++++++++++++++ device/lib/ds390/startup390.c | 92 +++++++++++++++++++++ device/lib/gets.c | 31 +++++++ device/lib/incl.mk | 2 +- device/lib/libsdcc.lib | 2 + device/lib/printf_large.c | 10 ++- device/lib/vprintf.c | 2 - src/SDCCmain.c | 29 ++++--- 13 files changed, 438 insertions(+), 22 deletions(-) create mode 100644 device/include/serial390.h create mode 100755 device/lib/ds390/Makefile create mode 100644 device/lib/ds390/serial390.c create mode 100755 device/lib/ds390/startup390.c create mode 100755 device/lib/gets.c diff --git a/device/include/serial390.h b/device/include/serial390.h new file mode 100644 index 00000000..426379df --- /dev/null +++ b/device/include/serial390.h @@ -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 diff --git a/device/include/stdio.h b/device/include/stdio.h index 14b575af..6449820c 100644 --- a/device/include/stdio.h +++ b/device/include/stdio.h @@ -27,12 +27,21 @@ #include +#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 diff --git a/device/lib/Makefile.in b/device/lib/Makefile.in index 3ac885b2..d73ff859 100644 --- a/device/lib/Makefile.in +++ b/device/lib/Makefile.in @@ -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 # --------------------- diff --git a/device/lib/clean.mk b/device/lib/clean.mk index c3d26ea6..6b4e3c15 100644 --- a/device/lib/clean.mk +++ b/device/lib/clean.mk @@ -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 index 00000000..e33674bf --- /dev/null +++ b/device/lib/ds390/Makefile @@ -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 index 00000000..ffe7aed6 --- /dev/null +++ b/device/lib/ds390/serial390.c @@ -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 +#include +#include + +#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 index 00000000..63d2c55f --- /dev/null +++ b/device/lib/ds390/startup390.c @@ -0,0 +1,92 @@ +#include +#include + +/* 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 index 00000000..7f4d0c0b --- /dev/null +++ b/device/lib/gets.c @@ -0,0 +1,31 @@ +#include + +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; + } + } +} diff --git a/device/lib/incl.mk b/device/lib/incl.mk index 18caa5eb..6f2231e7 100644 --- a/device/lib/incl.mk +++ b/device/lib/incl.mk @@ -1 +1 @@ -MODELS = small large flat24 +MODELS = small large flat24 diff --git a/device/lib/libsdcc.lib b/device/lib/libsdcc.lib index 42aa85d9..8a95b82e 100644 --- a/device/lib/libsdcc.lib +++ b/device/lib/libsdcc.lib @@ -36,6 +36,8 @@ serial _autobaud _startup _ser +puts +gets printfl printf_large vprintf diff --git a/device/lib/printf_large.c b/device/lib/printf_large.c index ce799a33..6697ca96 100644 --- a/device/lib/printf_large.c +++ b/device/lib/printf_large.c @@ -25,7 +25,13 @@ #include #include -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; diff --git a/device/lib/vprintf.c b/device/lib/vprintf.c index 9977d8ab..88ac993b 100644 --- a/device/lib/vprintf.c +++ b/device/lib/vprintf.c @@ -27,8 +27,6 @@ #include #include -extern void putchar(const char); - #define PTR value.p /****************************************************************************/ diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 9f42bb5d..be3101f9 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -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); -- 2.30.2