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.