ds390 library support
[fw/sdcc] / device / lib / ds390 / startup390.c
1 #include <ds80c390.h>
2 #include <serial390.h>
3
4 /* This routine is intended to setup the DS80C390 in contiguous addressing
5    mode, using a 10-bit stack (mapped to 0x400000).
6    It can be called from _sdcc_gs_init_startup in ANY mode.
7    Since it reinitializes the stack, it does a "ljmp" back to
8    __sdcc_init_data instead of returning. */
9
10
11 unsigned char _sdcc_external_startup(void)
12 {
13
14   // Let us assume we got here because the reset vector pointed to
15   // _sdcc_gsinit_startup. So, we are in 16-bit mode, 8051 stack.
16   // (not tested yet)
17   // 
18   // But it could as well have been a bootloader calling _sdcc_gsinit_startup
19   // at 0x10000 in 22-bit Contiguous Addressing Mode, 8051 or whatever stack.
20   // Hey :) that is a TINI!
21   // (tested "TINI loader 08-24-99 09:34" and "TINI loader 05-15-00 17:45")
22
23   // disable ALL interrupts
24   IE=0;
25
26   // use A19..16 and !CE3..0, no CAN
27   TA = 0xaa; // timed access
28   TA = 0x55;
29   P4CNT = 0x3f;
30   
31   // use !PCE3..0, serial 1 at P5.2/3
32   TA = 0xaa; // timed access
33   TA = 0x55;
34   P5CNT = 0x27;
35   
36   // disable watchdog
37   EWT=0;
38
39   // watchdog set to 9.1 seconds
40   // timers at 1/4 xtal
41   // no stretch-cycles for movx
42   CKCON = 0xf9;
43   
44   // use internal 4k RAM as stack memory at 0x400000 and
45   // move CANx Memory access to 0x401000 and upwards
46   TA = 0xaa; // timed access
47   TA = 0x55;
48   //MCON = 0xef; // program and/or data memory access
49   MCON = 0xaf; // data memory access only
50
51   PMR = 0x82; // two clocks per cycle
52   PMR = 0x92; // enable multiplier
53   while (!(EXIF&0x08))
54     // wait for multiplier to be ready
55     ;
56   PMR = 0x12; // one clock per cycle, xtal*2 
57
58   // Never mind port 2. If external hardware sets !MUX, it should take care
59   // of demultiplexing port 0 using !ALE as well, but we do not care...
60
61   // switch to: 
62   //   22-bit Contiguous Addressing Mode
63   //   10-bit Stack Mode
64   TA = 0xaa; // timed access
65   TA = 0x55;
66   ACON = 0x06;
67
68   // Set the stack to 0, although it is now mapped to 0x400000
69   // So be aware when accessing the stack !
70   ESP=SP=0; // note: we can not return from here anymore :)
71
72   // global interrupt enable, all masks cleared
73   // let the Gods be with you :)
74   IE = 0x80; 
75
76   // now that the stack is initialized, we can safely call
77   Serial390Init();
78
79   // I HATE this, but:
80   // We can do this safely because either AP is zero-ed when called from
81   // the reset vector, or should have been set by the bootloader to the bank
82   // in which we were called. We did not change it, so it will work as 
83   // long as we stay within the same (64k) bank.
84
85 _asm
86   ljmp __sdcc_init_data
87 _endasm;
88
89   // the compiler _SHOULD_ warn us if we did not do a:
90 // return 0;
91 }
92