fixed tini loader 0515 IVT mapping
[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 assumes that _sdcc_gsinit_startup is called from a boot loader
7    in 22-bit contiguous addressing mode */
8
9 /* Uncomment this if you are using the tini loader 000515. Make sure 
10    XSEG starts at 0x100080 or it will overwrite your IVT. This won't harm 
11    if you are using the 990824 loader */
12 #define TINI_LOADER_0515
13
14 unsigned char _sdcc_external_startup(void)
15 {
16   IE=0; // disable ALL interrupts
17
18   _asm
19     ; save the 24-bit return address
20     pop ar2; msb
21     pop ar1
22     pop ar0; lsb
23
24     ; use A19..16 and !CE3..0, no CAN
25     mov _TA,#0xaa; timed access
26     mov _TA,#0x55
27     mov _P4CNT,#0x3f
28
29     ; use !PCE3..0, serial 1 at P5.2/3
30     mov _TA,#0xaa; timed access
31     mov _TA,#0x55
32     mov _P5CNT,#0x27
33
34     ; disable watchdog
35     mov _EWT,#0x00
36
37     ; watchdog set to 9.1 seconds
38     ; timers at 1/4 xtal
39     ; no strech-cycles for movx
40     mov _CKCON,#0xf9;
41
42     ; use internal 4k RAM as data(stack) memory at 0x400000 and
43     ; move CANx memory access to 0x401000 and upwards
44     ; use !CE* for program and/or data memory access
45     mov _TA,#0xaa; timed access
46     mov _TA,#0x55
47     mov _MCON,#0xaf;
48
49     mov _PMR,#0x82; two clocks per cycle
50     mov _PMR,#0x92; enable multiplier
51 _Startup390WaitForClock:
52     mov a,_EXIF
53     jnb acc.3,_Startup390WaitForClock; wait for multiplier to be ready
54     mov _PMR,#0x12; one clock per cycle, xtal*2
55
56     mov _TA,#0xaa; timed access
57     mov _TA,#0x55
58     mov _ACON,#0x06; 24-bit addresses, 10-bit stack at 0x400000
59
60     mov _ESP,#0x00; reinitialize the stack
61     mov _SP,#0x00
62
63     ; restore the 24-bit return address
64     push ar0; lsb
65     push ar1
66     push ar2; msb
67   _endasm;
68
69 #ifdef TINI_LOADER_0515
70   // Copy the Interrupt Vector Table (128 bytes) from 0x10000 to 0x100000
71   // Make sure that XSEG starts at 0x100080 in this case!
72   _asm
73   push dpx
74   push dph
75   push dpl
76   push dps
77   push b
78   push acc
79   mov dps,#0x00 ; make sure no autoincrement in progress
80   mov dptr,#0x10000 ; from
81   inc dps ; switch to alternate dptr
82   mov dptr,#0x100000 ; to
83   mov b,#0x80 ; count
84
85 _Startup390CopyIVT:
86   inc dps
87   movx a,@dptr
88   inc dptr
89   inc dps
90   movx @dptr,a
91   inc dptr
92   djnz b,_Startup390CopyIVT
93
94   pop acc
95   pop b
96   pop dps
97   pop dpl
98   pop dph
99   pop dpx
100   _endasm;
101 #endif
102
103   // global interrupt enable, all masks cleared
104   // let the Gods be with us :)
105   IE = 0x80; 
106
107   // now that the stack is re-initialized, we can safely call
108   Serial390Init();
109
110   // signal _sdcc_gsinit_startup to initialize data (call _sdcc_init_data)
111   return 0; 
112 }
113