Bug Reported And __critical Purged
I reported the bug just now. It’s at https://sourceforge.net/p/sdcc/bugs/2416/ .
Now I have to figure out how to handle critical sections.
For now, just two functions–di() and ei(). They will use a global variable uint8_t interruptDisableReferenceCount. If it’s 0, interrupts are enabled. It will initialize to 1.
I also dealt with the __interrupt bug where it doesn’t generate ei before reti.
Here is my interrupt.c file for now:
1 #include "tick.h"
2 #include "uart.h"
3 #include "membank.h"
4
5 /*
6 ; for crt0.s
7 .globl _do_RST_00H
8 .globl _do_RST_08H
9 .globl _do_RST_10H
10 .globl _do_RST_01H
11 .globl _do_RST_20H
12 .globl _do_RST_28H
13 .globl _do_RST_30H
14 .globl _do_RST_38H
15 .globl _do_NMI
16 */
17
18 uint8_t interruptDisableRefCount = 1;
19
20 void do_RST_00H()
21 {
22 }
23
24 void do_RST_08H()
25 {
26 }
27
28 void do_RST_10H()
29 {
30 }
31
32 void do_RST_18H()
33 {
34 }
35
36 void do_RST_20H()
37 {
38 }
39
40 void do_RST_28H()
41 {
42 }
43
44 void do_RST_30H()
45 {
46 }
47
48 // Has to be naked because __interrupt fails to generate the ei before the reti
49 void do_RST_38H() __naked
50 {
51 __asm__("push af");
52 __asm__("push bc");
53 __asm__("push de");
54 __asm__("push hl");
55 __asm__("push ix");
56 __asm__("push iy");
57
58 #ifdef INT_SAVE_ALT_REG
59 __asm__("exx");
60 __asm__("push af");
61 __asm__("push bc");
62 __asm__("push de");
63 __asm__("push hl");
64 __asm__("push ix");
65 __asm__("push iy");
66 #endif
67
68 //tickISR();
69 uartISR();
70
71 #ifdef INT_SAVE_ALT_REG
72 __asm__("pop iy");
73 __asm__("pop ix");
74 __asm__("pop hl");
75 __asm__("pop de");
76 __asm__("pop bc");
77 __asm__("pop af");
78 __asm__("exx");
79 #endif
80
81 __asm__("pop iy");
82 __asm__("pop ix");
83 __asm__("pop hl");
84 __asm__("pop de");
85 __asm__("pop bc");
86 __asm__("pop af");
87 __asm__("ei");
88 __asm__("reti");
89 }
90
91 void do_NMI() __interrupt __critical
92 {
93 //nmiISR();
94 }
95
96 void di() __naked
97 {
98 __asm__("push af");
99 __asm__("ld a, (_interruptDisableRefCount)");
100 __asm__("or a");
101 __asm__("jr nz, skip_di");
102 __asm__("di");
103 __asm__("skip_di:");
104 __asm__("inc a");
105 __asm__("ld (_interruptDisableRefCount), a");
106 __asm__("pop af");
107 __asm__("ret");
108 }
109
110 void ei() __naked
111 {
112 __asm__("push af");
113 __asm__("ld a, (_interruptDisableRefCount)");
114 __asm__("dec a");
115 __asm__("ld (_interruptDisableRefCount), a");
116 __asm__("or a");
117 __asm__("jr nz, skip_ei");
118 __asm__("pop af");
119 __asm__("ret");
120 __asm__("skip_ei:");
121 __asm__("pop af");
122 __asm__("ei");
123 __asm__("ret");
124 }
I have also purged __critical from my code and placed di() and ei() where I need it.