From 856b88b89030bb496aaf9e21e39d98e5b48b9869 Mon Sep 17 00:00:00 2001 From: kvigor Date: Tue, 1 Jul 2003 21:12:35 +0000 Subject: [PATCH] DS800C400 fun, improved ROM interface and tinibios git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@2718 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 4 + device/examples/ds400/monitor400/mon400.c | 33 ++---- device/include/ds400rom.h | 33 ++++-- device/include/tinibios.h | 29 ++++- device/lib/ds400/ds400rom.c | 102 ++++-------------- device/lib/ds400/tinibios.c | 125 ++++++++++++++++++++-- src/SDCCglue.c | 7 ++ src/SDCCmain.c | 6 ++ src/avr/main.c | 1 + src/ds390/main.c | 24 +++++ src/mcs51/main.c | 1 + src/pic/main.c | 1 + src/pic16/main.c | 1 + src/port.h | 7 ++ src/xa51/main.c | 1 + src/z80/main.c | 2 + support/tests/dhrystone/dhry.c | 13 ++- 17 files changed, 253 insertions(+), 137 deletions(-) diff --git a/ChangeLog b/ChangeLog index c3451510..0976fe13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2003-07-01 Kevin Vigor + + * DS800C400 fun, improved ROM interface and tinibios. + 2003-06-27 Kevin Vigor * More support for DS80C400. Now includes beginning of interface to ROM. diff --git a/device/examples/ds400/monitor400/mon400.c b/device/examples/ds400/monitor400/mon400.c index 5f39556e..c0060ded 100644 --- a/device/examples/ds400/monitor400/mon400.c +++ b/device/examples/ds400/monitor400/mon400.c @@ -47,35 +47,14 @@ void main(void) { char buffer[80]; - // At this stage, the rom isn't initalized. We do have polled serial I/O, though. + // At this stage, the rom isn't initalized. We do have polled serial I/O, but that's + // about the only functional library service. printf("TINIm400 monitor rev 0.0\n"); - - P5 |= 4; // LED off. - - // double the cpu speed. - if (1) - { - PMR = 0x82; - PMR = 0x92; - - while (!(EXIF & 8)) - ; - - PMR = 0x12; - } - - // 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(); + romInit(1, SPEED_2X); + // Now we're cooking with gas. + while (1) { // monitor prompt. @@ -99,7 +78,7 @@ void main(void) } else if (!strcmp(buffer, "thread")) { - printf("Thread ID: %d\n", (int)DSS_getthreadID()); + printf("Thread ID: %d\n", (int)task_getthreadID()); } else if (!strcmp(buffer, "sleep")) { diff --git a/device/include/ds400rom.h b/device/include/ds400rom.h index 86d0f531..d96cd9f7 100644 --- a/device/include/ds400rom.h +++ b/device/include/ds400rom.h @@ -3,20 +3,33 @@ #ifndef DS400ROM_H_ #define DS400ROM_H_ -extern unsigned char DSS_rom_init(void xdata *loMem, - void xdata *hiMem) _naked; +extern unsigned char init_rom(void xdata *loMem, + void xdata *hiMem) _naked; -extern unsigned long DSS_gettimemillis(void) _naked; +extern unsigned long task_gettimemillis_long(void) _naked; -extern unsigned char DSS_getthreadID(void) _naked; +extern unsigned char task_getthreadID(void) _naked; -// Utility functions. +/** Timer reload value for 14.746 MHz crystal. */ +#define RELOAD_14_746 0xfb33 -// A wrapper which calls rom_init allocating all available RAM in CE0 -// to the heap. -unsigned char romInit(unsigned char noisy); +/** Timer reload value for 18.432 MHz crystal. */ +#define RELOAD_18_432 0xfa00 -// Install an interrupt handler. -void installInterrupt(void (*isrPtr)(void), unsigned char offset); +/** Timer reload value for 29.491 MHz crystal. */ +#define RELOAD_29_491 0xfd99 + +/** Timer reload value for 36.864 MHz crystal. */ +#define RELOAD_36_864 0xfd00 + +/** Timer reload value for 58.982 MHz crystal. */ +#define RELOAD_58_982 0xfecc + +/** Timer reload value for 73.728 MHz crystal. */ +#define RELOAD_73_728 0xfe80 + +extern unsigned int task_gettickreload(void); + +extern void task_settickreload(unsigned); #endif diff --git a/device/include/tinibios.h b/device/include/tinibios.h index 2bc544a7..c27837b6 100755 --- a/device/include/tinibios.h +++ b/device/include/tinibios.h @@ -38,7 +38,11 @@ void ClockMicroSecondsDelay(unsigned int us); #define SERIAL_1_RECEIVE_BUFFER_SIZE 64 // I know someone is fooling with the crystals -#define OSCILLATOR 18432000L +#if defined(SDCC_ds400) +# define OSCILLATOR 14745600L +#else +# define OSCILLATOR 18432000L +#endif /* Set the cpu speed in clocks per machine cycle, valid values are: 1024: Divide-by-1024 (power management) mode (screws ALL timers and serial) @@ -95,7 +99,30 @@ extern char i2cReceiveBuffer[I2C_BUFSIZE]; unsigned char _sdcc_external_startup(void); void Serial0IrqHandler (void) interrupt 4; void Serial1IrqHandler (void) interrupt 7; + +#if !defined(SDCC_ds400) void ClockInit(); void ClockIrqHandler (void) interrupt 1 _naked; +#endif + +#if defined(SDCC_ds400) +// functions for dealing with the ds400 ROM firmware. + +// A wrapper which calls rom_init allocating all available RAM in CE0 +// to the heap, sets the serial port to SERIAL_0_BAUD, sets up the +// millisecond timer, and diddles the clock multiplier. + +// Values for the romInit "speed" parameter. +#define SPEED_1X 0 /* no clock multiplier, normal speed. */ +#define SPEED_2X 1 /* 2x clock multiplier. */ +#define SPEED_4X 2 /* 4x clock, DOESN'T WORK ON TINIm400! */ + +unsigned char romInit(unsigned char noisy, + char speed); + +// Install an interrupt handler. +void installInterrupt(void (*isrPtr)(void), unsigned char offset); +#endif + #endif /* TINIBIOS_H */ diff --git a/device/lib/ds400/ds400rom.c b/device/lib/ds400/ds400rom.c index 0a91d1df..7bba973a 100644 --- a/device/lib/ds400/ds400rom.c +++ b/device/lib/ds400/ds400rom.c @@ -30,6 +30,14 @@ #include #include +// 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 @@ -334,8 +342,8 @@ _endasm; lcall __romredirect -// DSS_rom_init: the ds400 ROM_INIT ROM function. -unsigned char DSS_rom_init(void xdata *loMem, +// 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. @@ -348,8 +356,8 @@ _asm mov r2, dpx mov r1, dph mov r0, dpl - ; hiMem is in _DSS_rom_init_PARM_2 - mov dptr, #_DSS_rom_init_PARM_2 + ; hiMem is in _init_rom_PARM_2 + mov dptr, #_init_rom_PARM_2 mov r5, dpx mov r4, dph mov r3, dpl @@ -364,7 +372,7 @@ _endasm ; // DSS_gettimemillis: note that the ROM actually returns 5 bytes of time, // we're discarding the high byte here. -unsigned long DSS_gettimemillis(void) _naked +unsigned long task_gettimemillis_long(void) _naked { _asm ; no parameters to load. @@ -378,7 +386,7 @@ _asm _endasm; } -unsigned char DSS_getthreadID(void) _naked +unsigned char task_getthreadID(void) _naked { _asm ; no parameters to load. @@ -389,87 +397,13 @@ _asm _endasm; } - - -// 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 int task_gettickreload(void) { - unsigned char xdata *start; - - start = (unsigned char xdata *) _xisegStart(); - start += _xisegLen(); - - return (void xdata *)start; + return DSS_timerReload; } -// 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 task_settickreload(unsigned int rl) { - void xdata *heapStart; - void xdata *heapEnd; - unsigned long heapLen; - unsigned char rc; - - heapStart = _firstHeapByte(); - heapEnd = (void xdata *)CE0_END; - - rc = DSS_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; + DSS_timerReload = rl; } -// 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 eefc2038..1c059cf1 100755 --- a/device/lib/ds400/tinibios.c +++ b/device/lib/ds400/tinibios.c @@ -31,9 +31,6 @@ #define TIMED_ACCESS(sfr,value) { TA=0xaa; TA=0x55; sfr=value; } -#undef OSCILLATOR -#define OSCILLATOR 14745600 - unsigned char _sdcc_external_startup(void) { IE = 0; // Disable all interrupts. @@ -89,8 +86,7 @@ static data unsigned char serial0Buffered; */ -#define SERIAL0_BAUDRATE 115200 -#define TIMER_RELOAD (65536 - ((OSCILLATOR) / (32 * SERIAL0_BAUDRATE))) +#define TIMER_RELOAD (65536 - ((OSCILLATOR) / (32 * SERIAL_0_BAUD))) void Serial0Init (unsigned long baud, unsigned char buffered) { @@ -224,12 +220,125 @@ void ClockInit() { // we can't just use milliSeconds unsigned long ClockTicks(void) { - return DSS_gettimemillis(); + return task_gettimemillis_long(); } void ClockMilliSecondsDelay(unsigned long delay) { - unsigned long ms = DSS_gettimemillis() + delay; + unsigned long ms = task_gettimemillis_long() + delay; - while (ms > DSS_gettimemillis()) + 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; +} diff --git a/src/SDCCglue.c b/src/SDCCglue.c index c317fffc..7d7cda45 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -1668,6 +1668,13 @@ glue (void) fprintf (asmFile, "%s", iComments2); copyFile (asmFile, xidata->oFile); + /* If the port wants to generate any extra areas, let it do so. */ + if (port->extraAreas.genExtraAreaDeclaration) + { + port->extraAreas.genExtraAreaDeclaration(asmFile, + mainf && IFFUNC_HASBODY(mainf->type)); + } + /* copy the interrupt vector table */ if (mainf && IFFUNC_HASBODY(mainf->type)) { diff --git a/src/SDCCmain.c b/src/SDCCmain.c index abcd1bab..bda73ad7 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -1349,6 +1349,12 @@ linkEdit (char **envp) if ( (options.stack_loc) && (options.stack_loc<0x100) ) { WRITE_SEG_LOC ("SSEG", options.stack_loc); } + + /* If the port has any special linker area declarations, get 'em */ + if (port->extraAreas.genExtraAreaLinkOptions) + { + port->extraAreas.genExtraAreaLinkOptions(lnkfile); + } /* add the extra linker options */ fputStrSet(lnkfile, linkOptionsSet); diff --git a/src/avr/main.c b/src/avr/main.c index 9b377b50..73eb0ba6 100644 --- a/src/avr/main.c +++ b/src/avr/main.c @@ -194,6 +194,7 @@ PORT avr_port = { NULL, 0, }, + { NULL, NULL }, { -1, 1, 4, 1, 1, 0}, /* avr has an 8 bit mul */ diff --git a/src/ds390/main.c b/src/ds390/main.c index de5d91e8..285862e3 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -384,6 +384,7 @@ PORT ds390_port = NULL, 1 }, + { NULL, NULL }, { +1, 1, 4, 1, 1, 0 }, @@ -673,6 +674,7 @@ PORT tininative_port = NULL, 1 }, + { NULL, NULL }, { +1, 1, 4, 1, 1, 0 }, @@ -806,6 +808,27 @@ _ds400_finaliseOptions (void) } /* MODEL_FLAT24 */ } +extern char * iComments2; + +static void _ds400_generateRomDataArea(FILE *fp, bool isMain) +{ + /* Only do this for the file containing main() */ + if (isMain) + { + fprintf(fp, "%s", iComments2); + fprintf(fp, "; the direct data area used by the DS80c400 ROM code.\n"); + fprintf(fp, "%s", iComments2); + fprintf(fp, ".area ROMSEG (ABS,CON,DATA)\n\n"); + fprintf(fp, ".ds 24 ; 24 bytes of directs used starting at 0x68\n\n"); + } +} + +static void _ds400_linkRomDataArea(FILE *fp) +{ + fprintf(fp, "-b ROMSEG = 0x0068\n"); +} + + PORT ds400_port = { TARGET_ID_DS400, @@ -858,6 +881,7 @@ PORT ds400_port = NULL, 1 }, + { _ds400_generateRomDataArea, _ds400_linkRomDataArea }, { +1, 1, 4, 1, 1, 0 }, diff --git a/src/mcs51/main.c b/src/mcs51/main.c index 52048d1b..3857a4e5 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -277,6 +277,7 @@ PORT mcs51_port = NULL, 1 }, + { NULL, NULL }, { +1, 0, 4, 1, 1, 0 }, diff --git a/src/pic/main.c b/src/pic/main.c index 78cfda60..ff5bcd3d 100644 --- a/src/pic/main.c +++ b/src/pic/main.c @@ -395,6 +395,7 @@ PORT pic_port = NULL, 1 // code is read only }, + { NULL, NULL }, { +1, 1, 4, 1, 1, 0 }, diff --git a/src/pic16/main.c b/src/pic16/main.c index 4d2fb48f..d236fe6d 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -412,6 +412,7 @@ PORT pic16_port = NULL, 1 // code is read only }, + { NULL, NULL }, { +1, 1, 4, 1, 1, 0 }, diff --git a/src/port.h b/src/port.h index f3101ed6..835b55fb 100644 --- a/src/port.h +++ b/src/port.h @@ -149,6 +149,13 @@ typedef struct } mem; + struct + { + void (*genExtraAreaDeclaration)(FILE *, bool); + void (*genExtraAreaLinkOptions)(FILE *); + } + extraAreas; + /* stack related information */ struct { diff --git a/src/xa51/main.c b/src/xa51/main.c index d3aaa9ad..53b54359 100755 --- a/src/xa51/main.c +++ b/src/xa51/main.c @@ -258,6 +258,7 @@ PORT xa51_port = NULL, // default global map 1 }, + { NULL, NULL }, { -1, // stack grows down 0, // bank overhead NUY diff --git a/src/z80/main.c b/src/z80/main.c index 147dbbb4..2ff5b561 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -542,6 +542,7 @@ PORT z80_port = NULL, 1 }, + { NULL, NULL }, { -1, 0, 0, 4, 0, 2 }, @@ -636,6 +637,7 @@ PORT gbz80_port = NULL, 1 }, + { NULL, NULL }, { -1, 0, 0, 2, 0, 4 }, diff --git a/support/tests/dhrystone/dhry.c b/support/tests/dhrystone/dhry.c index 7b6cff8b..ad11ff83 100644 --- a/support/tests/dhrystone/dhry.c +++ b/support/tests/dhrystone/dhry.c @@ -126,15 +126,11 @@ void main(void) #if defined(SDCC_ds400) // Intialize the ROM. - if (romInit(1)) + if (romInit(1, SPEED_2X)) { // We're hosed. romInit will have printed an error, nothing more to do. return; } - - ClockInit(); - - P5 &= ~4; // LED on. #endif printf("[dhry]\n"); @@ -162,8 +158,11 @@ void main(void) #if DEBUG Number_Of_Runs = 1; #else - // Number_Of_Runs = 32766; - Number_Of_Runs = 2048; +#if defined(SDCC_ds400) + Number_Of_Runs = 10240; +#else + Number_Of_Runs = 32766; +#endif #endif runTime = clock(); -- 2.30.2