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:
#include "tick.h"
#include "uart.h"
#include "membank.h"
/*
; for crt0.s
.globl _do_RST_00H
.globl _do_RST_08H
.globl _do_RST_10H
.globl _do_RST_01H
.globl _do_RST_20H
.globl _do_RST_28H
.globl _do_RST_30H
.globl _do_RST_38H
.globl _do_NMI
*/
uint8_t interruptDisableRefCount = 1;
void do_RST_00H()
{
}
void do_RST_08H()
{
}
void do_RST_10H()
{
}
void do_RST_18H()
{
}
void do_RST_20H()
{
}
void do_RST_28H()
{
}
void do_RST_30H()
{
}
// Has to be naked because __interrupt fails to generate the ei before the reti
void do_RST_38H() __naked
{
__asm__("push af");
__asm__("push bc");
__asm__("push de");
__asm__("push hl");
__asm__("push ix");
__asm__("push iy");
#ifdef INT_SAVE_ALT_REG
__asm__("exx");
__asm__("push af");
__asm__("push bc");
__asm__("push de");
__asm__("push hl");
__asm__("push ix");
__asm__("push iy");
#endif
//tickISR();
uartISR();
#ifdef INT_SAVE_ALT_REG
__asm__("pop iy");
__asm__("pop ix");
__asm__("pop hl");
__asm__("pop de");
__asm__("pop bc");
__asm__("pop af");
__asm__("exx");
#endif
__asm__("pop iy");
__asm__("pop ix");
__asm__("pop hl");
__asm__("pop de");
__asm__("pop bc");
__asm__("pop af");
__asm__("ei");
__asm__("reti");
}
void do_NMI() __interrupt __critical
{
//nmiISR();
}
void di() __naked
{
__asm__("push af");
__asm__("ld a, (_interruptDisableRefCount)");
__asm__("or a");
__asm__("jr nz, skip_di");
__asm__("di");
__asm__("skip_di:");
__asm__("inc a");
__asm__("ld (_interruptDisableRefCount), a");
__asm__("pop af");
__asm__("ret");
}
void ei() __naked
{
__asm__("push af");
__asm__("ld a, (_interruptDisableRefCount)");
__asm__("dec a");
__asm__("ld (_interruptDisableRefCount), a");
__asm__("or a");
__asm__("jr nz, skip_ei");
__asm__("pop af");
__asm__("ret");
__asm__("skip_ei:");
__asm__("pop af");
__asm__("ei");
__asm__("ret");
}
I have also purged __critical from my code and placed di() and ei() where I need it.
No comments:
Post a Comment