From: epetrich Date: Wed, 4 Aug 2004 21:05:21 +0000 (+0000) Subject: * src/z80/main.c: enabled "critical" keyword X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=67a7d48073f066e319f43a8e8e4e827d5c88afd3;p=fw%2Fsdcc * src/z80/main.c: enabled "critical" keyword * src/z80/mappings.i, * src/z80/gen.c (genFunction, genEndFunction): support for interrupt functions (fixes bug #979646) * doc/sdccman.lyx: added a subsection explaining z80 interrupt support git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3420 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 1821e22f..0fc53ce6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2004-08-04 Erik Petrich + * src/z80/main.c: enabled "critical" keyword + * src/z80/mappings.i, + * src/z80/gen.c (genFunction, genEndFunction): support for interrupt + functions (fixes bug #979646) + * doc/sdccman.lyx: added a subsection explaining z80 interrupt support + 2004-08-04 Jesus Calvino-Fraga * src/mcs51/gen.c (genInline): Add \n for labels, not DOS/WIN dirs diff --git a/doc/sdccman.lyx b/doc/sdccman.lyx index 75d1494e..582b8366 100644 --- a/doc/sdccman.lyx +++ b/doc/sdccman.lyx @@ -10340,6 +10340,41 @@ Since the number of interrupts available is chip specific and the interrupt \end_inset for details on customizing startup. +\layout Subsection + +Z80 Interrupt Service Routines +\layout Standard + +The Z80 uses several different methods for determining the correct interrupt + vector depending on the hardware implementation. + Therefore, SDCC ignores the optional interrupt number and does not attempt + to generate an interrupt vector table. +\layout Standard + +By default, SDCC generates code for a maskable interrupt, which uses an + RETI instruction to return from the interrupt. + To write an interrupt handler for the non-maskable interrupt, which needs + an RETN instruction instead, add the +\emph on +critical +\emph default + keyword: +\layout Verse + + +\family typewriter +void nmi_isr (void) critical interrupt +\newline +{ +\newline +\SpecialChar ~ +\SpecialChar ~ +\SpecialChar ~ +\SpecialChar ~ +... + +\newline +} \layout Section Enabling and Disabling Interrupts diff --git a/src/z80/gen.c b/src/z80/gen.c index 127bc13f..2818150f 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -3113,14 +3113,21 @@ genFunction (iCode * ic) ftype = operandType (IC_LEFT (ic)); - /* if critical function then turn interrupts off */ - if (IFFUNC_ISCRITICAL (ftype)) - emit2 ("!di"); - /* if this is an interrupt service routine then save all potentially used registers. */ if (IFFUNC_ISISR (sym->type)) { - emit2 ("!pusha"); + if (!FUNC_ISNAKED( sym->type )) + { + emit2 ("!pusha"); + } + } + else + { + /* if critical function then turn interrupts off */ + if (IFFUNC_ISCRITICAL (sym->type)) + { + emit2 ("!di"); + } } /* PENDING: callee-save etc */ @@ -3218,64 +3225,80 @@ genEndFunction (iCode * ic) { symbol *sym = OP_SYMBOL (IC_LEFT (ic)); - if (IFFUNC_ISISR (sym->type)) + + /* PENDING: calleeSave */ + if (IS_Z80 && _G.omitFramePtr) { - wassertl (0, "Tried to close an interrupt support function"); + if (_G.stack.offset) + emit2 ("!ldaspsp", _G.stack.offset); } - else + else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX) { - if (IFFUNC_ISCRITICAL (sym->type)) - emit2 ("!ei"); - - /* PENDING: calleeSave */ - - if (IS_Z80 && _G.omitFramePtr) - { - if (_G.stack.offset) - emit2 ("!ldaspsp", _G.stack.offset); - } - else if (_G.stack.offset && IS_GB && _G.stack.offset > INT8MAX) - { - emit2 ("!leavexl", _G.stack.offset); - } - else if (_G.stack.offset) - { - emit2 ("!leavex", _G.stack.offset); - } - else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */ - { - emit2 ("!leave"); - } + emit2 ("!leavexl", _G.stack.offset); + } + else if (_G.stack.offset) + { + emit2 ("!leavex", _G.stack.offset); + } + else if( !FUNC_ISNAKED( sym->type )) /*.p.t.20030716 - now supporting Naked funcitons */ + { + emit2 ("!leave"); + } + + if (_G.calleeSaves.pushedDE) + { + emit2 ("pop de"); + _G.calleeSaves.pushedDE = FALSE; + } - if (_G.calleeSaves.pushedDE) - { - emit2 ("pop de"); - _G.calleeSaves.pushedDE = FALSE; - } + if (_G.calleeSaves.pushedBC) + { + emit2 ("pop bc"); + _G.calleeSaves.pushedBC = FALSE; + } - if (_G.calleeSaves.pushedBC) - { - emit2 ("pop bc"); - _G.calleeSaves.pushedBC = FALSE; - } + if (options.profile) + { + emit2 ("!profileexit"); + } - if (options.profile) + /* if this is an interrupt service routine then restore all potentially used registers. */ + if (IFFUNC_ISISR (sym->type)) + { + if (!FUNC_ISNAKED( sym->type )) { - emit2 ("!profileexit"); + emit2 ("!popa"); } + } + else + { + /* if critical function then turn interrupts back on */ + if (IFFUNC_ISCRITICAL (sym->type)) + emit2 ("!ei"); + } - - if (options.debug && currFunc) - { - debugFile->writeEndFunction (currFunc, ic, 1); - } + if (options.debug && currFunc) + { + debugFile->writeEndFunction (currFunc, ic, 1); + } + if (IFFUNC_ISISR (sym->type)) + { + /* "critical interrupt" is used to imply NMI handler */ + if (IS_Z80 && IFFUNC_ISCRITICAL (sym->type)) + emit2 ("retn"); + else + emit2 ("reti"); + } + else + { /* Both banked and non-banked just ret */ emit2 ("ret"); - - sprintf (buffer, "%s_end", sym->rname); - emit2 ("!labeldef", buffer); } + + sprintf (buffer, "%s_end", sym->rname); + emit2 ("!labeldef", buffer); + _G.flushStatics = 1; _G.stack.pushed = 0; _G.stack.offset = 0; diff --git a/src/z80/main.c b/src/z80/main.c index de057f89..99a518dd 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -81,6 +81,7 @@ static char *_keywords[] = "banked", "at", //.p.t.20030714 adding support for 'sfr at ADDR' construct "_naked", //.p.t.20030714 adding support for '_naked' functions + "critical", NULL }; diff --git a/src/z80/mappings.i b/src/z80/mappings.i index 60267bd0..d7725124 100644 --- a/src/z80/mappings.i +++ b/src/z80/mappings.i @@ -35,6 +35,12 @@ static const ASM_MAPPING _asxxxx_gb_mapping[] = { "\tpush de\n" "\tpush hl" }, + { "popa", + "pop hl\n" + "\tpop de\n" + "\tpop bc\n" + "\tpop af" + }, { "adjustsp", "lda sp,-%d(sp)" }, { "fileprelude", "" }, { "profileenter", @@ -93,7 +99,15 @@ static const ASM_MAPPING _asxxxx_z80_mapping[] = { "push af\n" "\tpush\tbc\n" "\tpush\tde\n" - "\tpush\thl" + "\tpush\thl\n" + "\tpush\tiy" + }, + { "popa", + "pop iy\n" + "\tpop\thl\n" + "\tpop\tde\n" + "\tpop\tbc\n" + "\tpop\taf" }, { "adjustsp", "lda sp,-%d(sp)" }, { "profileenter", @@ -172,6 +186,12 @@ static const ASM_MAPPING _rgbds_gb_mapping[] = { "\tpush de\n" "\tpush hl" }, + { "popa", + "pop hl\n" + "\tpop de\n" + "\tpop bc\n" + "\tpop af" + }, { "di", "di" }, { "adjustsp", "add sp,-%d" }, { "enter", "" }, @@ -257,6 +277,12 @@ static const ASM_MAPPING _isas_gb_mapping[] = { "\tpush de\n" "\tpush hl" }, + { "popa", + "pop hl\n" + "\tpop de\n" + "\tpop bc\n" + "\tpop af" + }, { "di", "di" }, { "adjustsp", "add sp,-%d" }, { "enter", "" }, @@ -370,7 +396,15 @@ static const ASM_MAPPING _z80asm_z80_mapping[] = { "push af\n" "\tpush\tbc\n" "\tpush\tde\n" - "\tpush\thl" + "\tpush\thl\n" + "\tpush\tiy" + }, + { "popa", + "pop\tiy\n" + "\tpop\thl\n" + "\tpop\tde\n" + "\tpop\tbc\n" + "\tpop\taf" }, { "adjustsp", "lda sp,(sp%+d)" }, { "profileenter",