summaryrefslogtreecommitdiff
path: root/device/lib/ds400
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /device/lib/ds400
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'device/lib/ds400')
-rw-r--r--device/lib/ds400/Makefile67
-rw-r--r--device/lib/ds400/Makefile.dep9
-rw-r--r--device/lib/ds400/Makefile.in67
-rw-r--r--device/lib/ds400/ds400rom.c435
-rw-r--r--device/lib/ds400/memcpyx.c106
-rw-r--r--device/lib/ds400/tinibios.c352
6 files changed, 1036 insertions, 0 deletions
diff --git a/device/lib/ds400/Makefile b/device/lib/ds400/Makefile
new file mode 100644
index 0000000..1166d95
--- /dev/null
+++ b/device/lib/ds400/Makefile
@@ -0,0 +1,67 @@
+# libc/ds400 Makefile
+
+
+srcdir = .
+top_builddir = ../../..
+
+LIB_TYPE = RANLIB
+
+CC = $(top_builddir)/bin/sdcc
+
+# override PORTDIR defined by super (parent) makefile
+override PORTDIR = ../build/ds400
+
+#VERBOSE = --verbose
+
+OBJECTS = tinibios.rel memcpyx.rel ds400rom.rel
+
+SOURCES = $(patsubst %.rel,%.c,$(OBJECTS))
+
+CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../include/ds400
+CFLAGS = -mds400 $(CPPFLAGS) $(VERBOSE) --std-c11
+
+all: $(OBJECTS) $(PORTDIR)/libds400.lib
+
+clean:
+ rm -f *.lst *.rel *.sym *.cdb *.asm \#* *~ *.rst *.hex
+ rm -f *.ihx temp.lnk *.map *.lib
+
+distclean: clean
+ rm -f Makefile Makefile.dep
+
+$(PORTDIR)/libds400.lib: $(OBJECTS)
+ifeq ($(LIB_TYPE), SDCCLIB)
+ rm -f $@; \
+ $(top_builddir)/bin/sdcclib -a $@ $(OBJECTS)
+else
+ ifeq ($(LIB_TYPE), AR)
+ $(top_builddir)/bin/sdar -rcSD $@ $(OBJECTS)
+ else
+ ifeq ($(LIB_TYPE), RANLIB)
+ $(top_builddir)/bin/sdar -rcD $@ $(OBJECTS)
+ else
+ rm -f $@;
+ for libfile in $(basename $(OBJECTS)); do echo $$libfile >>$@; done
+ cp $(OBJECTS) $(PORTDIR)
+ endif
+ endif
+endif
+
+%.rel: %.c
+ $(CC) -c $(CFLAGS) $<
+
+# Creating dependencies
+# ---------------------
+depend: Makefile.dep
+
+Makefile.dep: $(SOURCES)
+ rm -f Makefile.dep
+ for i in $^; do \
+ $(CC) -M $(CPPFLAGS) $$i >$${i}.dep; \
+ cat $${i}.dep >>Makefile.dep; \
+ rm $${i}.dep; \
+ done
+
+ifeq "$(findstring $(MAKECMDGOALS),clean distclean)" ""
+ -include Makefile.dep
+endif
diff --git a/device/lib/ds400/Makefile.dep b/device/lib/ds400/Makefile.dep
new file mode 100644
index 0000000..4d596e6
--- /dev/null
+++ b/device/lib/ds400/Makefile.dep
@@ -0,0 +1,9 @@
+tinibios.rel: tinibios.c ../../include/tinibios.h \
+ ../../include/ds80c390.h ../../include/time.h \
+ ../../include/ds400/ds400rom.h ../../include/stdio.h \
+ ../../include/stdarg.h ../../include/sdcc-lib.h \
+ ../../include/asm/mcs51/features.h
+memcpyx.rel: memcpyx.c ../../include/string.h
+ds400rom.rel: ds400rom.c ../../include/stdio.h ../../include/stdarg.h \
+ ../../include/sdcc-lib.h ../../include/asm/mcs51/features.h \
+ ../../include/ds400/ds400rom.h
diff --git a/device/lib/ds400/Makefile.in b/device/lib/ds400/Makefile.in
new file mode 100644
index 0000000..f1c9324
--- /dev/null
+++ b/device/lib/ds400/Makefile.in
@@ -0,0 +1,67 @@
+# libc/ds400 Makefile
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+top_builddir = @top_builddir@
+
+LIB_TYPE = @LIB_TYPE@
+
+CC = $(top_builddir)/bin/sdcc
+
+# override PORTDIR defined by super (parent) makefile
+override PORTDIR = ../build/ds400
+
+#VERBOSE = --verbose
+
+OBJECTS = tinibios.rel memcpyx.rel ds400rom.rel
+
+SOURCES = $(patsubst %.rel,%.c,$(OBJECTS))
+
+CPPFLAGS = -I$(srcdir)/../../include -I$(srcdir)/../../include/ds400
+CFLAGS = -mds400 $(CPPFLAGS) $(VERBOSE) --std-c11
+
+all: $(OBJECTS) $(PORTDIR)/libds400.lib
+
+clean:
+ rm -f *.lst *.rel *.sym *.cdb *.asm \#* *~ *.rst *.hex
+ rm -f *.ihx temp.lnk *.map *.lib
+
+distclean: clean
+ rm -f Makefile Makefile.dep
+
+$(PORTDIR)/libds400.lib: $(OBJECTS)
+ifeq ($(LIB_TYPE), SDCCLIB)
+ rm -f $@; \
+ $(top_builddir)/bin/sdcclib -a $@ $(OBJECTS)
+else
+ ifeq ($(LIB_TYPE), AR)
+ $(top_builddir)/bin/sdar -rcSD $@ $(OBJECTS)
+ else
+ ifeq ($(LIB_TYPE), RANLIB)
+ $(top_builddir)/bin/sdar -rcD $@ $(OBJECTS)
+ else
+ rm -f $@;
+ for libfile in $(basename $(OBJECTS)); do echo $$libfile >>$@; done
+ cp $(OBJECTS) $(PORTDIR)
+ endif
+ endif
+endif
+
+%.rel: %.c
+ $(CC) -c $(CFLAGS) $<
+
+# Creating dependencies
+# ---------------------
+depend: Makefile.dep
+
+Makefile.dep: $(SOURCES)
+ rm -f Makefile.dep
+ for i in $^; do \
+ $(CC) -M $(CPPFLAGS) $$i >$${i}.dep; \
+ cat $${i}.dep >>Makefile.dep; \
+ rm $${i}.dep; \
+ done
+
+ifeq "$(findstring $(MAKECMDGOALS),clean distclean)" ""
+ -include Makefile.dep
+endif
diff --git a/device/lib/ds400/ds400rom.c b/device/lib/ds400/ds400rom.c
new file mode 100644
index 0000000..49fb8e3
--- /dev/null
+++ b/device/lib/ds400/ds400rom.c
@@ -0,0 +1,435 @@
+/*-------------------------------------------------------------------------
+ ds400rom.c
+
+ Copyright (C) 2003, Dallas Semiconductor Corporation
+
+ This library 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 library 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 library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+// Interface to the DS80C400 ROM functions. Largely based on code released
+// by Dallas, hence the following copyright.
+
+// ---------------------------------------------------------------------------
+// Copyright (C) 2003 Dallas Semiconductor Corporation, All Rights Reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
+// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+//
+// Except as contained in this notice, the name of Dallas Semiconductor
+// shall not be used except as stated in the Dallas Semiconductor
+// Branding Policy.
+// ---------------------------------------------------------------------------
+
+#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
+#define R2_B3 0x1A
+#define R3_B3 0x1B
+#define R4_B3 0x1C
+#define R5_B3 0x1D
+#define R6_B3 0x1E
+#define R7_B3 0x1F
+
+
+// The top of the redirect function table in RAM.
+#define CALL_TABLE_TOP 256
+
+// The bank the ROM is stored in. Should be 0FFh for production
+// 400's. Change this value when running with a debug ROM.
+
+#define ROM_BANK 0xFF
+
+// The address of the ROM export table is stored
+// at (ROM_BANK << 16) | ROM_EXPORTTABLE_OFFS
+
+#define ROM_EXPORTTABLE_OFFS 2
+
+//
+// Each entry in the ROM export table is 3 bytes.
+//
+#define ROMXT_ENTRYSIZE 3
+
+//
+// The number of functions in the ROM export table is stored
+// first in the export table.
+//
+#define ROMXT_NUMFUNCTIONS (0 * ROMXT_ENTRYSIZE)
+
+//
+// ROM EXPORT TABLE FUNCTIONS (denoted with ROMXT)
+//
+
+// UTILITY functions
+#define ROMXT_CRC16 (1 * ROMXT_ENTRYSIZE) //
+#define ROMXT_MEM_CLEAR_16 (2 * ROMXT_ENTRYSIZE) //
+#define ROMXT_MEM_COPY_16 (3 * ROMXT_ENTRYSIZE) //
+#define ROMXT_MEM_COMPARE (4 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ADD_DPTR1_16 (5 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_ADD_DPTR2_16 (6 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_SUB_DPTR1_16 (7 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_SUB_DPTR2_16 (8 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_GETPSEUDORANDOM (9 * ROMXT_ENTRYSIZE) //
+
+// MEMORY MGR
+#define ROMXT_KERNELMALLOC (10 * ROMXT_ENTRYSIZE) // not exposed
+#define ROMXT_KERNELFREE (11 * ROMXT_ENTRYSIZE) // not exposed
+#define ROMXT_MM_MALLOC (12 * ROMXT_ENTRYSIZE) // exposed as redirected function
+#define ROMXT_MM_MALLOC_DIRTY (13 * ROMXT_ENTRYSIZE) // exposed as redirected function
+#define ROMXT_MM_FREE (14 * ROMXT_ENTRYSIZE) // exposed as redirected function
+#define ROMXT_MM_DEREF (15 * ROMXT_ENTRYSIZE) // exposed as redirected function
+#define ROMXT_GETFREERAM (16 * ROMXT_ENTRYSIZE) // exposed as redirected function
+
+// SOCKET functions
+#define ROMXT_ROM_SOCKET (17 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_CLOSESOCKET (18 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_SENDTO (19 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_RECVFROM (20 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_CONNECT (21 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_BIND (22 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_LISTEN (23 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_ACCEPT (24 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_RECV (25 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_SEND (26 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_GETSOCKOPT (27 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_SETSOCKOPT (28 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_GETSOCKNAME (29 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_GETPEERNAME (30 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_CLEANUP (31 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_AVAIL (32 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_JOIN (33 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_LEAVE (34 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_PING (35 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_GETNETWORKPARAMS (36 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_SETNETWORKPARAMS (37 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_GETIPV6PARAMS (38 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_GETETHERNETSTATUS (39 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_GETTFTPSERVER (40 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_SETTFTPSERVER (41 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ETH_PROCESSINTERRUPT (42 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_ARP_GENERATEREQUEST (43 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_NET_ETH0_MAC_ID (44 * ROMXT_ENTRYSIZE) //
+
+// DHCP functions
+#define ROMXT_DHCP_INIT (45 * ROMXT_ENTRYSIZE) //
+#define ROMXT_DHCP_SETUP (46 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_DHCP_STARTUP (47 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_DHCP_RUN (48 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_DHCP_STATUS (49 * ROMXT_ENTRYSIZE) //
+#define ROMXT_DHCP_STOP (50 * ROMXT_ENTRYSIZE) //
+#define ROMXT_DHCPNOTIFY (51 * ROMXT_ENTRYSIZE) // empty redirect stub, not implemented
+
+// TFTP functions
+#define ROMXT_TFTP_INIT (52 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TFTP_FIRST (53 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TFTP_NEXT (54 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TFTP_MSG (55 * ROMXT_ENTRYSIZE) //
+
+// SCHEDULER functions
+#define ROMXT_TASK_GENESIS (56 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_GETCURRENT (57 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_GETPRIORITY (58 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_SETPRIORITY (59 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_FORK (60 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_KILL (61 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_SUSPEND (62 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_SLEEP (63 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TASK_SIGNAL (64 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_TASK_SWITCH_IN (65 * ROMXT_ENTRYSIZE) // empty redirect stub, not implemented
+#define ROMXT_ROM_TASK_SWITCH_OUT (66 * ROMXT_ENTRYSIZE) // empty redirect stub, not implemented
+#define ROMXT_ENTERCRITSECTION (67 * ROMXT_ENTRYSIZE) //
+#define ROMXT_LEAVECRITSECTION (68 * ROMXT_ENTRYSIZE) //
+
+// INIT functions
+#define ROMXT_ROM_INIT (69 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_COPYIVT (70 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ROM_REDIRECT_INIT (71 * ROMXT_ENTRYSIZE) //
+#define ROMXT_MM_INIT (72 * ROMXT_ENTRYSIZE) //
+#define ROMXT_KM_INIT (73 * ROMXT_ENTRYSIZE) //
+#define ROMXT_OW_INIT (74 * ROMXT_ENTRYSIZE) //
+#define ROMXT_NETWORK_INIT (75 * ROMXT_ENTRYSIZE) //
+#define ROMXT_ETH_INIT (76 * ROMXT_ENTRYSIZE) //
+#define ROMXT_INIT_SOCKETS (77 * ROMXT_ENTRYSIZE) //
+#define ROMXT_TICK_INIT (78 * ROMXT_ENTRYSIZE) //
+
+// Timer Interrupt vectors
+#define ROMXT_WOS_TICK (79 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_BLOB (80 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+
+// Maintenance functions
+#define ROMXT_WOS_IOPOLL (81 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_IP_PROCESSRECEIVEQUEUES (82 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_IP_PROCESSOUTPUT (83 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_TCP_RETRYTOP (84 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_ETH_PROCESSOUTPUT (85 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_IGMP_GROUPMAINTAINENCE (86 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_IP6_PROCESSRECEIVEQUEUES (87 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_IP6_PROCESSOUTPUT (88 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_PARAMBUFFER (89 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_RAM_TOP (90 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_BOOT_MEMBEGIN (91 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_BOOT_MEMEND (92 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+
+// 1-Wire
+#define ROMXT_OWM_FIRST (93 * ROMXT_ENTRYSIZE) //
+#define ROMXT_OWM_NEXT (94 * ROMXT_ENTRYSIZE) //
+#define ROMXT_OWM_RESET (95 * ROMXT_ENTRYSIZE) //
+#define ROMXT_OWM_BYTE (96 * ROMXT_ENTRYSIZE) //
+#define ROMXT_OWM_SEARCH (97 * ROMXT_ENTRYSIZE) // not implemented for C compiler
+#define ROMXT_OW_ROMID (98 * ROMXT_ENTRYSIZE) //
+
+// Misc, extras, late additions
+#define ROMXT_AUTOBAUD (99 * ROMXT_ENTRYSIZE)
+#define ROMXT_TFTP_CLOSE (100 * ROMXT_ENTRYSIZE)
+
+
+#define ROMRT_ENTRYSIZE 3
+
+//
+// ROM REDIRECT TABLE FUNCTIONS (denoted with ROMRT)
+//
+#define ROMRT_KERNELMALLOC ( 1 * ROMRT_ENTRYSIZE)
+#define ROMRT_KERNELFREE ( 2 * ROMRT_ENTRYSIZE)
+#define ROMRT_MALLOC ( 3 * ROMRT_ENTRYSIZE)
+#define ROMRT_FREE ( 4 * ROMRT_ENTRYSIZE)
+#define ROMRT_MALLOCDIRTY ( 5 * ROMRT_ENTRYSIZE)
+#define ROMRT_DEREF ( 6 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETFREERAM ( 7 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETTIMEMILLIS ( 8 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETTHREADID ( 9 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADRESUME (10 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADIOSLEEP (11 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADIOSLEEPNC (12 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADSAVE (13 * ROMRT_ENTRYSIZE)
+#define ROMRT_THREADRESTORE (14 * ROMRT_ENTRYSIZE)
+#define ROMRT_SLEEP (15 * ROMRT_ENTRYSIZE)
+#define ROMRT_GETTASKID (16 * ROMRT_ENTRYSIZE)
+#define ROMRT_INFOSENDCHAR (17 * ROMRT_ENTRYSIZE)
+#define ROMRT_IP_COMPUTECHECKSUM_SOFTWARE (18 * ROMRT_ENTRYSIZE)
+#define ROMRT_0 (19 * ROMRT_ENTRYSIZE) // undefined
+#define ROMRT_DHCPNOTIFY (20 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_CREATE (21 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_DUPLICATE (22 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_DESTROY (23 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_SWITCH_IN (24 * ROMRT_ENTRYSIZE)
+#define ROMRT_ROM_TASK_SWITCH_OUT (25 * ROMRT_ENTRYSIZE)
+#define ROMRT_OWIP_READCONFIG (26 * ROMRT_ENTRYSIZE)
+#define ROMRT_SETMACID (27 * ROMRT_ENTRYSIZE)
+#define ROMRT_UNDEREF (28 * ROMRT_ENTRYSIZE)
+
+
+#define GETC \
+ clr a \
+ movc a, @a+dptr
+
+
+// expects function number in R6_B3 (low byte) & R7_B3 (high byte)
+void _romcall(void) __naked
+{
+__asm
+ push dpx ; dptr0 preserved here
+ push dph
+ push dpl
+
+ ; point to the address of the table
+ mov dptr, #(ROM_BANK << 16 | ROM_EXPORTTABLE_OFFS)
+
+ push acc ; acc preserved here
+ push b ; b preserved here
+ inc dptr
+ GETC ; get the address of the table
+ push acc
+ inc dptr
+ GETC
+ add a, R6_B3 ; add function offset to the table
+ mov dpl, a
+ pop acc
+ addc a, R7_B3
+ mov dph, a
+
+ ;
+ ; dpx is the same, all in the same bank
+ ;
+ inc dptr ; get the target address of the function we want
+ GETC
+ mov b, a
+ inc dptr
+ GETC
+ mov R3_B3, a
+ mov R4_B3, b
+ mov R5_B3, dpx ; high byte does not change
+ pop b ; b restored here
+ pop acc ; acc restored here
+ pop dpl ; dptr0 preserved here
+ pop dph
+ pop dpx
+ push R3_B3 ; push the target address
+ push R4_B3
+ push R5_B3
+ ret ; this is not a ret, it is a call!
+
+ ; the called function ends with a ret which will return to our original caller.
+__endasm ;
+}
+
+// expects function number in R6_B3 (low byte) & R7_B3 (high byte)
+void _romredirect(void) __naked
+{
+__asm
+ push dpx
+ push dph
+ push dpl
+ push acc
+ ; dptr = CALL_TABLE_TOP + function offset.
+ mov a, #(CALL_TABLE_TOP & 0xff)
+ add a, R6_B3 ; add function offset to the table
+ mov dpl, a
+ mov a, #((CALL_TABLE_TOP >> 8) & 0xff)
+ addc a, R7_B3
+ mov dph, a
+ mov dpx, #((CALL_TABLE_TOP >> 16) & 0xff)
+ movx a, @dptr ; read high byte
+ mov R5_B3, a
+ inc dptr
+ movx a, @dptr ; read mid byte
+ mov R4_B3, a
+ inc dptr
+ movx a, @dptr ; read low byte
+ mov R3_B3, a
+ pop acc ; restore acc and dptr
+ pop dpl
+ pop dph
+ pop dpx
+ push R3_B3 ; push low byte of target address
+ push R4_B3
+ push R5_B3 ; push high byte of target address
+ ret ; this is not a ret, it is a call!
+
+ ; the called function ends with a ret which will return to our original caller.
+__endasm;
+}
+
+
+// This macro is invalid for the standard C preprocessor, since it
+// includes a hash character in the expansion, hence the SDCC specific
+// pragma.
+#pragma sdcc_hash +
+#define ROMCALL(x) \
+ mov R6_B3, #(x & 0xff) \
+ mov R7_B3, #((x >> 8) & 0xff) \
+ lcall __romcall
+
+#define ROMREDIRECT(x) \
+ mov R6_B3, #(x & 0xff) \
+ mov R7_B3, #((x >> 8) & 0xff) \
+ lcall __romredirect
+
+
+// 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.
+ loMem;
+ hiMem;
+
+__asm
+ ; load params.
+ ; loMem is already in DPTR.
+ mov r2, dpx
+ mov r1, dph
+ mov r0, dpl
+ ; hiMem is in _init_rom_PARM_2
+ mov dptr, #_init_rom_PARM_2
+ mov r5, dpx
+ mov r4, dph
+ mov r3, dpl
+
+ ROMCALL(ROMXT_ROM_INIT)
+
+ ; result is in acc, move to dpl for C convention.
+ mov dpl, a
+ ret
+__endasm ;
+}
+
+// DSS_gettimemillis: note that the ROM actually returns 5 bytes of time,
+// we're discarding the high byte here.
+unsigned long task_gettimemillis_long(void) __naked
+{
+__asm
+ ; no parameters to load.
+ ROMREDIRECT(ROMRT_GETTIMEMILLIS)
+ ; results in r4 - r0, return in DPTR/B
+ mov dpl, r0
+ mov dph, r1
+ mov dpx, r2
+ mov b, r3
+ ret
+__endasm;
+}
+
+unsigned char task_getthreadID(void) __naked
+{
+__asm
+ ; no parameters to load.
+ ROMREDIRECT(ROMRT_GETTHREADID)
+ ; results in acc, return in dpl
+ mov dpl, a
+ ret
+__endasm;
+}
+
+unsigned int task_gettickreload(void)
+{
+ return DSS_timerReload;
+}
+
+void task_settickreload(unsigned int rl)
+{
+ DSS_timerReload = rl;
+}
diff --git a/device/lib/ds400/memcpyx.c b/device/lib/ds400/memcpyx.c
new file mode 100644
index 0000000..2fc8d27
--- /dev/null
+++ b/device/lib/ds400/memcpyx.c
@@ -0,0 +1,106 @@
+/*-------------------------------------------------------------------------
+ memcpyx.c
+
+ Copyright (C) 2003, Kevin Vigor
+
+ This library 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 library 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 library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#include <string.h>
+
+// FIXME: can optimize even further on '400 with auto-increment/auto-toggle.
+
+void __xdata * memcpyx (
+ void __xdata * dst,
+ void __xdata * src,
+ int count
+ ) __naked
+{
+ /* Shut compiler up about unused parameters. */
+ dst; src; count;
+
+__asm
+ ; Destination is in DPTR. Save it on stack so we can return it at end.
+
+ push dpx
+ push dph
+ push dpl
+
+ mov dps, #0x1 ; Alternate DPTR.
+
+ ; count is in _memcpyx_PARM_3
+ mov dptr, #_memcpyx_PARM_3
+ movx a, @dptr
+ inc dptr
+ mov r2, a
+ movx a, @dptr
+ mov r3, a
+
+ ; src is in _memcpyx_PARM_2
+ mov dptr, #_memcpyx_PARM_2
+ movx a, @dptr
+ inc dptr
+ push acc
+ movx a, @dptr
+ inc dptr
+ push acc
+ movx a, @dptr
+ mov dpx1, a
+ pop dph1
+ pop dpl1
+
+ mov dps, #0x21 ; Current DPTR is alt DPTR, toggle after each op.
+
+ ; src is in alt DPTR, dst is in normal DPTR, count is in r2/r3.
+
+ ; If we have zero bytes to copy, quick out.
+ mov a, r2
+ orl a, r3
+ jz _memcpy_done
+
+ ; increment r3 if r2 != 0 (makes djnz end-of-loop sequence possible).
+ inc r3
+ cjne r2, #0x0, _memcpyx_loopTop
+ dec r3
+
+_memcpyx_loopTop:
+
+ movx a, @dptr
+ movx @dptr, a
+ inc dptr
+ inc dptr
+
+ djnz r2, _memcpyx_loopTop
+ djnz r3, _memcpyx_loopTop
+
+_memcpy_done:
+
+ mov dps, #0x0
+
+ pop dpl
+ pop dph
+ pop dpx
+ ret
+__endasm;
+
+}
diff --git a/device/lib/ds400/tinibios.c b/device/lib/ds400/tinibios.c
new file mode 100644
index 0000000..5d7ac7a
--- /dev/null
+++ b/device/lib/ds400/tinibios.c
@@ -0,0 +1,352 @@
+/*-------------------------------------------------------------------------
+ tinibios.c - startup and serial routines for the DS80C400 (tested on TINIM400)
+
+ Copyright (C) 2003, Johan Knol <johan.knol AT iduna.nl>
+
+ This library 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 library 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 library; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA.
+
+ As a special exception, if you link this library with other files,
+ some of which are compiled with SDCC, to produce an executable,
+ this library does not by itself cause the resulting executable to
+ be covered by the GNU General Public License. This exception does
+ not however invalidate any other reasons why the executable file
+ might be covered by the GNU General Public License.
+-------------------------------------------------------------------------*/
+
+#include <tinibios.h>
+#include <ds400rom.h>
+
+#include <stdio.h>
+
+#define TIMED_ACCESS(sfr,value) { TA=0xaa; TA=0x55; sfr=value; }
+
+unsigned char _sdcc_external_startup(void)
+{
+ IE = 0; // Disable all interrupts.
+
+ PSW = 0;
+
+ __asm
+ ; save the 24-bit return address
+ pop ar2; msb
+ pop ar1
+ pop ar0; lsb
+
+
+ mov _ESP,#0x00; reinitialize the stack
+ mov _SP,#0x00
+
+ ; restore the 24-bit return address
+ push ar0; lsb
+ push ar1
+ push ar2; msb
+ __endasm;
+
+ // Stub: call rom_init here, then fixup IVT.
+ //
+
+ Serial0Init(1, 0); // baud argument ignored.
+
+ IE = 0x80; // Enable interrupts.
+
+ return 0;
+}
+
+// now the serial0 stuff
+
+// just to make the code more readable
+#define S0RBS SERIAL_0_RECEIVE_BUFFER_SIZE
+
+// this is a ring buffer and can overflow at anytime!
+static volatile unsigned char receive0Buffer[S0RBS];
+static volatile int receive0BufferHead=0;
+static volatile int receive0BufferTail=0;
+// no buffering for transmit
+static volatile char transmit0IsBusy=0;
+
+static __data unsigned char serial0Buffered;
+
+/* Initialize serial0.
+
+ Available baudrates are from 110 upto 115200 (using 16-bit timer 2)
+ If baud==0, the port is disabled.
+
+ If buffered!=0, characters received are buffered using an interrupt
+*/
+
+
+#define TIMER_RELOAD (65536 - ((OSCILLATOR) / (32 * SERIAL_0_BAUD)))
+
+void Serial0Init (unsigned long baud, unsigned char buffered)
+{
+ ES0 = 0; // disable serial channel 0 interrupt
+
+#if 0
+ // Need no port setup, done by boot rom.
+ baud;
+#else
+ SCON0 = 0x5A; // 10 bit serial 0, use timer baud rate, enable recieving
+ RCAP2H = (TIMER_RELOAD >> 8) & 0xff;
+ RCAP2L = TIMER_RELOAD & 0xff;
+ T2CON = 0x30; // Enable timer 2 for serial port
+ TR2 = 1; // Set timer 2 to run
+
+ baud;
+#endif
+
+ serial0Buffered=buffered;
+
+ if (buffered) {
+ installInterrupt(Serial0IrqHandler, 0x23);
+ 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
+ }
+}
+
+void Serial0SwitchToBuffered(void)
+{
+ IE &= ~0x80;
+
+ serial0Buffered = 1;
+ installInterrupt(Serial0IrqHandler, 0x23);
+ RI_0=TI_0=0; // clear "pending" interrupts
+ ES0 = 1; // enable serial channel 0 interrupt
+
+ IE |= 0x80;
+}
+
+void Serial0IrqHandler (void) __interrupt 4
+{
+ if (RI_0) {
+ receive0Buffer[receive0BufferHead]=SBUF0;
+ receive0BufferHead=(receive0BufferHead+1)&(S0RBS-1);
+ if (receive0BufferHead==receive0BufferTail) {
+ /* buffer overrun, sorry :) */
+ receive0BufferTail=(receive0BufferTail+1)&(S0RBS-1);
+ }
+ RI_0=0;
+ }
+ if (TI_0) {
+ TI_0=0;
+ transmit0IsBusy=0;
+ }
+}
+
+char Serial0CharArrived(void)
+{
+ if (serial0Buffered) {
+ if (receive0BufferHead!=receive0BufferTail)
+ return receive0Buffer[receive0BufferTail];
+ } else {
+ if (RI_0)
+ return SBUF0;
+ }
+ return 0;
+}
+
+void Serial0PutChar (char c)
+{
+ if (serial0Buffered) {
+ while (transmit0IsBusy)
+ ;
+ transmit0IsBusy=1;
+ SBUF0=c;
+ } else {
+ while (!TI_0)
+ ;
+ TI_0 = 0;
+ SBUF0=c;
+ }
+}
+
+char Serial0GetChar (void)
+{
+ char c;
+ if (serial0Buffered) {
+ while (receive0BufferHead==receive0BufferTail)
+ ;
+ c=receive0Buffer[receive0BufferTail];
+ ES0=0; // disable serial interrupts
+ receive0BufferTail=(receive0BufferTail+1)&(S0RBS-1);
+ ES0=1; // enable serial interrupts
+ } else {
+ while (!RI_0)
+ ;
+ c=SBUF0;
+ RI_0=0;
+ }
+ return c;
+}
+
+void Serial0SendBreak()
+{
+ P3 &= ~0x02;
+ ClockMilliSecondsDelay(2);
+ P3 |= 0x02;
+}
+
+void Serial0Flush()
+{
+ ES0=0; // disable interrupts
+ receive0BufferHead=receive0BufferTail=0;
+ RI_0=0;
+ if (serial0Buffered) {
+ TI_0=0;
+ ES0=1; // enable interrupts
+ } else {
+ TI_0=1;
+ }
+}
+
+// now let's go for the clock stuff - on the DS400, we can just
+// use the ROM's millisecond timer, running off timer 0.
+//
+// for now, this timer runs too fast by about 20%. We need an implementation of
+// task_settickreload to fix this.
+
+void ClockInit()
+{
+ // nada, all done by DSS_rom_init
+}
+
+// we can't just use milliSeconds
+unsigned long ClockTicks(void)
+{
+ return task_gettimemillis_long();
+}
+
+void ClockMilliSecondsDelay(unsigned long delay)
+{
+ unsigned long ms = task_gettimemillis_long() + delay;
+
+ 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;
+}