From: johanknol Date: Mon, 11 Sep 2000 17:58:46 +0000 (+0000) Subject: fixed tini loader 0515 IVT mapping X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=02028a31df0fec9fe8c2f084012a2f3e229fba45;p=fw%2Fsdcc fixed tini loader 0515 IVT mapping git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@351 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/device/lib/ds390/startup390.c b/device/lib/ds390/startup390.c index 63d2c55f..fdf983f1 100755 --- a/device/lib/ds390/startup390.c +++ b/device/lib/ds390/startup390.c @@ -3,90 +3,111 @@ /* This routine is intended to setup the DS80C390 in contiguous addressing mode, using a 10-bit stack (mapped to 0x400000). - It can be called from _sdcc_gs_init_startup in ANY mode. - Since it reinitializes the stack, it does a "ljmp" back to - __sdcc_init_data instead of returning. */ + It assumes that _sdcc_gsinit_startup is called from a boot loader + in 22-bit contiguous addressing mode */ +/* Uncomment this if you are using the tini loader 000515. Make sure + XSEG starts at 0x100080 or it will overwrite your IVT. This won't harm + if you are using the 990824 loader */ +#define TINI_LOADER_0515 unsigned char _sdcc_external_startup(void) { - - // Let us assume we got here because the reset vector pointed to - // _sdcc_gsinit_startup. So, we are in 16-bit mode, 8051 stack. - // (not tested yet) - // - // But it could as well have been a bootloader calling _sdcc_gsinit_startup - // at 0x10000 in 22-bit Contiguous Addressing Mode, 8051 or whatever stack. - // Hey :) that is a TINI! - // (tested "TINI loader 08-24-99 09:34" and "TINI loader 05-15-00 17:45") - - // disable ALL interrupts - IE=0; - - // use A19..16 and !CE3..0, no CAN - TA = 0xaa; // timed access - TA = 0x55; - P4CNT = 0x3f; - - // use !PCE3..0, serial 1 at P5.2/3 - TA = 0xaa; // timed access - TA = 0x55; - P5CNT = 0x27; - - // disable watchdog - EWT=0; - - // watchdog set to 9.1 seconds - // timers at 1/4 xtal - // no stretch-cycles for movx - CKCON = 0xf9; - - // use internal 4k RAM as stack memory at 0x400000 and - // move CANx Memory access to 0x401000 and upwards - TA = 0xaa; // timed access - TA = 0x55; - //MCON = 0xef; // program and/or data memory access - MCON = 0xaf; // data memory access only - - PMR = 0x82; // two clocks per cycle - PMR = 0x92; // enable multiplier - while (!(EXIF&0x08)) - // wait for multiplier to be ready - ; - PMR = 0x12; // one clock per cycle, xtal*2 - - // Never mind port 2. If external hardware sets !MUX, it should take care - // of demultiplexing port 0 using !ALE as well, but we do not care... - - // switch to: - // 22-bit Contiguous Addressing Mode - // 10-bit Stack Mode - TA = 0xaa; // timed access - TA = 0x55; - ACON = 0x06; - - // Set the stack to 0, although it is now mapped to 0x400000 - // So be aware when accessing the stack ! - ESP=SP=0; // note: we can not return from here anymore :) + IE=0; // disable ALL interrupts + + _asm + ; save the 24-bit return address + pop ar2; msb + pop ar1 + pop ar0; lsb + + ; use A19..16 and !CE3..0, no CAN + mov _TA,#0xaa; timed access + mov _TA,#0x55 + mov _P4CNT,#0x3f + + ; use !PCE3..0, serial 1 at P5.2/3 + mov _TA,#0xaa; timed access + mov _TA,#0x55 + mov _P5CNT,#0x27 + + ; disable watchdog + mov _EWT,#0x00 + + ; watchdog set to 9.1 seconds + ; timers at 1/4 xtal + ; no strech-cycles for movx + mov _CKCON,#0xf9; + + ; use internal 4k RAM as data(stack) memory at 0x400000 and + ; move CANx memory access to 0x401000 and upwards + ; use !CE* for program and/or data memory access + mov _TA,#0xaa; timed access + mov _TA,#0x55 + mov _MCON,#0xaf; + + mov _PMR,#0x82; two clocks per cycle + mov _PMR,#0x92; enable multiplier +_Startup390WaitForClock: + mov a,_EXIF + jnb acc.3,_Startup390WaitForClock; wait for multiplier to be ready + mov _PMR,#0x12; one clock per cycle, xtal*2 + + mov _TA,#0xaa; timed access + mov _TA,#0x55 + mov _ACON,#0x06; 24-bit addresses, 10-bit stack at 0x400000 + + mov _ESP,#0x00; reinitialize the stack + mov _SP,#0x00 + + ; restore the 24-bit return address + push ar0; lsb + push ar1 + push ar2; msb + _endasm; + +#ifdef TINI_LOADER_0515 + // Copy the Interrupt Vector Table (128 bytes) from 0x10000 to 0x100000 + // Make sure that XSEG starts at 0x100080 in this case! + _asm + push dpx + push dph + push dpl + push dps + push b + push acc + mov dps,#0x00 ; make sure no autoincrement in progress + mov dptr,#0x10000 ; from + inc dps ; switch to alternate dptr + mov dptr,#0x100000 ; to + mov b,#0x80 ; count + +_Startup390CopyIVT: + inc dps + movx a,@dptr + inc dptr + inc dps + movx @dptr,a + inc dptr + djnz b,_Startup390CopyIVT + + pop acc + pop b + pop dps + pop dpl + pop dph + pop dpx + _endasm; +#endif // global interrupt enable, all masks cleared - // let the Gods be with you :) + // let the Gods be with us :) IE = 0x80; - // now that the stack is initialized, we can safely call + // now that the stack is re-initialized, we can safely call Serial390Init(); - // I HATE this, but: - // We can do this safely because either AP is zero-ed when called from - // the reset vector, or should have been set by the bootloader to the bank - // in which we were called. We did not change it, so it will work as - // long as we stay within the same (64k) bank. - -_asm - ljmp __sdcc_init_data -_endasm; - - // the compiler _SHOULD_ warn us if we did not do a: -// return 0; + // signal _sdcc_gsinit_startup to initialize data (call _sdcc_init_data) + return 0; }