--- /dev/null
+/*-------------------------------------------------------------------------
+ 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
#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
_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)
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
$(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
for model i $(MODELS); do \
rm -rf $(datadir)/lib/$$model; \
done
+ rm -rf $(datadir)/lib/ds390
# Performing self-test
[ -d $(datadir)/lib/$$model ] || \
mkdir -p $(datadir)/lib/$$model; \
done
-
+ [ -d $(datadir)/lib/ds390 ] || mkdir -p $(datadir)/lib/ds390
# Creating dependencies
# ---------------------
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
# -----------------------------------------
--- /dev/null
+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
+
+
--- /dev/null
+/*-------------------------------------------------------------------------
+ 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
--- /dev/null
+#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;
+}
+
--- /dev/null
+#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;
+ }
+ }
+}
-MODELS = small large flat24
+MODELS = small large flat24
_autobaud
_startup
_ser
+puts
+gets
printfl
printf_large
vprintf
#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;
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;
#include <ctype.h>
#include <stdio.h>
-extern void putchar(const char);
-
#define PTR value.p
/****************************************************************************/
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);
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);