More support for DS80C400
authorkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 27 Jun 2003 20:33:05 +0000 (20:33 +0000)
committerkvigor <kvigor@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 27 Jun 2003 20:33:05 +0000 (20:33 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2715 4a8a32a2-be11-0410-ad9d-d568d2c75423

15 files changed:
ChangeLog
device/examples/ds400/monitor400/Makefile [new file with mode: 0644]
device/examples/ds400/monitor400/mon400.c [new file with mode: 0644]
device/include/ds400rom.h [new file with mode: 0644]
device/include/tinibios.h
device/lib/ds400/Makefile
device/lib/ds400/ds400rom.c [new file with mode: 0644]
device/lib/ds400/tinibios.c
src/SDCCopt.c
src/SDCCpeeph.c
src/ds390/gen.c
src/ds390/main.c
support/cpp2/cpplib.c
support/cpp2/cpplib.h
support/cpp2/cppmacro.c

index fd21ca5aebc9fab4d080c69e5411cb0dfc9b1154..c3451510f36ecd6591b02e49b5b8dcfb93aba7a1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-06-27 Kevin Vigor <kevin@vigor.nu>
+
+       * More support for DS80C400. Now includes beginning of interface to ROM.
+
 2003-06-25  Bernhard Held <bernhard@bernhardheld.de>
 
        * src/mcs51/gen.c (gencjneshort): fixed bug #760345
diff --git a/device/examples/ds400/monitor400/Makefile b/device/examples/ds400/monitor400/Makefile
new file mode 100644 (file)
index 0000000..625cca0
--- /dev/null
@@ -0,0 +1,21 @@
+CC = ../../../../bin/sdcc
+
+MFLAGS = -mds400
+LFLAGS = --xram-loc 0x10000 --code-loc 0x400000 -Wl-r
+
+OBJECTS = mon400.rel
+
+all: mon400.hex
+
+clean:
+       rm -f *~ \#* *.asm *.cdb *.rel *.hex *.ihx *.lst *.map *.rst *.sym *.lnk
+
+mon400.hex: mon400.ihx
+       packihx mon400.ihx >mon400.hex
+
+mon400.ihx: $(OBJECTS)
+       $(CC) $(MFLAGS) $(LFLAGS) $(OBJECTS)
+
+%.rel: %.c
+       $(CC) -c $(MFLAGS) $<
+
diff --git a/device/examples/ds400/monitor400/mon400.c b/device/examples/ds400/monitor400/mon400.c
new file mode 100644 (file)
index 0000000..15b05fb
--- /dev/null
@@ -0,0 +1,58 @@
+#include <tinibios.h>
+#include <ds400rom.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#define BUF_LEN 80
+
+void usage(void)
+{
+    puts("Available commands:\n");
+    puts("ledon: turns LED on.");
+    puts("ledoff: turns LED off.");
+}
+
+void main(void)
+{
+    char buffer[80];
+    
+    // At this stage, the rom isn't initalized. We do have polled serial I/O, though.
+    printf("TINIm400 monitor rev 0.0\n");
+
+    // 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();
+
+    while (1)
+    {
+       // monitor prompt.
+        printf("-> ");
+       
+       gets(buffer); // unsafe, of course, should use some equivalent of fgets.
+       
+       if (!strcmp(buffer, "ledon"))
+       {
+           P5 &= ~4; // LED on.
+           printf("LED on.\n");
+       }
+       else if (!strcmp(buffer, "ledoff"))
+       {
+           P5 |= 4;
+           printf("LED off.\n");
+       }
+       else if (buffer[0])
+       {
+           printf("Unknown command \"%s\".\n", buffer);
+           usage();
+       }
+    }
+}
diff --git a/device/include/ds400rom.h b/device/include/ds400rom.h
new file mode 100644 (file)
index 0000000..20a679b
--- /dev/null
@@ -0,0 +1,18 @@
+// Interface to DS80C400 ROM functions.
+
+#ifndef DS400ROM_H_
+#define DS400ROM_H_
+
+extern unsigned char rom_init(void xdata *loMem,
+                             void xdata *hiMem) _naked;
+
+// Utility functions.
+
+// A wrapper which calls rom_init allocating all available RAM in CE0
+// to the heap.
+unsigned char romInit(unsigned char noisy);
+
+// Install an interrupt handler.
+void installInterrupt(void (*isrPtr)(void), unsigned char offset);
+
+#endif
index 810789fdf294850519da3de007f64b8508f6c7b0..2bc544a7fd9dfbbb7420e3203509b976c2684f86 100755 (executable)
@@ -16,6 +16,8 @@ void Serial0Baud(unsigned long baud);
 void Serial0SendBreak(void);
 void Serial0Flush(void);
 
+void Serial0SwitchToBuffered(void); // ds400 only.
+
 void Serial1Init (unsigned long baud, unsigned char buffered);
 char Serial1GetChar(void);
 void Serial1PutChar(char);
index 3bf3bfcce5d50dec97b28cf24365e9bd5f3d38a7..7925d0367481f0c7589e03c62ca3a6f135d34f19 100755 (executable)
@@ -2,7 +2,7 @@ CC = ../../../bin/sdcc
 
 #VERBOSE = --verbose
 
-OBJECTS = tinibios.rel memcpyx.rel
+OBJECTS = tinibios.rel memcpyx.rel ds400rom.rel
 
 SOURCES = $(patsubst %.rel,%.c,$(OBJECTS))
 
diff --git a/device/lib/ds400/ds400rom.c b/device/lib/ds400/ds400rom.c
new file mode 100644 (file)
index 0000000..219d367
--- /dev/null
@@ -0,0 +1,366 @@
+// 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>
+
+// 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 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 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 ;
+}
+
+// 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
+
+
+// rom_init: the ds400 ROM_INIT ROM function.
+unsigned char rom_init(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 _rom_init_PARM_2
+       mov     dptr, #_rom_init_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        ;
+}
+
+// all other ROM functions should go here, using rom_init as a template...
+
+// 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 char xdata *start;
+    
+    start = (unsigned char xdata *) _xisegStart();     
+    start += _xisegLen();
+
+    return (void xdata *)start;
+}
+
+// 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 xdata *heapStart;
+    void xdata *heapEnd;
+    unsigned long heapLen; 
+    unsigned char rc;
+    
+    heapStart = _firstHeapByte();
+    heapEnd = (void xdata *)CE0_END;
+
+    rc = 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;
+}
+
+// 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 0623b9536c7a485653cc050dea6ac2c442d680db..0e3bdbcb66c318a882629ffc547255f6e1144d21 100755 (executable)
 -------------------------------------------------------------------------*/
 
 #include <tinibios.h>
+#include <ds400rom.h>
 
 #define TIMED_ACCESS(sfr,value) { TA=0xaa; TA=0x55; sfr=value; }
 
-// FIXME: Doesn't work, maybe?
-static 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;
-}
-
 unsigned char _sdcc_external_startup(void)
 {
-#if 0    
-    int i, j;
-
-    // Do some blinking of the LED.
-    for  (j = 0; j < 10; j++)
-    {
-       P5 |= 4;
-       for (i = 0; i < 32767; i++)
-       {
-           ;
-       }
-       P5 &= ~4;
-       for (i = 0; i < 32767; i++)
-       {
-           ;
-       }       
-    }
-#endif    
-    
     IE = 0; // Disable all interrupts.
+
+    PSW = 0;
     
   _asm
     ; save the 24-bit return address
@@ -118,16 +90,11 @@ void Serial0Init (unsigned long baud, unsigned char buffered) {
   // Need no port setup, done by boot rom.
   
   baud;
-  
-  // hack serial ISR in, no magic support for ISR routines yet.
-  //
-  // FIXME: this doesn't work, use only non-buffered mode!
-  
-  _installInterrupt(Serial0IrqHandler, 0x23);  
-    
+
   serial0Buffered=buffered;
  
  if (buffered) {
+    installInterrupt(Serial0IrqHandler, 0x23);
     RI_0=TI_0=0; // clear "pending" interrupts
     ES0 = 1; // enable serial channel 0 interrupt
   } else {
@@ -145,8 +112,21 @@ void Serial0Baud(unsigned long baud) {
   TR2=1; // start timer
 }  
 
+
+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 {
-  P5 |= 4;
   if (RI_0) {
     receive0Buffer[receive0BufferHead]=SBUF0;
     receive0BufferHead=(receive0BufferHead+1)&(S0RBS-1);
@@ -183,8 +163,9 @@ void Serial0PutChar (char c)
   } else {
     while (!TI_0)
       ;
+    TI_0 = 0;
     SBUF0=c;
-    TI_0=0;
+    // TI_0=0;
   }
 }
 
index 2e1ff9a6f2c65a1ef891b34b196723441501310d..ce59ec5732292088a803bdeb40f8991717c793e8 100644 (file)
@@ -925,7 +925,9 @@ eBBlockFromiCode (iCode * ic)
   if (!options.lessPedantic) {
     // this is a good place to check missing return values
     if (currFunc) {
-      if (!IS_VOID(currFunc->etype)) {
+      // the user is on his own with naked functions...
+      if (!IS_VOID(currFunc->etype)
+       && !FUNC_ISNAKED(currFunc->type)) {
        eBBlock *bp;
        // make sure all predecessors of the last block end in a return
        for (bp=setFirstItem(ebbs[saveCount-1]->predList); 
index 0a263f41d6d4732e3f4320824e86e6de70bfc54d..29942d3d7fc192df62773bab7583a89a12e8fa9e 100644 (file)
@@ -211,7 +211,8 @@ pcDistance (lineNode * cpos, char *lbl, bool back)
 /*-----------------------------------------------------------------*/
 FBYNAME (flat24bitModeAndPortDS390)
 {
-    return ((strcmp(port->target,"ds390") == 0) && 
+    return (((strcmp(port->target,"ds390") == 0) ||
+            (strcmp(port->target,"ds400") == 0)) && 
            (options.model == MODEL_FLAT24));
 }
 
@@ -220,7 +221,8 @@ FBYNAME (flat24bitModeAndPortDS390)
 /*-----------------------------------------------------------------*/
 FBYNAME (portIsDS390)
 {
-    return (strcmp(port->target,"ds390") == 0);
+    return ((strcmp(port->target,"ds390") == 0) ||
+           (strcmp(port->target,"ds400") == 0));
 }
 
 /*-----------------------------------------------------------------*/
index 129900af02a4545892cca3834652377a393108da..2adeded37d96058b67a1eb1c00ceae38e650e985 100644 (file)
@@ -8644,7 +8644,7 @@ genRightShiftLiteral (operand * left,
    && (shCount < (size * 8))
    && (size != 1)
    && (size != 2)
-   /* && (size != 4) in a minute... */)
+   && (size != 4))
   {
       D(emitcode (";", "genRightShiftLiteral wimping out"););  
       return FALSE;
index c0a0b148200694252a2283129ab0991775273445..de5d91e8b5fc2cadb6aa65aa69727304599c1b7b 100644 (file)
@@ -799,6 +799,10 @@ _ds400_finaliseOptions (void)
     if (options.parms_in_bank1) {
        addSet(&preArgvSet, Safe_strdup("-DSDCC_PARMS_IN_BANK1"));
     }
+     
+    // the DS400 rom calling interface uses register bank 3.
+    RegBankUsed[3] = 1;
+      
   }  /* MODEL_FLAT24 */
 }
 
index cb493105ae94e2461cd3dbe975e3bed40e0fee82..f0bc9cec6e1f886a4b8dd23ff14b313d37fbf81f 100644 (file)
@@ -97,6 +97,7 @@ static cpp_hashnode *lex_macro_node   PARAMS ((cpp_reader *));
 static void do_include_common  PARAMS ((cpp_reader *, enum include_type));
 static void do_pragma_once     PARAMS ((cpp_reader *));
 static void do_pragma_poison   PARAMS ((cpp_reader *));
+static void do_pragma_sdcc_hash PARAMS ((cpp_reader *));
 static void do_pragma_system_header    PARAMS ((cpp_reader *));
 static void do_pragma_dependency       PARAMS ((cpp_reader *));
 static int get__Pragma_string  PARAMS ((cpp_reader *, cpp_token *));
@@ -1025,6 +1026,9 @@ _cpp_init_internal_pragmas (pfile)
   cpp_register_pragma (pfile, "GCC", "poison", do_pragma_poison);
   cpp_register_pragma (pfile, "GCC", "system_header", do_pragma_system_header);
   cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
+    
+  /* Kevin abuse for SDCC. */
+  cpp_register_pragma(pfile, 0, "sdcc_hash", do_pragma_sdcc_hash);
 }
 
 static void
@@ -1126,6 +1130,28 @@ do_pragma_poison (pfile)
 #endif
 }
 
+static void
+do_pragma_sdcc_hash (pfile)
+     cpp_reader *pfile;
+{
+    cpp_token tok;
+    cpp_hashnode *hp;
+
+    _cpp_lex_token (pfile, &tok);
+    if (tok.type == CPP_PLUS)
+    {
+       CPP_OPTION(pfile, allow_naked_hash)++;
+    }
+    else if (tok.type == CPP_MINUS)
+    {
+       CPP_OPTION(pfile, allow_naked_hash)--;  
+    }
+    else
+    {
+       cpp_error (pfile, "invalid #pragma sdcc_hash directive, need '+' or '-'");
+    }
+}
+
 /* Mark the current header as a system header.  This will suppress
    some categories of warnings (notably those from -pedantic).  It is
    intended for use in system libraries that cannot be implemented in
index c05b5e2e431be5ba0ed77c8d9ffcd1d7bdd492bd..337d7d766402d1b12d28a02faa5faac33981fb5d 100644 (file)
@@ -384,6 +384,11 @@ struct cpp_options
      options.  Stand-alone CPP should then bail out after option
      parsing; drivers might want to continue printing help.  */
   unsigned char help_only;
+    
+  /* SDCC abuse by Kevin: allow naked '#' characters in expanded macros
+   * (see _cpp_create_definition in cppmacro.c)
+   */
+  unsigned char allow_naked_hash;
 };
 
 /* This structure is passed to the call back when changing file.  */
index 643aeefca3a0f9dcdb0ca74e30e2bf18e7319243..ed02b2ab2842b368d9a69a57a97016ee14c6089c 100644 (file)
@@ -1420,7 +1420,8 @@ _cpp_create_definition (pfile, node)
              macro->count--;
            }
          /* Let assembler get away with murder.  */
-         else if (CPP_OPTION (pfile, lang) != CLK_ASM)
+         else if ((CPP_OPTION (pfile, lang) != CLK_ASM)
+               && (!CPP_OPTION(pfile, allow_naked_hash)))
            {
              ok = 0;
              cpp_error (pfile, "'#' is not followed by a macro parameter");