From 60cb2e605644de2556d5b30c29ab62c566b96d1e Mon Sep 17 00:00:00 2001 From: kvigor Date: Fri, 27 Jun 2003 20:33:05 +0000 Subject: [PATCH] More support for DS80C400 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2715 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 4 + device/examples/ds400/monitor400/Makefile | 21 ++ device/examples/ds400/monitor400/mon400.c | 58 ++++ device/include/ds400rom.h | 18 ++ device/include/tinibios.h | 2 + device/lib/ds400/Makefile | 2 +- device/lib/ds400/ds400rom.c | 366 ++++++++++++++++++++++ device/lib/ds400/tinibios.c | 61 ++-- src/SDCCopt.c | 4 +- src/SDCCpeeph.c | 6 +- src/ds390/gen.c | 2 +- src/ds390/main.c | 4 + support/cpp2/cpplib.c | 26 ++ support/cpp2/cpplib.h | 5 + support/cpp2/cppmacro.c | 3 +- 15 files changed, 536 insertions(+), 46 deletions(-) create mode 100644 device/examples/ds400/monitor400/Makefile create mode 100644 device/examples/ds400/monitor400/mon400.c create mode 100644 device/include/ds400rom.h create mode 100644 device/lib/ds400/ds400rom.c diff --git a/ChangeLog b/ChangeLog index fd21ca5a..c3451510 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2003-06-27 Kevin Vigor + + * More support for DS80C400. Now includes beginning of interface to ROM. + 2003-06-25 Bernhard Held * 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 index 00000000..625cca04 --- /dev/null +++ b/device/examples/ds400/monitor400/Makefile @@ -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 index 00000000..15b05fb2 --- /dev/null +++ b/device/examples/ds400/monitor400/mon400.c @@ -0,0 +1,58 @@ +#include +#include + +#include +#include + +#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 index 00000000..20a679b7 --- /dev/null +++ b/device/include/ds400rom.h @@ -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 diff --git a/device/include/tinibios.h b/device/include/tinibios.h index 810789fd..2bc544a7 100755 --- a/device/include/tinibios.h +++ b/device/include/tinibios.h @@ -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); diff --git a/device/lib/ds400/Makefile b/device/lib/ds400/Makefile index 3bf3bfcc..7925d036 100755 --- a/device/lib/ds400/Makefile +++ b/device/lib/ds400/Makefile @@ -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 index 00000000..219d367e --- /dev/null +++ b/device/lib/ds400/ds400rom.c @@ -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 +#include + +// 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; +} diff --git a/device/lib/ds400/tinibios.c b/device/lib/ds400/tinibios.c index 0623b953..0e3bdbcb 100755 --- a/device/lib/ds400/tinibios.c +++ b/device/lib/ds400/tinibios.c @@ -25,43 +25,15 @@ -------------------------------------------------------------------------*/ #include +#include #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; } } diff --git a/src/SDCCopt.c b/src/SDCCopt.c index 2e1ff9a6..ce59ec57 100644 --- a/src/SDCCopt.c +++ b/src/SDCCopt.c @@ -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); diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index 0a263f41..29942d3d 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -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)); } /*-----------------------------------------------------------------*/ diff --git a/src/ds390/gen.c b/src/ds390/gen.c index 129900af..2adeded3 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -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; diff --git a/src/ds390/main.c b/src/ds390/main.c index c0a0b148..de5d91e8 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -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 */ } diff --git a/support/cpp2/cpplib.c b/support/cpp2/cpplib.c index cb493105..f0bc9cec 100644 --- a/support/cpp2/cpplib.c +++ b/support/cpp2/cpplib.c @@ -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 diff --git a/support/cpp2/cpplib.h b/support/cpp2/cpplib.h index c05b5e2e..337d7d76 100644 --- a/support/cpp2/cpplib.h +++ b/support/cpp2/cpplib.h @@ -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. */ diff --git a/support/cpp2/cppmacro.c b/support/cpp2/cppmacro.c index 643aeefc..ed02b2ab 100644 --- a/support/cpp2/cppmacro.c +++ b/support/cpp2/cppmacro.c @@ -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"); -- 2.39.5